|
||||
File indexing completed on 2025-01-18 09:39:18
0001 /* 0002 * Copyright Andrey Semashev 2007 - 2015. 0003 * Distributed under the Boost Software License, Version 1.0. 0004 * (See accompanying file LICENSE_1_0.txt or copy at 0005 * http://www.boost.org/LICENSE_1_0.txt) 0006 */ 0007 /*! 0008 * \file attribute_value.hpp 0009 * \author Andrey Semashev 0010 * \date 21.05.2010 0011 * 0012 * The header contains \c attribute_value class definition. 0013 */ 0014 0015 #ifndef BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_ 0016 #define BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_ 0017 0018 #include <boost/type_index.hpp> 0019 #include <boost/move/core.hpp> 0020 #include <boost/smart_ptr/intrusive_ptr.hpp> 0021 #include <boost/core/explicit_operator_bool.hpp> 0022 #include <boost/log/detail/config.hpp> 0023 #include <boost/log/utility/type_dispatch/type_dispatcher.hpp> 0024 #include <boost/log/attributes/attribute.hpp> 0025 #include <boost/log/attributes/value_extraction_fwd.hpp> 0026 #include <boost/log/attributes/value_visitation_fwd.hpp> 0027 #include <boost/log/detail/header.hpp> 0028 0029 #ifdef BOOST_HAS_PRAGMA_ONCE 0030 #pragma once 0031 #endif 0032 0033 namespace boost { 0034 0035 BOOST_LOG_OPEN_NAMESPACE 0036 0037 /*! 0038 * \brief An attribute value class 0039 * 0040 * An attribute value is an object that contains a piece of data that represents an attribute state 0041 * at the point of the value acquisition. All major operations with log records, such as filtering and 0042 * formatting, involve attribute values contained in a single view. Most likely an attribute value is 0043 * implemented as a simple holder of some typed value. This holder implements the 0044 * \c attribute_value::implementation interface and acts as a pimpl for the \c attribute_value 0045 * object. The \c attribute_value class provides type dispatching support in order to allow 0046 * to extract the value from the holder. 0047 * 0048 * Normally, attributes and their values shall be designed in order to exclude as much interference as 0049 * reasonable. Such approach allows to have more than one attribute value simultaneously, which improves 0050 * scalability and allows to implement generating attributes. 0051 * 0052 * However, there are cases when this approach does not help to achieve the required level of independency 0053 * of attribute values and attribute itself from each other at a reasonable performance tradeoff. 0054 * For example, an attribute or its values may use thread-specific data, which is global and shared 0055 * between all the instances of the attribute/value. Passing such an attribute value to another thread 0056 * would be a disaster. To solve this the library defines an additional method for attribute values, 0057 * namely \c detach_from_thread. The \c attribute_value class forwards the call to its pimpl, 0058 * which is supposed to ensure that it no longer refers to any thread-specific data after the call. 0059 * The pimpl can create a new holder as a result of this method and return it to the \c attribute_value 0060 * wrapper, which will keep the returned reference for any further calls. 0061 * This method is called for all attribute values that are passed to another thread. 0062 */ 0063 class attribute_value 0064 { 0065 BOOST_COPYABLE_AND_MOVABLE(attribute_value) 0066 0067 public: 0068 /*! 0069 * \brief A base class for an attribute value implementation 0070 * 0071 * All attribute value holders should derive from this interface. 0072 */ 0073 struct BOOST_LOG_NO_VTABLE impl : 0074 public attribute::impl 0075 { 0076 public: 0077 /*! 0078 * The method dispatches the value to the given object. 0079 * 0080 * \param dispatcher The object that attempts to dispatch the stored value. 0081 * \return true if \a dispatcher was capable to consume the real attribute value type and false otherwise. 0082 */ 0083 virtual bool dispatch(type_dispatcher& dispatcher) = 0; 0084 0085 /*! 0086 * The method is called when the attribute value is passed to another thread (e.g. 0087 * in case of asynchronous logging). The value should ensure it properly owns all thread-specific data. 0088 * 0089 * \return An actual pointer to the attribute value. It may either point to this object or another. 0090 * In the latter case the returned pointer replaces the pointer used by caller to invoke this 0091 * method and is considered to be a functional equivalent to the previous pointer. 0092 */ 0093 virtual intrusive_ptr< impl > detach_from_thread() 0094 { 0095 return this; 0096 } 0097 0098 /*! 0099 * \return The attribute value that refers to self implementation. 0100 */ 0101 attribute_value get_value() BOOST_OVERRIDE { return attribute_value(this); } 0102 0103 /*! 0104 * \return The attribute value type 0105 */ 0106 virtual typeindex::type_index get_type() const { return typeindex::type_index(); } 0107 }; 0108 0109 private: 0110 //! Pointer to the value implementation 0111 intrusive_ptr< impl > m_pImpl; 0112 0113 public: 0114 /*! 0115 * Default constructor. Creates an empty (absent) attribute value. 0116 */ 0117 BOOST_DEFAULTED_FUNCTION(attribute_value(), BOOST_NOEXCEPT {}) 0118 0119 /*! 0120 * Copy constructor 0121 */ 0122 attribute_value(attribute_value const& that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) {} 0123 0124 /*! 0125 * Move constructor 0126 */ 0127 attribute_value(BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); } 0128 0129 /*! 0130 * Initializing constructor. Creates an attribute value that refers to the specified holder. 0131 * 0132 * \param p A pointer to the attribute value holder. 0133 */ 0134 explicit attribute_value(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); } 0135 0136 /*! 0137 * Copy assignment 0138 */ 0139 attribute_value& operator= (BOOST_COPY_ASSIGN_REF(attribute_value) that) BOOST_NOEXCEPT 0140 { 0141 m_pImpl = that.m_pImpl; 0142 return *this; 0143 } 0144 0145 /*! 0146 * Move assignment 0147 */ 0148 attribute_value& operator= (BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT 0149 { 0150 m_pImpl.swap(that.m_pImpl); 0151 return *this; 0152 } 0153 0154 /*! 0155 * The operator checks if the attribute value is empty 0156 */ 0157 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() 0158 /*! 0159 * The operator checks if the attribute value is empty 0160 */ 0161 bool operator! () const BOOST_NOEXCEPT { return !m_pImpl; } 0162 0163 /*! 0164 * The method returns the type information of the stored value of the attribute. 0165 * The returned type info wrapper may be empty if the attribute value is empty or 0166 * the information cannot be provided. If the returned value is not empty, the type 0167 * can be used for value extraction. 0168 */ 0169 typeindex::type_index get_type() const 0170 { 0171 if (m_pImpl.get()) 0172 return m_pImpl->get_type(); 0173 else 0174 return typeindex::type_index(); 0175 } 0176 0177 /*! 0178 * The method is called when the attribute value is passed to another thread (e.g. 0179 * in case of asynchronous logging). The value should ensure it properly owns all thread-specific data. 0180 * 0181 * \post The attribute value no longer refers to any thread-specific resources. 0182 */ 0183 void detach_from_thread() 0184 { 0185 if (m_pImpl.get()) 0186 m_pImpl->detach_from_thread().swap(m_pImpl); 0187 } 0188 0189 /*! 0190 * The method dispatches the value to the given object. This method is a low level interface for 0191 * attribute value visitation and extraction. For typical usage these interfaces may be more convenient. 0192 * 0193 * \param dispatcher The object that attempts to dispatch the stored value. 0194 * \return \c true if the value is not empty and the \a dispatcher was capable to consume 0195 * the real attribute value type and \c false otherwise. 0196 */ 0197 bool dispatch(type_dispatcher& dispatcher) const 0198 { 0199 if (m_pImpl.get()) 0200 return m_pImpl->dispatch(dispatcher); 0201 else 0202 return false; 0203 } 0204 0205 #if !defined(BOOST_LOG_DOXYGEN_PASS) 0206 #if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) 0207 #define BOOST_LOG_AUX_VOID_DEFAULT = void 0208 #else 0209 #define BOOST_LOG_AUX_VOID_DEFAULT 0210 #endif 0211 #endif // !defined(BOOST_LOG_DOXYGEN_PASS) 0212 0213 /*! 0214 * The method attempts to extract the stored value, assuming the value has the specified type. 0215 * One can specify either a single type or an MPL type sequence, in which case the stored value 0216 * is checked against every type in the sequence. 0217 * 0218 * \note Include <tt>value_extraction.hpp</tt> prior to using this method. 0219 * 0220 * \return The extracted value, if the attribute value is not empty and the value is the same 0221 * as specified. Otherwise returns an empty value. See description of the \c result_of::extract 0222 * metafunction for information on the nature of the result value. 0223 */ 0224 template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT > 0225 typename result_of::extract< T, TagT >::type extract() const; 0226 0227 /*! 0228 * The method attempts to extract the stored value, assuming the value has the specified type. 0229 * One can specify either a single type or an MPL type sequence, in which case the stored value 0230 * is checked against every type in the sequence. 0231 * 0232 * \note Include <tt>value_extraction.hpp</tt> prior to using this method. 0233 * 0234 * \return The extracted value, if the attribute value is not empty and the value is the same 0235 * as specified. Otherwise an exception is thrown. See description of the \c result_of::extract_or_throw 0236 * metafunction for information on the nature of the result value. 0237 */ 0238 template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT > 0239 typename result_of::extract_or_throw< T, TagT >::type extract_or_throw() const; 0240 0241 /*! 0242 * The method attempts to extract the stored value, assuming the value has the specified type. 0243 * One can specify either a single type or an MPL type sequence, in which case the stored value 0244 * is checked against every type in the sequence. If extraction fails, the default value is returned. 0245 * 0246 * \note Include <tt>value_extraction.hpp</tt> prior to using this method. 0247 * 0248 * \param def_value Default value. 0249 * 0250 * \return The extracted value, if the attribute value is not empty and the value is the same 0251 * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default 0252 * metafunction for information on the nature of the result value. 0253 */ 0254 template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT > 0255 typename result_of::extract_or_default< T, T, TagT >::type extract_or_default(T const& def_value) const; 0256 0257 /*! 0258 * The method attempts to extract the stored value, assuming the value has the specified type. 0259 * One can specify either a single type or an MPL type sequence, in which case the stored value 0260 * is checked against every type in the sequence. If extraction fails, the default value is returned. 0261 * 0262 * \note Include <tt>value_extraction.hpp</tt> prior to using this method. 0263 * 0264 * \param def_value Default value. 0265 * 0266 * \return The extracted value, if the attribute value is not empty and the value is the same 0267 * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default 0268 * metafunction for information on the nature of the result value. 0269 */ 0270 template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT > 0271 typename result_of::extract_or_default< T, DefaultT, TagT >::type extract_or_default(DefaultT const& def_value) const; 0272 0273 #if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) 0274 /*! 0275 * The method attempts to extract the stored value, assuming the value has the specified type. 0276 * One can specify either a single type or an MPL type sequence, in which case the stored value 0277 * is checked against every type in the sequence. 0278 * 0279 * \note Include <tt>value_extraction.hpp</tt> prior to using this method. 0280 * 0281 * \return The extracted value, if the attribute value is not empty and the value is the same 0282 * as specified. Otherwise returns an empty value. See description of the \c result_of::extract 0283 * metafunction for information on the nature of the result value. 0284 */ 0285 template< typename T > 0286 typename result_of::extract< T >::type extract() const; 0287 0288 /*! 0289 * The method attempts to extract the stored value, assuming the value has the specified type. 0290 * One can specify either a single type or an MPL type sequence, in which case the stored value 0291 * is checked against every type in the sequence. 0292 * 0293 * \note Include <tt>value_extraction.hpp</tt> prior to using this method. 0294 * 0295 * \return The extracted value, if the attribute value is not empty and the value is the same 0296 * as specified. Otherwise an exception is thrown. See description of the \c result_of::extract_or_throw 0297 * metafunction for information on the nature of the result value. 0298 */ 0299 template< typename T > 0300 typename result_of::extract_or_throw< T >::type extract_or_throw() const; 0301 0302 /*! 0303 * The method attempts to extract the stored value, assuming the value has the specified type. 0304 * One can specify either a single type or an MPL type sequence, in which case the stored value 0305 * is checked against every type in the sequence. If extraction fails, the default value is returned. 0306 * 0307 * \note Include <tt>value_extraction.hpp</tt> prior to using this method. 0308 * 0309 * \param def_value Default value. 0310 * 0311 * \return The extracted value, if the attribute value is not empty and the value is the same 0312 * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default 0313 * metafunction for information on the nature of the result value. 0314 */ 0315 template< typename T > 0316 typename result_of::extract_or_default< T, T >::type extract_or_default(T const& def_value) const; 0317 0318 /*! 0319 * The method attempts to extract the stored value, assuming the value has the specified type. 0320 * One can specify either a single type or an MPL type sequence, in which case the stored value 0321 * is checked against every type in the sequence. If extraction fails, the default value is returned. 0322 * 0323 * \note Include <tt>value_extraction.hpp</tt> prior to using this method. 0324 * 0325 * \param def_value Default value. 0326 * 0327 * \return The extracted value, if the attribute value is not empty and the value is the same 0328 * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default 0329 * metafunction for information on the nature of the result value. 0330 */ 0331 template< typename T, typename DefaultT > 0332 typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(DefaultT const& def_value) const; 0333 #endif // defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) 0334 0335 #undef BOOST_LOG_AUX_VOID_DEFAULT 0336 0337 /*! 0338 * The method attempts to extract the stored value, assuming the value has the specified type, 0339 * and pass it to the \a visitor function object. 0340 * One can specify either a single type or an MPL type sequence, in which case the stored value 0341 * is checked against every type in the sequence. 0342 * 0343 * \note Include <tt>value_visitation.hpp</tt> prior to using this method. 0344 * 0345 * \param visitor A function object that will be invoked on the extracted attribute value. 0346 * The visitor should be capable to be called with a single argument of 0347 * any type of the specified types in \c T. 0348 * 0349 * \return The result of visitation. 0350 */ 0351 template< typename T, typename VisitorT > 0352 visitation_result visit(VisitorT visitor) const; 0353 0354 /*! 0355 * The method swaps two attribute values 0356 */ 0357 void swap(attribute_value& that) BOOST_NOEXCEPT 0358 { 0359 m_pImpl.swap(that.m_pImpl); 0360 } 0361 }; 0362 0363 /*! 0364 * The function swaps two attribute values 0365 */ 0366 inline void swap(attribute_value& left, attribute_value& right) BOOST_NOEXCEPT 0367 { 0368 left.swap(right); 0369 } 0370 0371 BOOST_LOG_CLOSE_NAMESPACE // namespace log 0372 0373 } // namespace boost 0374 0375 #include <boost/log/detail/footer.hpp> 0376 #if defined(BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_) 0377 #include <boost/log/detail/attribute_get_value_impl.hpp> 0378 #endif 0379 0380 #endif // BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |