Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-04 08:36:18

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