annotate DEPENDENCIES/generic/include/boost/log/sources/global_logger_storage.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*
Chris@101 2 * Copyright Andrey Semashev 2007 - 2015.
Chris@16 3 * Distributed under the Boost Software License, Version 1.0.
Chris@16 4 * (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 * http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 */
Chris@16 7 /*!
Chris@16 8 * \file global_logger_storage.hpp
Chris@16 9 * \author Andrey Semashev
Chris@16 10 * \date 21.04.2008
Chris@16 11 *
Chris@16 12 * The header contains implementation of facilities to declare global loggers.
Chris@16 13 */
Chris@16 14
Chris@16 15 #ifndef BOOST_LOG_SOURCES_GLOBAL_LOGGER_STORAGE_HPP_INCLUDED_
Chris@16 16 #define BOOST_LOG_SOURCES_GLOBAL_LOGGER_STORAGE_HPP_INCLUDED_
Chris@16 17
Chris@16 18 #include <typeinfo>
Chris@16 19 #include <stdexcept>
Chris@16 20 #include <boost/smart_ptr/shared_ptr.hpp>
Chris@16 21 #include <boost/smart_ptr/make_shared_object.hpp>
Chris@16 22 #include <boost/preprocessor/seq/enum.hpp>
Chris@16 23 #include <boost/log/detail/config.hpp>
Chris@16 24 #include <boost/log/detail/singleton.hpp>
Chris@16 25 #include <boost/log/detail/visible_type.hpp>
Chris@16 26 #include <boost/log/detail/header.hpp>
Chris@16 27
Chris@16 28 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@16 29 #pragma once
Chris@16 30 #endif
Chris@16 31
Chris@16 32 namespace boost {
Chris@16 33
Chris@16 34 BOOST_LOG_OPEN_NAMESPACE
Chris@16 35
Chris@16 36 namespace sources {
Chris@16 37
Chris@16 38 namespace aux {
Chris@16 39
Chris@16 40 //! The base class for logger holders
Chris@16 41 struct BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE logger_holder_base
Chris@16 42 {
Chris@16 43 //! The source file name where the logger was registered
Chris@16 44 const char* m_RegistrationFile;
Chris@16 45 //! The line number where the logger was registered
Chris@16 46 unsigned int m_RegistrationLine;
Chris@16 47
Chris@16 48 logger_holder_base(const char* file, unsigned int line) :
Chris@16 49 m_RegistrationFile(file),
Chris@16 50 m_RegistrationLine(line)
Chris@16 51 {
Chris@16 52 }
Chris@16 53 virtual ~logger_holder_base() {}
Chris@16 54 virtual std::type_info const& logger_type() const = 0;
Chris@16 55 };
Chris@16 56
Chris@16 57 //! The actual logger holder class
Chris@16 58 template< typename LoggerT >
Chris@16 59 struct BOOST_SYMBOL_VISIBLE logger_holder :
Chris@16 60 public logger_holder_base
Chris@16 61 {
Chris@16 62 //! The logger instance
Chris@16 63 LoggerT m_Logger;
Chris@16 64
Chris@16 65 logger_holder(const char* file, unsigned int line, LoggerT const& logger) :
Chris@16 66 logger_holder_base(file, line),
Chris@16 67 m_Logger(logger)
Chris@16 68 {
Chris@16 69 }
Chris@16 70 std::type_info const& logger_type() const { return typeid(LoggerT); }
Chris@16 71 };
Chris@16 72
Chris@16 73 //! The class implements a global repository of tagged loggers
Chris@16 74 struct global_storage
Chris@16 75 {
Chris@16 76 typedef shared_ptr< logger_holder_base >(*initializer_t)();
Chris@16 77
Chris@16 78 //! Finds or creates the logger and returns its holder
Chris@16 79 BOOST_LOG_API static shared_ptr< logger_holder_base > get_or_init(std::type_info const& key, initializer_t initializer);
Chris@16 80
Chris@16 81 // Non-constructible, non-copyable, non-assignable
Chris@16 82 BOOST_DELETED_FUNCTION(global_storage())
Chris@16 83 BOOST_DELETED_FUNCTION(global_storage(global_storage const&))
Chris@16 84 BOOST_DELETED_FUNCTION(global_storage& operator= (global_storage const&))
Chris@16 85 };
Chris@16 86
Chris@16 87 //! Throws the \c odr_violation exception
Chris@16 88 BOOST_LOG_API BOOST_LOG_NORETURN void throw_odr_violation(
Chris@16 89 std::type_info const& tag_type,
Chris@16 90 std::type_info const& logger_type,
Chris@16 91 logger_holder_base const& registered);
Chris@16 92
Chris@16 93 //! The class implements a logger singleton
Chris@16 94 template< typename TagT >
Chris@16 95 struct logger_singleton :
Chris@16 96 public boost::log::aux::lazy_singleton<
Chris@16 97 logger_singleton< TagT >,
Chris@16 98 shared_ptr< logger_holder< typename TagT::logger_type > >
Chris@16 99 >
Chris@16 100 {
Chris@16 101 //! Base type
Chris@16 102 typedef boost::log::aux::lazy_singleton<
Chris@16 103 logger_singleton< TagT >,
Chris@16 104 shared_ptr< logger_holder< typename TagT::logger_type > >
Chris@16 105 > base_type;
Chris@16 106 //! Logger type
Chris@16 107 typedef typename TagT::logger_type logger_type;
Chris@16 108
Chris@16 109 //! Returns the logger instance
Chris@16 110 static logger_type& get()
Chris@16 111 {
Chris@16 112 return base_type::get()->m_Logger;
Chris@16 113 }
Chris@16 114
Chris@16 115 //! Initializes the logger instance (called only once)
Chris@16 116 static void init_instance()
Chris@16 117 {
Chris@16 118 shared_ptr< logger_holder< logger_type > >& instance = base_type::get_instance();
Chris@16 119 shared_ptr< logger_holder_base > holder = global_storage::get_or_init(
Chris@16 120 typeid(boost::log::aux::visible_type< TagT >),
Chris@16 121 &logger_singleton::construct_logger);
Chris@16 122 instance = boost::dynamic_pointer_cast< logger_holder< logger_type > >(holder);
Chris@16 123 if (!instance)
Chris@16 124 {
Chris@16 125 // In pure C++ this should never happen, since there cannot be two
Chris@16 126 // different tag types that have equal type_infos. In real life it can
Chris@16 127 // happen if the same-named tag is defined differently in two or more
Chris@16 128 // dlls. This check is intended to detect such ODR violations. However, there
Chris@16 129 // is no protection against different definitions of the logger type itself.
Chris@16 130 throw_odr_violation(typeid(TagT), typeid(logger_type), *holder);
Chris@16 131 }
Chris@16 132 }
Chris@16 133
Chris@16 134 private:
Chris@16 135 //! Constructs a logger holder
Chris@16 136 static shared_ptr< logger_holder_base > construct_logger()
Chris@16 137 {
Chris@16 138 return boost::make_shared< logger_holder< logger_type > >(
Chris@16 139 TagT::registration_file(),
Chris@16 140 static_cast< unsigned int >(TagT::registration_line),
Chris@16 141 TagT::construct_logger());
Chris@16 142 }
Chris@16 143 };
Chris@16 144
Chris@16 145 } // namespace aux
Chris@16 146
Chris@16 147 //! The macro forward-declares a global logger with a custom initialization
Chris@16 148 #define BOOST_LOG_GLOBAL_LOGGER(tag_name, logger)\
Chris@16 149 struct tag_name\
Chris@16 150 {\
Chris@16 151 typedef logger logger_type;\
Chris@16 152 enum registration_line_t { registration_line = __LINE__ };\
Chris@16 153 static const char* registration_file() { return __FILE__; }\
Chris@16 154 static logger_type construct_logger();\
Chris@16 155 static inline logger_type& get()\
Chris@16 156 {\
Chris@16 157 return ::boost::log::sources::aux::logger_singleton< tag_name >::get();\
Chris@16 158 }\
Chris@16 159 };
Chris@16 160
Chris@16 161 //! The macro defines a global logger initialization routine
Chris@16 162 #define BOOST_LOG_GLOBAL_LOGGER_INIT(tag_name, logger)\
Chris@16 163 tag_name::logger_type tag_name::construct_logger()
Chris@16 164
Chris@16 165 //! The macro defines a global logger initializer that will default-construct the logger
Chris@16 166 #define BOOST_LOG_GLOBAL_LOGGER_DEFAULT(tag_name, logger)\
Chris@16 167 BOOST_LOG_GLOBAL_LOGGER_INIT(tag_name, logger)\
Chris@16 168 {\
Chris@16 169 return logger_type();\
Chris@16 170 }
Chris@16 171
Chris@16 172 //! The macro defines a global logger initializer that will construct the logger with the specified constructor arguments
Chris@16 173 #define BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS(tag_name, logger, args)\
Chris@16 174 BOOST_LOG_GLOBAL_LOGGER_INIT(tag_name, logger)\
Chris@16 175 {\
Chris@16 176 return logger_type(BOOST_PP_SEQ_ENUM(args));\
Chris@16 177 }
Chris@16 178
Chris@16 179 //! The macro declares a global logger with a custom initialization
Chris@16 180 #define BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(tag_name, logger)\
Chris@16 181 BOOST_LOG_GLOBAL_LOGGER(tag_name, logger)\
Chris@16 182 inline BOOST_LOG_GLOBAL_LOGGER_INIT(tag_name, logger)
Chris@16 183
Chris@16 184 //! The macro declares a global logger that will be default-constructed
Chris@16 185 #define BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(tag_name, logger)\
Chris@16 186 BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(tag_name, logger)\
Chris@16 187 {\
Chris@16 188 return logger_type();\
Chris@16 189 }
Chris@16 190
Chris@16 191 //! The macro declares a global logger that will be constructed with the specified arguments
Chris@16 192 #define BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(tag_name, logger, args)\
Chris@16 193 BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(tag_name, logger)\
Chris@16 194 {\
Chris@16 195 return logger_type(BOOST_PP_SEQ_ENUM(args));\
Chris@16 196 }
Chris@16 197
Chris@16 198 } // namespace sources
Chris@16 199
Chris@16 200 BOOST_LOG_CLOSE_NAMESPACE // namespace log
Chris@16 201
Chris@16 202 } // namespace boost
Chris@16 203
Chris@16 204 #include <boost/log/detail/footer.hpp>
Chris@16 205
Chris@16 206 #endif // BOOST_LOG_SOURCES_GLOBAL_LOGGER_STORAGE_HPP_INCLUDED_