Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 08:55:36

0001 /*
0002  *  Copyright (c), 2017, Blue Brain Project - EPFL (CH)
0003  *
0004  *  Distributed under the Boost Software License, Version 1.0.
0005  *    (See accompanying file LICENSE_1_0.txt or copy at
0006  *          http://www.boost.org/LICENSE_1_0.txt)
0007  *
0008  */
0009 
0010 #pragma once
0011 
0012 #include <functional>
0013 #include <string>
0014 #include <iostream>
0015 
0016 #include "bits/h5e_wrapper.hpp"
0017 #include "bits/H5Friends.hpp"
0018 
0019 namespace HighFive {
0020 
0021 ///
0022 /// \brief Utility class to disable HDF5 stack printing inside a scope.
0023 ///
0024 class SilenceHDF5 {
0025   public:
0026     inline SilenceHDF5(bool enable = true)
0027         : _client_data(nullptr) {
0028         detail::nothrow::h5e_get_auto2(H5E_DEFAULT, &_func, &_client_data);
0029 
0030         if (enable) {
0031             detail::nothrow::h5e_set_auto2(H5E_DEFAULT, nullptr, nullptr);
0032         }
0033     }
0034 
0035     inline ~SilenceHDF5() {
0036         detail::nothrow::h5e_set_auto2(H5E_DEFAULT, _func, _client_data);
0037     }
0038 
0039   private:
0040     H5E_auto2_t _func;
0041     void* _client_data;
0042 };
0043 
0044 #define HIGHFIVE_LOG_LEVEL_DEBUG 10
0045 #define HIGHFIVE_LOG_LEVEL_INFO  20
0046 #define HIGHFIVE_LOG_LEVEL_WARN  30
0047 #define HIGHFIVE_LOG_LEVEL_ERROR 40
0048 
0049 #ifndef HIGHFIVE_LOG_LEVEL
0050 #define HIGHFIVE_LOG_LEVEL HIGHFIVE_LOG_LEVEL_WARN
0051 #endif
0052 
0053 enum class LogSeverity {
0054     Debug = HIGHFIVE_LOG_LEVEL_DEBUG,
0055     Info = HIGHFIVE_LOG_LEVEL_INFO,
0056     Warn = HIGHFIVE_LOG_LEVEL_WARN,
0057     Error = HIGHFIVE_LOG_LEVEL_ERROR
0058 };
0059 
0060 inline std::string to_string(LogSeverity severity) {
0061     switch (severity) {
0062     case LogSeverity::Debug:
0063         return "DEBUG";
0064     case LogSeverity::Info:
0065         return "INFO";
0066     case LogSeverity::Warn:
0067         return "WARN";
0068     case LogSeverity::Error:
0069         return "ERROR";
0070     default:
0071         return "??";
0072     }
0073 }
0074 
0075 /** \brief A logger with supporting basic functionality.
0076  *
0077  * This logger delegates the logging task to a callback. This level of
0078  * indirection enables using the default Python logger from C++; or
0079  * integrating HighFive into some custom logging solution.
0080  *
0081  * Using this class directly to log is not intended. Rather you should use
0082  *   - `HIGHFIVE_LOG_DEBUG{,_IF}`
0083  *   - `HIGHFIVE_LOG_INFO{,_IF}`
0084  *   - `HIGHFIVE_LOG_WARNING{,_IF}`
0085  *   - `HIGHFIVE_LOG_ERROR{,_IF}`
0086  *
0087  * This is intended to used as a singleton, via `get_global_logger()`.
0088  */
0089 class Logger {
0090   public:
0091     using callback_type =
0092         std::function<void(LogSeverity, const std::string&, const std::string&, int)>;
0093 
0094   public:
0095     Logger() = delete;
0096     Logger(const Logger&) = delete;
0097     Logger(Logger&&) = delete;
0098 
0099     explicit Logger(callback_type cb)
0100         : _cb(std::move(cb)) {}
0101 
0102     Logger& operator=(const Logger&) = delete;
0103     Logger& operator=(Logger&&) = delete;
0104 
0105     inline void log(LogSeverity severity,
0106                     const std::string& message,
0107                     const std::string& file,
0108                     int line) {
0109         _cb(severity, message, file, line);
0110     }
0111 
0112     inline void set_logging_callback(callback_type cb) {
0113         _cb = std::move(cb);
0114     }
0115 
0116   private:
0117     callback_type _cb;
0118 };
0119 
0120 inline void default_logging_callback(LogSeverity severity,
0121                                      const std::string& message,
0122                                      const std::string& file,
0123                                      int line) {
0124     std::clog << file << ": " << line << " [" << to_string(severity) << "] " << message
0125               << std::endl;
0126 }
0127 
0128 /// \brief Obtain a reference to the logger used by HighFive.
0129 ///
0130 /// This uses a Meyers singleton, to ensure that the global logger is
0131 /// initialized with a safe default logger, before it is used.
0132 ///
0133 /// Note: You probably don't need to call this function explicitly.
0134 ///
0135 inline Logger& get_global_logger() {
0136     static Logger logger(&default_logging_callback);
0137     return logger;
0138 }
0139 
0140 /// \brief Sets the callback that's used by the logger.
0141 inline void register_logging_callback(Logger::callback_type cb) {
0142     auto& logger = get_global_logger();
0143     logger.set_logging_callback(std::move(cb));
0144 }
0145 
0146 namespace detail {
0147 /// \brief Log a `message` with severity `severity`.
0148 inline void log(LogSeverity severity,
0149                 const std::string& message,
0150                 const std::string& file,
0151                 int line) {
0152     auto& logger = get_global_logger();
0153     logger.log(severity, message, file, line);
0154 }
0155 }  // namespace detail
0156 
0157 #if HIGHFIVE_LOG_LEVEL <= HIGHFIVE_LOG_LEVEL_DEBUG
0158 #define HIGHFIVE_LOG_DEBUG(message) \
0159     ::HighFive::detail::log(::HighFive::LogSeverity::Debug, (message), __FILE__, __LINE__);
0160 
0161 // Useful, for the common pattern: if ...; then log something.
0162 #define HIGHFIVE_LOG_DEBUG_IF(cond, message) \
0163     if ((cond)) {                            \
0164         HIGHFIVE_LOG_DEBUG((message));       \
0165     }
0166 
0167 #else
0168 #define HIGHFIVE_LOG_DEBUG(message)          ;
0169 #define HIGHFIVE_LOG_DEBUG_IF(cond, message) ;
0170 #endif
0171 
0172 #if HIGHFIVE_LOG_LEVEL <= HIGHFIVE_LOG_LEVEL_INFO
0173 #define HIGHFIVE_LOG_INFO(message) \
0174     ::HighFive::detail::log(::HighFive::LogSeverity::Info, (message), __FILE__, __LINE__);
0175 
0176 // Useful, for the common pattern: if ...; then log something.
0177 #define HIGHFIVE_LOG_INFO_IF(cond, message) \
0178     if ((cond)) {                           \
0179         HIGHFIVE_LOG_INFO((message));       \
0180     }
0181 
0182 #else
0183 #define HIGHFIVE_LOG_INFO(message)          ;
0184 #define HIGHFIVE_LOG_INFO_IF(cond, message) ;
0185 #endif
0186 
0187 
0188 #if HIGHFIVE_LOG_LEVEL <= HIGHFIVE_LOG_LEVEL_WARN
0189 #define HIGHFIVE_LOG_WARN(message) \
0190     ::HighFive::detail::log(::HighFive::LogSeverity::Warn, (message), __FILE__, __LINE__);
0191 
0192 // Useful, for the common pattern: if ...; then log something.
0193 #define HIGHFIVE_LOG_WARN_IF(cond, message) \
0194     if ((cond)) {                           \
0195         HIGHFIVE_LOG_WARN((message));       \
0196     }
0197 
0198 #else
0199 #define HIGHFIVE_LOG_WARN(message)          ;
0200 #define HIGHFIVE_LOG_WARN_IF(cond, message) ;
0201 #endif
0202 
0203 #if HIGHFIVE_LOG_LEVEL <= HIGHFIVE_LOG_LEVEL_ERROR
0204 #define HIGHFIVE_LOG_ERROR(message) \
0205     ::HighFive::detail::log(::HighFive::LogSeverity::Error, (message), __FILE__, __LINE__);
0206 
0207 // Useful, for the common pattern: if ...; then log something.
0208 #define HIGHFIVE_LOG_ERROR_IF(cond, message) \
0209     if ((cond)) {                            \
0210         HIGHFIVE_LOG_ERROR((message));       \
0211     }
0212 
0213 #else
0214 #define HIGHFIVE_LOG_ERROR(message)          ;
0215 #define HIGHFIVE_LOG_ERROR_IF(cond, message) ;
0216 #endif
0217 
0218 }  // namespace HighFive