1 /* 2 * Copyright Andrey Semashev 2007 - 2015. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 /*! 8 * \file sinks/frontend_requirements.hpp 9 * \author Andrey Semashev 10 * \date 22.04.2007 11 * 12 * The header contains definition of requirement tags that sink backend may declare 13 * with regard to frontends. These requirements ensure that a backend will not 14 * be used with an incompatible frontend. 15 */ 16 17 #ifndef BOOST_LOG_SINKS_FRONTEND_REQUIREMENTS_HPP_INCLUDED_ 18 #define BOOST_LOG_SINKS_FRONTEND_REQUIREMENTS_HPP_INCLUDED_ 19 20 #include <boost/mpl/aux_/na.hpp> 21 #include <boost/mpl/placeholders.hpp> 22 #include <boost/mpl/inherit.hpp> 23 #include <boost/mpl/inherit_linearly.hpp> 24 #include <boost/mpl/vector.hpp> 25 #include <boost/preprocessor/repetition/enum_params.hpp> 26 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp> 27 #include <boost/type_traits/is_base_of.hpp> 28 #include <boost/log/detail/config.hpp> 29 #include <boost/log/detail/header.hpp> 30 31 #ifdef BOOST_HAS_PRAGMA_ONCE 32 #pragma once 33 #endif 34 35 #ifndef BOOST_LOG_COMBINE_REQUIREMENTS_LIMIT 36 //! The macro specifies the maximum number of requirements that can be combined with the \c combine_requirements metafunction 37 #define BOOST_LOG_COMBINE_REQUIREMENTS_LIMIT 5 38 #endif 39 40 namespace boost { 41 42 BOOST_LOG_OPEN_NAMESPACE 43 44 namespace sinks { 45 46 /*! 47 * The sink backend expects pre-synchronized calls, all needed synchronization is implemented 48 * in the frontend (IOW, only one thread is feeding records to the backend concurrently, but 49 * it is possible for several threads to write sequentially). Note that if a frontend supports 50 * synchronized record feeding, it will also report capable of concurrent record feeding. 51 */ 52 struct synchronized_feeding {}; 53 54 #if !defined(BOOST_LOG_NO_THREADS) 55 56 /*! 57 * The sink backend ensures all needed synchronization, it is capable to handle multithreaded calls 58 */ 59 struct concurrent_feeding : synchronized_feeding {}; 60 61 #else // !defined(BOOST_LOG_NO_THREADS) 62 63 // If multithreading is disabled, threading models become redundant 64 typedef synchronized_feeding concurrent_feeding; 65 66 #endif // !defined(BOOST_LOG_NO_THREADS) 67 68 /*! 69 * The sink backend requires the frontend to perform log record formatting before feeding 70 */ 71 struct formatted_records {}; 72 73 /*! 74 * The sink backend supports flushing 75 */ 76 struct flushing {}; 77 78 #ifdef BOOST_LOG_DOXYGEN_PASS 79 80 /*! 81 * The metafunction combines multiple requirement tags into one type. The resulting type will 82 * satisfy all specified requirements (i.e. \c has_requirement metafunction will return positive result). 83 */ 84 template< typename... RequirementsT > 85 struct combine_requirements; 86 87 #else 88 89 template< BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_LOG_COMBINE_REQUIREMENTS_LIMIT, typename ReqT, mpl::na) > 90 struct combine_requirements : 91 mpl::inherit_linearly< 92 mpl::vector< BOOST_PP_ENUM_PARAMS(BOOST_LOG_COMBINE_REQUIREMENTS_LIMIT, ReqT) >, 93 mpl::inherit2< mpl::_1, mpl::_2 > 94 > 95 { 96 }; 97 98 #endif // BOOST_LOG_DOXYGEN_PASS 99 100 /*! 101 * A helper metafunction to check if a requirement is satisfied. The \c TestedT template argument 102 * should be the type combining one or several requirements and \c RequiredT is the requirement 103 * to test against. The metafunction will yield a positive result if \c TestedT supports \c RequiredT. 104 */ 105 template< typename TestedT, typename RequiredT > 106 struct has_requirement : 107 public is_base_of< RequiredT, TestedT > 108 { 109 }; 110 111 } // namespace sinks 112 113 BOOST_LOG_CLOSE_NAMESPACE // namespace log 114 115 } // namespace boost 116 117 #include <boost/log/detail/footer.hpp> 118 119 #endif // BOOST_LOG_SINKS_FRONTEND_REQUIREMENTS_HPP_INCLUDED_ 120