Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:48

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2020-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file corecel/io/detail/LoggerMessage.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <memory>
0011 #include <sstream>
0012 #include <utility>
0013 
0014 #include "corecel/Macros.hh"
0015 
0016 #include "../LoggerTypes.hh"
0017 
0018 namespace celeritas
0019 {
0020 namespace detail
0021 {
0022 //---------------------------------------------------------------------------//
0023 /*!
0024  * Stream-like helper class for writing log messages.
0025  *
0026  * This class should only be created by a Logger instance. When it destructs,
0027  * the handler is called to print the information.
0028  */
0029 class LoggerMessage
0030 {
0031   public:
0032     //!@{
0033     //! \name Type aliases
0034     using StreamManip = std::ostream& (*)(std::ostream&);
0035     //!@}
0036 
0037   public:
0038     // Construct with reference to function object, etc.
0039     inline LoggerMessage(LogHandler* handle, LogProvenance&& prov, LogLevel lev);
0040 
0041     // Flush message on destruction
0042     inline ~LoggerMessage();
0043 
0044     //! Prevent copying but allow moving
0045     CELER_DEFAULT_MOVE_DELETE_COPY(LoggerMessage);
0046 
0047     // Write the object to the stream if applicable
0048     template<class T>
0049     inline LoggerMessage& operator<<(T&& rhs);
0050 
0051     // Accept manipulators such as std::endl, std::setw
0052     inline LoggerMessage& operator<<(StreamManip manip);
0053 
0054     // Update the stream state
0055     inline void setstate(std::ostream::iostate state);
0056 
0057   private:
0058     LogHandler* handle_;
0059     LogProvenance prov_;
0060     LogLevel lev_;
0061     std::unique_ptr<std::ostringstream> os_;
0062 
0063     // Create the message when handle is non-null
0064     void construct_impl(LogProvenance&& prov, LogLevel lev);
0065 
0066     // Flush the message during destruction
0067     void destroy_impl() noexcept;
0068 };
0069 
0070 //---------------------------------------------------------------------------//
0071 /*!
0072  * Construct with reference to function object, etc.
0073  *
0074  * The handle *may be* null, indicating that the output of this message will
0075  * not be displayed.
0076  */
0077 CELER_FORCEINLINE LoggerMessage::LoggerMessage(LogHandler* handle,
0078                                                LogProvenance&& prov,
0079                                                LogLevel lev)
0080     : handle_(handle)
0081 {
0082     if (CELER_UNLIKELY(handle_))
0083     {
0084         this->construct_impl(std::move(prov), lev);
0085     }
0086 }
0087 
0088 //---------------------------------------------------------------------------//
0089 /*!
0090  * Flush message on destruction.
0091  *
0092  * Note that due to move semantics, it's possible for a stale "moved"
0093  * LoggerMessage to have a nonnull \c handle_ but a null \c os_ .
0094  */
0095 CELER_FORCEINLINE LoggerMessage::~LoggerMessage()
0096 {
0097     if (CELER_UNLIKELY(os_))
0098     {
0099         this->destroy_impl();
0100     }
0101 }
0102 
0103 //---------------------------------------------------------------------------//
0104 /*!
0105  * Write the object to the stream if applicable.
0106  */
0107 template<class T>
0108 CELER_FORCEINLINE LoggerMessage& LoggerMessage::operator<<(T&& rhs)
0109 {
0110     if (CELER_UNLIKELY(os_))
0111     {
0112         *os_ << std::forward<T>(rhs);
0113     }
0114     return *this;
0115 }
0116 
0117 //---------------------------------------------------------------------------//
0118 /*!
0119  * Accept a stream manipulator.
0120  */
0121 CELER_FORCEINLINE LoggerMessage& LoggerMessage::operator<<(StreamManip manip)
0122 {
0123     if (CELER_UNLIKELY(os_))
0124     {
0125         manip(*os_);
0126     }
0127     return *this;
0128 }
0129 
0130 //---------------------------------------------------------------------------//
0131 /*!
0132  * Update the steam state (needed by some manipulators).
0133  */
0134 CELER_FORCEINLINE void LoggerMessage::setstate(std::ostream::iostate state)
0135 {
0136     if (CELER_UNLIKELY(os_))
0137     {
0138         os_->setstate(state);
0139     }
0140 }
0141 
0142 //---------------------------------------------------------------------------//
0143 }  // namespace detail
0144 }  // namespace celeritas