]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 value_visitation.hpp | |
9 | * \author Andrey Semashev | |
10 | * \date 01.03.2008 | |
11 | * | |
12 | * The header contains implementation of convenience tools to apply visitors to an attribute value | |
13 | * in the view. | |
14 | */ | |
15 | ||
16 | #ifndef BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_ | |
17 | #define BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_ | |
18 | ||
19 | #include <boost/log/detail/config.hpp> | |
20 | #include <boost/log/exceptions.hpp> | |
21 | #include <boost/log/core/record.hpp> | |
22 | #include <boost/log/attributes/attribute_name.hpp> | |
23 | #include <boost/log/attributes/attribute_value.hpp> | |
24 | #include <boost/log/attributes/attribute.hpp> | |
25 | #include <boost/log/attributes/attribute_value_set.hpp> | |
26 | #include <boost/log/attributes/value_visitation_fwd.hpp> | |
27 | #include <boost/log/attributes/fallback_policy.hpp> | |
28 | #include <boost/log/expressions/keyword_fwd.hpp> | |
29 | #include <boost/utility/explicit_operator_bool.hpp> | |
30 | #include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp> | |
31 | #include <boost/log/detail/header.hpp> | |
32 | ||
33 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
34 | #pragma once | |
35 | #endif | |
36 | ||
37 | namespace boost { | |
38 | ||
39 | BOOST_LOG_OPEN_NAMESPACE | |
40 | ||
41 | /*! | |
42 | * \brief The class represents attribute value visitation result | |
43 | * | |
44 | * The main purpose of this class is to provide a convenient interface for checking | |
45 | * whether the attribute value visitation succeeded or not. It also allows to discover | |
46 | * the actual cause of failure, should the operation fail. | |
47 | */ | |
48 | class visitation_result | |
49 | { | |
50 | public: | |
51 | //! Error codes for attribute value visitation | |
52 | enum error_code | |
53 | { | |
54 | ok, //!< The attribute value has been visited successfully | |
55 | value_not_found, //!< The attribute value is not present in the view | |
56 | value_has_invalid_type //!< The attribute value is present in the view, but has an unexpected type | |
57 | }; | |
58 | ||
59 | private: | |
60 | error_code m_code; | |
61 | ||
62 | public: | |
63 | /*! | |
64 | * Initializing constructor. Creates the result that is equivalent to the | |
65 | * specified error code. | |
66 | */ | |
67 | BOOST_CONSTEXPR visitation_result(error_code code = ok) BOOST_NOEXCEPT : m_code(code) {} | |
68 | ||
69 | /*! | |
70 | * Checks if the visitation was successful. | |
71 | * | |
72 | * \return \c true if the value was visited successfully, \c false otherwise. | |
73 | */ | |
74 | BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() | |
75 | /*! | |
76 | * Checks if the visitation was unsuccessful. | |
77 | * | |
78 | * \return \c false if the value was visited successfully, \c true otherwise. | |
79 | */ | |
80 | bool operator! () const BOOST_NOEXCEPT { return (m_code != ok); } | |
81 | ||
82 | /*! | |
83 | * \return The actual result code of value visitation | |
84 | */ | |
85 | error_code code() const BOOST_NOEXCEPT { return m_code; } | |
86 | }; | |
87 | ||
88 | /*! | |
89 | * \brief Generic attribute value visitor invoker | |
90 | * | |
91 | * Attribute value invoker is a functional object that attempts to find and extract the stored | |
92 | * attribute value from the attribute value view or a log record. The extracted value is passed to | |
93 | * a unary function object (the visitor) provided by user. | |
94 | * | |
95 | * The invoker can be specialized on one or several attribute value types that should be | |
96 | * specified in the second template argument. | |
97 | */ | |
98 | template< typename T, typename FallbackPolicyT > | |
99 | class value_visitor_invoker : | |
100 | private FallbackPolicyT | |
101 | { | |
102 | typedef value_visitor_invoker< T, FallbackPolicyT > this_type; | |
103 | ||
104 | public: | |
105 | //! Attribute value types | |
106 | typedef T value_type; | |
107 | ||
108 | //! Fallback policy | |
109 | typedef FallbackPolicyT fallback_policy; | |
110 | ||
111 | //! Function object result type | |
112 | typedef visitation_result result_type; | |
113 | ||
114 | public: | |
115 | /*! | |
116 | * Default constructor | |
117 | */ | |
118 | BOOST_DEFAULTED_FUNCTION(value_visitor_invoker(), {}) | |
119 | ||
120 | /*! | |
121 | * Copy constructor | |
122 | */ | |
123 | value_visitor_invoker(value_visitor_invoker const& that) : fallback_policy(static_cast< fallback_policy const& >(that)) | |
124 | { | |
125 | } | |
126 | ||
127 | /*! | |
128 | * Initializing constructor | |
129 | * | |
130 | * \param arg Fallback policy argument | |
131 | */ | |
132 | template< typename U > | |
133 | explicit value_visitor_invoker(U const& arg) : fallback_policy(arg) {} | |
134 | ||
135 | /*! | |
136 | * Visitation operator. Attempts to acquire the stored value of one of the supported types. If acquisition succeeds, | |
137 | * the value is passed to \a visitor. | |
138 | * | |
139 | * \param attr An attribute value to apply the visitor to. | |
140 | * \param visitor A receiving function object to pass the attribute value to. | |
141 | * \return The result of visitation. | |
142 | */ | |
143 | template< typename VisitorT > | |
144 | result_type operator() (attribute_value const& attr, VisitorT visitor) const | |
145 | { | |
146 | if (!!attr) | |
147 | { | |
148 | static_type_dispatcher< value_type > disp(visitor); | |
149 | if (attr.dispatch(disp) || fallback_policy::apply_default(visitor)) | |
150 | { | |
151 | return visitation_result::ok; | |
152 | } | |
153 | else | |
154 | { | |
155 | fallback_policy::on_invalid_type(attr.get_type()); | |
156 | return visitation_result::value_has_invalid_type; | |
157 | } | |
158 | } | |
159 | ||
160 | if (fallback_policy::apply_default(visitor)) | |
161 | return visitation_result::ok; | |
162 | ||
163 | fallback_policy::on_missing_value(); | |
164 | return visitation_result::value_not_found; | |
165 | } | |
166 | ||
167 | /*! | |
168 | * Visitation operator. Looks for an attribute value with the specified name | |
169 | * and tries to acquire the stored value of one of the supported types. If acquisition succeeds, | |
170 | * the value is passed to \a visitor. | |
171 | * | |
172 | * \param name Attribute value name. | |
173 | * \param attrs A set of attribute values in which to look for the specified attribute value. | |
174 | * \param visitor A receiving function object to pass the attribute value to. | |
175 | * \return The result of visitation. | |
176 | */ | |
177 | template< typename VisitorT > | |
178 | result_type operator() (attribute_name const& name, attribute_value_set const& attrs, VisitorT visitor) const | |
179 | { | |
180 | try | |
181 | { | |
182 | attribute_value_set::const_iterator it = attrs.find(name); | |
183 | if (it != attrs.end()) | |
184 | return operator() (it->second, visitor); | |
185 | else | |
186 | return operator() (attribute_value(), visitor); | |
187 | } | |
188 | catch (exception& e) | |
189 | { | |
190 | // Attach the attribute name to the exception | |
191 | boost::log::aux::attach_attribute_name_info(e, name); | |
192 | throw; | |
193 | } | |
194 | } | |
195 | ||
196 | /*! | |
197 | * Visitation operator. Looks for an attribute value with the specified name | |
198 | * and tries to acquire the stored value of one of the supported types. If acquisition succeeds, | |
199 | * the value is passed to \a visitor. | |
200 | * | |
201 | * \param name Attribute value name. | |
202 | * \param rec A log record. The attribute value will be sought among those associated with the record. | |
203 | * \param visitor A receiving function object to pass the attribute value to. | |
204 | * \return The result of visitation. | |
205 | */ | |
206 | template< typename VisitorT > | |
207 | result_type operator() (attribute_name const& name, record const& rec, VisitorT visitor) const | |
208 | { | |
209 | return operator() (name, rec.attribute_values(), visitor); | |
210 | } | |
211 | ||
212 | /*! | |
213 | * Visitation operator. Looks for an attribute value with the specified name | |
214 | * and tries to acquire the stored value of one of the supported types. If acquisition succeeds, | |
215 | * the value is passed to \a visitor. | |
216 | * | |
217 | * \param name Attribute value name. | |
218 | * \param rec A log record view. The attribute value will be sought among those associated with the record. | |
219 | * \param visitor A receiving function object to pass the attribute value to. | |
220 | * \return The result of visitation. | |
221 | */ | |
222 | template< typename VisitorT > | |
223 | result_type operator() (attribute_name const& name, record_view const& rec, VisitorT visitor) const | |
224 | { | |
225 | return operator() (name, rec.attribute_values(), visitor); | |
226 | } | |
227 | ||
228 | /*! | |
229 | * \returns Fallback policy | |
230 | */ | |
231 | fallback_policy const& get_fallback_policy() const | |
232 | { | |
233 | return *static_cast< fallback_policy const* >(this); | |
234 | } | |
235 | }; | |
236 | ||
237 | /*! | |
238 | * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the | |
239 | * type or set of possible types of the attribute value to be visited. | |
240 | * | |
241 | * \param name The name of the attribute value to visit. | |
242 | * \param attrs A set of attribute values in which to look for the specified attribute value. | |
243 | * \param visitor A receiving function object to pass the attribute value to. | |
244 | * \return The result of visitation. | |
245 | */ | |
246 | template< typename T, typename VisitorT > | |
247 | inline visitation_result | |
248 | visit(attribute_name const& name, attribute_value_set const& attrs, VisitorT visitor) | |
249 | { | |
250 | value_visitor_invoker< T > invoker; | |
251 | return invoker(name, attrs, visitor); | |
252 | } | |
253 | ||
254 | /*! | |
255 | * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the | |
256 | * type or set of possible types of the attribute value to be visited. | |
257 | * | |
258 | * \param name The name of the attribute value to visit. | |
259 | * \param rec A log record. The attribute value will be sought among those associated with the record. | |
260 | * \param visitor A receiving function object to pass the attribute value to. | |
261 | * \return The result of visitation. | |
262 | */ | |
263 | template< typename T, typename VisitorT > | |
264 | inline visitation_result | |
265 | visit(attribute_name const& name, record const& rec, VisitorT visitor) | |
266 | { | |
267 | value_visitor_invoker< T > invoker; | |
268 | return invoker(name, rec, visitor); | |
269 | } | |
270 | ||
271 | /*! | |
272 | * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the | |
273 | * type or set of possible types of the attribute value to be visited. | |
274 | * | |
275 | * \param name The name of the attribute value to visit. | |
276 | * \param rec A log record view. The attribute value will be sought among those associated with the record. | |
277 | * \param visitor A receiving function object to pass the attribute value to. | |
278 | * \return The result of visitation. | |
279 | */ | |
280 | template< typename T, typename VisitorT > | |
281 | inline visitation_result | |
282 | visit(attribute_name const& name, record_view const& rec, VisitorT visitor) | |
283 | { | |
284 | value_visitor_invoker< T > invoker; | |
285 | return invoker(name, rec, visitor); | |
286 | } | |
287 | ||
288 | /*! | |
289 | * The function applies a visitor to an attribute value. The user has to explicitly specify the | |
290 | * type or set of possible types of the attribute value to be visited. | |
291 | * | |
292 | * \param value The attribute value to visit. | |
293 | * \param visitor A receiving function object to pass the attribute value to. | |
294 | * \return The result of visitation. | |
295 | */ | |
296 | template< typename T, typename VisitorT > | |
297 | inline visitation_result | |
298 | visit(attribute_value const& value, VisitorT visitor) | |
299 | { | |
300 | value_visitor_invoker< T > invoker; | |
301 | return invoker(value, visitor); | |
302 | } | |
303 | ||
304 | /*! | |
305 | * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the | |
306 | * type or set of possible types of the attribute value to be visited. | |
307 | * | |
308 | * \param keyword The keyword of the attribute value to visit. | |
309 | * \param attrs A set of attribute values in which to look for the specified attribute value. | |
310 | * \param visitor A receiving function object to pass the attribute value to. | |
311 | * \return The result of visitation. | |
312 | */ | |
313 | template< typename DescriptorT, template< typename > class ActorT, typename VisitorT > | |
314 | inline visitation_result | |
315 | visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs, VisitorT visitor) | |
316 | { | |
317 | value_visitor_invoker< typename DescriptorT::value_type > invoker; | |
318 | return invoker(keyword.get_name(), attrs, visitor); | |
319 | } | |
320 | ||
321 | /*! | |
322 | * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the | |
323 | * type or set of possible types of the attribute value to be visited. | |
324 | * | |
325 | * \param keyword The keyword of the attribute value to visit. | |
326 | * \param rec A log record. The attribute value will be sought among those associated with the record. | |
327 | * \param visitor A receiving function object to pass the attribute value to. | |
328 | * \return The result of visitation. | |
329 | */ | |
330 | template< typename DescriptorT, template< typename > class ActorT, typename VisitorT > | |
331 | inline visitation_result | |
332 | visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec, VisitorT visitor) | |
333 | { | |
334 | value_visitor_invoker< typename DescriptorT::value_type > invoker; | |
335 | return invoker(keyword.get_name(), rec, visitor); | |
336 | } | |
337 | ||
338 | /*! | |
339 | * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the | |
340 | * type or set of possible types of the attribute value to be visited. | |
341 | * | |
342 | * \param keyword The keyword of the attribute value to visit. | |
343 | * \param rec A log record view. The attribute value will be sought among those associated with the record. | |
344 | * \param visitor A receiving function object to pass the attribute value to. | |
345 | * \return The result of visitation. | |
346 | */ | |
347 | template< typename DescriptorT, template< typename > class ActorT, typename VisitorT > | |
348 | inline visitation_result | |
349 | visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec, VisitorT visitor) | |
350 | { | |
351 | value_visitor_invoker< typename DescriptorT::value_type > invoker; | |
352 | return invoker(keyword.get_name(), rec, visitor); | |
353 | } | |
354 | ||
355 | ||
356 | #if !defined(BOOST_LOG_DOXYGEN_PASS) | |
357 | ||
358 | template< typename T, typename VisitorT > | |
359 | inline visitation_result attribute_value::visit(VisitorT visitor) const | |
360 | { | |
361 | return boost::log::visit< T >(*this, visitor); | |
362 | } | |
363 | ||
364 | #endif // !defined(BOOST_LOG_DOXYGEN_PASS) | |
365 | ||
366 | BOOST_LOG_CLOSE_NAMESPACE // namespace log | |
367 | ||
368 | } // namespace boost | |
369 | ||
370 | #include <boost/log/detail/footer.hpp> | |
371 | ||
372 | #endif // BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_ |