Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:55:05

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* handle, LogProvenance&& prov, LogLevel lev);
0039 
0040     // Flush message on destruction
0041     inline ~LoggerMessage();
0042 
0043     //! Prevent copying but allow moving
0044     CELER_DEFAULT_MOVE_DELETE_COPY(LoggerMessage);
0045 
0046     // Write the object to the stream if applicable
0047     template<class T>
0048     inline LoggerMessage& operator<<(T&& rhs);
0049 
0050     // Accept manipulators such as std::endl, std::setw
0051     inline LoggerMessage& operator<<(StreamManip manip);
0052 
0053     // Update the stream state
0054     inline void setstate(std::ostream::iostate state);
0055 
0056   private:
0057     LogHandler* handle_;
0058     LogProvenance prov_;
0059     LogLevel lev_;
0060     std::unique_ptr<std::ostringstream> os_;
0061 
0062     // Create the message when handle is non-null
0063     void construct_impl(LogProvenance&& prov, LogLevel lev);
0064 
0065     // Flush the message during destruction
0066     void destroy_impl() noexcept;
0067 };
0068 
0069 //---------------------------------------------------------------------------//
0070 /*!
0071  * Construct with reference to function object, etc.
0072  *
0073  * The handle *may be* null, indicating that the output of this message will
0074  * not be displayed.
0075  */
0076 CELER_FORCEINLINE LoggerMessage::LoggerMessage(LogHandler* handle,
0077                                                LogProvenance&& prov,
0078                                                LogLevel lev)
0079     : handle_(handle)
0080 {
0081     if (CELER_UNLIKELY(handle_))
0082     {
0083         this->construct_impl(std::move(prov), lev);
0084     }
0085 }
0086 
0087 //---------------------------------------------------------------------------//
0088 /*!
0089  * Flush message on destruction.
0090  *
0091  * Note that due to move semantics, it's possible for a stale "moved"
0092  * LoggerMessage to have a nonnull \c handle_ but a null \c os_ .
0093  */
0094 CELER_FORCEINLINE LoggerMessage::~LoggerMessage()
0095 {
0096     if (CELER_UNLIKELY(os_))
0097     {
0098         this->destroy_impl();
0099     }
0100 }
0101 
0102 //---------------------------------------------------------------------------//
0103 /*!
0104  * Write the object to the stream if applicable.
0105  */
0106 template<class T>
0107 CELER_FORCEINLINE LoggerMessage& LoggerMessage::operator<<(T&& rhs)
0108 {
0109     if (CELER_UNLIKELY(os_))
0110     {
0111         *os_ << std::forward<T>(rhs);
0112     }
0113     return *this;
0114 }
0115 
0116 //---------------------------------------------------------------------------//
0117 /*!
0118  * Accept a stream manipulator.
0119  */
0120 CELER_FORCEINLINE LoggerMessage& LoggerMessage::operator<<(StreamManip manip)
0121 {
0122     if (CELER_UNLIKELY(os_))
0123     {
0124         manip(*os_);
0125     }
0126     return *this;
0127 }
0128 
0129 //---------------------------------------------------------------------------//
0130 /*!
0131  * Update the steam state (needed by some manipulators).
0132  */
0133 CELER_FORCEINLINE void LoggerMessage::setstate(std::ostream::iostate state)
0134 {
0135     if (CELER_UNLIKELY(os_))
0136     {
0137         os_->setstate(state);
0138     }
0139 }
0140 
0141 //---------------------------------------------------------------------------//
0142 }  // namespace detail
0143 }  // namespace celeritas