record_view.hpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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 record_view.hpp
  9. * \author Andrey Semashev
  10. * \date 09.03.2009
  11. *
  12. * This header contains a logging record view class definition.
  13. */
  14. #ifndef BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_
  15. #define BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_
  16. #include <boost/smart_ptr/intrusive_ptr.hpp>
  17. #include <boost/move/core.hpp>
  18. #include <boost/move/utility_core.hpp>
  19. #include <boost/core/explicit_operator_bool.hpp>
  20. #include <boost/log/detail/config.hpp>
  21. #include <boost/log/attributes/attribute_value_set.hpp>
  22. #include <boost/log/expressions/keyword_fwd.hpp>
  23. #ifndef BOOST_LOG_NO_THREADS
  24. #include <boost/detail/atomic_count.hpp>
  25. #endif // BOOST_LOG_NO_THREADS
  26. #include <boost/log/detail/header.hpp>
  27. #ifdef BOOST_HAS_PRAGMA_ONCE
  28. #pragma once
  29. #endif
  30. namespace boost {
  31. BOOST_LOG_OPEN_NAMESPACE
  32. #ifndef BOOST_LOG_DOXYGEN_PASS
  33. class core;
  34. class record;
  35. #endif // BOOST_LOG_DOXYGEN_PASS
  36. /*!
  37. * \brief Logging record view class
  38. *
  39. * The logging record encapsulates all information related to a single logging statement,
  40. * in particular, attribute values view and the log message string. The view is immutable,
  41. * it is implemented as a wrapper around a reference-counted implementation.
  42. */
  43. class record_view
  44. {
  45. BOOST_COPYABLE_AND_MOVABLE(record_view)
  46. friend class core;
  47. friend class record;
  48. #ifndef BOOST_LOG_DOXYGEN_PASS
  49. private:
  50. //! Private data
  51. struct private_data;
  52. friend struct private_data;
  53. //! Publicly available record data
  54. struct public_data
  55. {
  56. //! Reference counter
  57. #ifndef BOOST_LOG_NO_THREADS
  58. mutable boost::detail::atomic_count m_ref_counter;
  59. #else
  60. mutable unsigned int m_ref_counter;
  61. #endif // BOOST_LOG_NO_THREADS
  62. //! Attribute values view
  63. attribute_value_set m_attribute_values;
  64. //! Constructor from the attribute value set
  65. explicit public_data(BOOST_RV_REF(attribute_value_set) values) BOOST_NOEXCEPT :
  66. m_ref_counter(1),
  67. m_attribute_values(boost::move(values))
  68. {
  69. }
  70. //! Destructor
  71. BOOST_LOG_API static void destroy(const public_data* p) BOOST_NOEXCEPT;
  72. protected:
  73. ~public_data() {}
  74. BOOST_DELETED_FUNCTION(public_data(public_data const&))
  75. BOOST_DELETED_FUNCTION(public_data& operator= (public_data const&))
  76. friend void intrusive_ptr_add_ref(const public_data* p) BOOST_NOEXCEPT { ++p->m_ref_counter; }
  77. friend void intrusive_ptr_release(const public_data* p) BOOST_NOEXCEPT { if (--p->m_ref_counter == 0) public_data::destroy(p); }
  78. };
  79. private:
  80. //! A pointer to the log record implementation
  81. intrusive_ptr< public_data > m_impl;
  82. private:
  83. // A private constructor, accessible from record
  84. explicit record_view(public_data* impl) BOOST_NOEXCEPT : m_impl(impl, false) {}
  85. #endif // BOOST_LOG_DOXYGEN_PASS
  86. public:
  87. /*!
  88. * Default constructor. Creates an empty record view that is equivalent to the invalid record handle.
  89. *
  90. * \post <tt>!*this == true</tt>
  91. */
  92. BOOST_CONSTEXPR record_view() BOOST_NOEXCEPT
  93. #if !defined(BOOST_LOG_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS) && !defined(BOOST_LOG_NO_CXX11_DEFAULTED_CONSTEXPR_CONSTRUCTORS)
  94. = default;
  95. #else
  96. {}
  97. #endif
  98. /*!
  99. * Copy constructor
  100. */
  101. record_view(record_view const& that) BOOST_NOEXCEPT : m_impl(that.m_impl) {}
  102. /*!
  103. * Move constructor. Source record contents unspecified after the operation.
  104. */
  105. record_view(BOOST_RV_REF(record_view) that) BOOST_NOEXCEPT
  106. {
  107. m_impl.swap(that.m_impl);
  108. }
  109. /*!
  110. * Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
  111. */
  112. ~record_view() BOOST_NOEXCEPT {}
  113. /*!
  114. * Copy assignment
  115. */
  116. record_view& operator= (BOOST_COPY_ASSIGN_REF(record_view) that) BOOST_NOEXCEPT
  117. {
  118. m_impl = that.m_impl;
  119. return *this;
  120. }
  121. /*!
  122. * Move assignment. Source record contents unspecified after the operation.
  123. */
  124. record_view& operator= (BOOST_RV_REF(record_view) that) BOOST_NOEXCEPT
  125. {
  126. m_impl.swap(that.m_impl);
  127. return *this;
  128. }
  129. /*!
  130. * \return A reference to the set of attribute values attached to this record
  131. *
  132. * \pre <tt>!!*this</tt>
  133. */
  134. attribute_value_set const& attribute_values() const BOOST_NOEXCEPT
  135. {
  136. return m_impl->m_attribute_values;
  137. }
  138. /*!
  139. * Equality comparison
  140. *
  141. * \param that Comparand
  142. * \return \c true if both <tt>*this</tt> and \a that identify the same log record or both do not
  143. * identify any record, \c false otherwise.
  144. */
  145. bool operator== (record_view const& that) const BOOST_NOEXCEPT
  146. {
  147. return m_impl == that.m_impl;
  148. }
  149. /*!
  150. * Inequality comparison
  151. *
  152. * \param that Comparand
  153. * \return <tt>!(*this == that)</tt>
  154. */
  155. bool operator!= (record_view const& that) const BOOST_NOEXCEPT
  156. {
  157. return !operator== (that);
  158. }
  159. /*!
  160. * Conversion to an unspecified boolean type
  161. *
  162. * \return \c true, if the <tt>*this</tt> identifies a log record, \c false, if the <tt>*this</tt> is not valid
  163. */
  164. BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
  165. /*!
  166. * Inverted conversion to an unspecified boolean type
  167. *
  168. * \return \c false, if the <tt>*this</tt> identifies a log record, \c true, if the <tt>*this</tt> is not valid
  169. */
  170. bool operator! () const BOOST_NOEXCEPT
  171. {
  172. return !m_impl;
  173. }
  174. /*!
  175. * Swaps two handles
  176. *
  177. * \param that Another record to swap with
  178. * <b>Throws:</b> Nothing
  179. */
  180. void swap(record_view& that) BOOST_NOEXCEPT
  181. {
  182. m_impl.swap(that.m_impl);
  183. }
  184. /*!
  185. * Resets the log record handle. If there are no other handles left, the log record is closed
  186. * and all resources referenced by the record are released.
  187. *
  188. * \post <tt>!*this == true</tt>
  189. */
  190. void reset() BOOST_NOEXCEPT
  191. {
  192. m_impl.reset();
  193. }
  194. /*!
  195. * Attribute value lookup.
  196. *
  197. * \param name Attribute name.
  198. * \return An \c attribute_value, non-empty if it is found, empty otherwise.
  199. */
  200. attribute_value_set::mapped_type operator[] (attribute_value_set::key_type name) const
  201. {
  202. return m_impl->m_attribute_values[name];
  203. }
  204. /*!
  205. * Attribute value lookup.
  206. *
  207. * \param keyword Attribute keyword.
  208. * \return A \c value_ref with extracted attribute value if it is found, empty \c value_ref otherwise.
  209. */
  210. template< typename DescriptorT, template< typename > class ActorT >
  211. typename result_of::extract< typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type, DescriptorT >::type
  212. operator[] (expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) const
  213. {
  214. return m_impl->m_attribute_values[keyword];
  215. }
  216. };
  217. /*!
  218. * A free-standing swap function overload for \c record_view
  219. */
  220. inline void swap(record_view& left, record_view& right) BOOST_NOEXCEPT
  221. {
  222. left.swap(right);
  223. }
  224. BOOST_LOG_CLOSE_NAMESPACE // namespace log
  225. } // namespace boost
  226. #include <boost/log/detail/footer.hpp>
  227. #endif // BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_