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

source code of boost/libs/log/include/boost/log/core/record_view.hpp