Chris@16
|
1 /*
|
Chris@16
|
2 * Copyright Andrey Semashev 2007 - 2013.
|
Chris@16
|
3 * Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
4 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
5 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 */
|
Chris@16
|
7 /*!
|
Chris@16
|
8 * \file attr.hpp
|
Chris@16
|
9 * \author Andrey Semashev
|
Chris@16
|
10 * \date 21.07.2012
|
Chris@16
|
11 *
|
Chris@16
|
12 * The header contains implementation of a generic attribute placeholder in template expressions.
|
Chris@16
|
13 */
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
|
Chris@16
|
16 #define BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/mpl/bool.hpp>
|
Chris@16
|
19 #include <boost/utility/result_of.hpp>
|
Chris@16
|
20 #include <boost/phoenix/core/actor.hpp>
|
Chris@16
|
21 #include <boost/phoenix/core/terminal_fwd.hpp>
|
Chris@16
|
22 #include <boost/phoenix/core/is_nullary.hpp>
|
Chris@16
|
23 #include <boost/phoenix/core/environment.hpp>
|
Chris@16
|
24 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
Chris@16
|
25 #include <boost/type_traits/remove_cv.hpp>
|
Chris@16
|
26 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
27 #include <boost/log/detail/config.hpp>
|
Chris@16
|
28 #include <boost/log/detail/custom_terminal_spec.hpp>
|
Chris@16
|
29 #include <boost/log/attributes/attribute_name.hpp>
|
Chris@16
|
30 #include <boost/log/attributes/value_extraction.hpp>
|
Chris@16
|
31 #include <boost/log/attributes/fallback_policy.hpp>
|
Chris@16
|
32 #include <boost/log/expressions/attr_fwd.hpp>
|
Chris@16
|
33 #include <boost/log/detail/header.hpp>
|
Chris@16
|
34
|
Chris@16
|
35 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@16
|
36 #pragma once
|
Chris@16
|
37 #endif
|
Chris@16
|
38
|
Chris@16
|
39 namespace boost {
|
Chris@16
|
40
|
Chris@16
|
41 BOOST_LOG_OPEN_NAMESPACE
|
Chris@16
|
42
|
Chris@16
|
43 namespace expressions {
|
Chris@16
|
44
|
Chris@16
|
45 /*!
|
Chris@16
|
46 * An attribute value extraction terminal
|
Chris@16
|
47 */
|
Chris@16
|
48 template< typename T, typename FallbackPolicyT, typename TagT >
|
Chris@16
|
49 class attribute_terminal
|
Chris@16
|
50 {
|
Chris@16
|
51 private:
|
Chris@16
|
52 //! Value extractor type
|
Chris@16
|
53 typedef value_extractor< T, FallbackPolicyT, TagT > value_extractor_type;
|
Chris@16
|
54 //! Self type
|
Chris@16
|
55 typedef attribute_terminal< T, FallbackPolicyT, TagT > this_type;
|
Chris@16
|
56
|
Chris@16
|
57 public:
|
Chris@16
|
58 //! Internal typedef for type categorization
|
Chris@16
|
59 typedef void _is_boost_log_terminal;
|
Chris@16
|
60
|
Chris@16
|
61 //! Attribute tag type
|
Chris@16
|
62 typedef TagT tag_type;
|
Chris@16
|
63 //! Attribute value type
|
Chris@16
|
64 typedef typename value_extractor_type::value_type value_type;
|
Chris@16
|
65 //! Fallback policy type
|
Chris@16
|
66 typedef typename value_extractor_type::fallback_policy fallback_policy;
|
Chris@16
|
67
|
Chris@16
|
68 //! Function result type
|
Chris@16
|
69 template< typename >
|
Chris@16
|
70 struct result;
|
Chris@16
|
71
|
Chris@16
|
72 template< typename ContextT >
|
Chris@16
|
73 struct result< this_type(ContextT) >
|
Chris@16
|
74 {
|
Chris@16
|
75 typedef typename remove_cv<
|
Chris@16
|
76 typename remove_reference< typename phoenix::result_of::env< ContextT >::type >::type
|
Chris@16
|
77 >::type env_type;
|
Chris@16
|
78 typedef typename env_type::args_type args_type;
|
Chris@16
|
79
|
Chris@16
|
80 typedef typename boost::result_of< value_extractor_type(attribute_name const&, typename fusion::result_of::at_c< args_type, 0 >::type) >::type type;
|
Chris@16
|
81 };
|
Chris@16
|
82
|
Chris@16
|
83 template< typename ContextT >
|
Chris@16
|
84 struct result< const this_type(ContextT) >
|
Chris@16
|
85 {
|
Chris@16
|
86 typedef typename remove_cv<
|
Chris@16
|
87 typename remove_reference< typename phoenix::result_of::env< ContextT >::type >::type
|
Chris@16
|
88 >::type env_type;
|
Chris@16
|
89 typedef typename env_type::args_type args_type;
|
Chris@16
|
90
|
Chris@16
|
91 typedef typename boost::result_of< const value_extractor_type(attribute_name const&, typename fusion::result_of::at_c< args_type, 0 >::type) >::type type;
|
Chris@16
|
92 };
|
Chris@16
|
93
|
Chris@16
|
94 private:
|
Chris@16
|
95 //! Attribute value name
|
Chris@16
|
96 const attribute_name m_name;
|
Chris@16
|
97 //! Attribute value extractor
|
Chris@16
|
98 value_extractor_type m_value_extractor;
|
Chris@16
|
99
|
Chris@16
|
100 public:
|
Chris@16
|
101 /*!
|
Chris@16
|
102 * Initializing constructor
|
Chris@16
|
103 */
|
Chris@16
|
104 explicit attribute_terminal(attribute_name const& name) : m_name(name)
|
Chris@16
|
105 {
|
Chris@16
|
106 }
|
Chris@16
|
107
|
Chris@16
|
108 /*!
|
Chris@16
|
109 * Initializing constructor
|
Chris@16
|
110 */
|
Chris@16
|
111 template< typename U >
|
Chris@16
|
112 attribute_terminal(attribute_name const& name, U const& arg) : m_name(name), m_value_extractor(arg)
|
Chris@16
|
113 {
|
Chris@16
|
114 }
|
Chris@16
|
115
|
Chris@16
|
116 /*!
|
Chris@16
|
117 * \returns Attribute value name
|
Chris@16
|
118 */
|
Chris@16
|
119 attribute_name get_name() const
|
Chris@16
|
120 {
|
Chris@16
|
121 return m_name;
|
Chris@16
|
122 }
|
Chris@16
|
123
|
Chris@16
|
124 /*!
|
Chris@16
|
125 * \returns Fallback policy
|
Chris@16
|
126 */
|
Chris@16
|
127 fallback_policy const& get_fallback_policy() const
|
Chris@16
|
128 {
|
Chris@16
|
129 return m_value_extractor.get_fallback_policy();
|
Chris@16
|
130 }
|
Chris@16
|
131
|
Chris@16
|
132 /*!
|
Chris@16
|
133 * The operator extracts attribute value
|
Chris@16
|
134 */
|
Chris@16
|
135 template< typename ContextT >
|
Chris@16
|
136 typename result< this_type(ContextT const&) >::type
|
Chris@16
|
137 operator() (ContextT const& ctx)
|
Chris@16
|
138 {
|
Chris@16
|
139 return m_value_extractor(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()));
|
Chris@16
|
140 }
|
Chris@16
|
141
|
Chris@16
|
142 /*!
|
Chris@16
|
143 * The operator extracts attribute value
|
Chris@16
|
144 */
|
Chris@16
|
145 template< typename ContextT >
|
Chris@16
|
146 typename result< const this_type(ContextT const&) >::type
|
Chris@16
|
147 operator() (ContextT const& ctx) const
|
Chris@16
|
148 {
|
Chris@16
|
149 return m_value_extractor(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()));
|
Chris@16
|
150 }
|
Chris@16
|
151
|
Chris@16
|
152 BOOST_DELETED_FUNCTION(attribute_terminal())
|
Chris@16
|
153 };
|
Chris@16
|
154
|
Chris@16
|
155 /*!
|
Chris@16
|
156 * An attribute value extraction terminal actor
|
Chris@16
|
157 */
|
Chris@16
|
158 template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT >
|
Chris@16
|
159 class attribute_actor :
|
Chris@16
|
160 public ActorT< attribute_terminal< T, FallbackPolicyT, TagT > >
|
Chris@16
|
161 {
|
Chris@16
|
162 public:
|
Chris@16
|
163 //! Attribute tag type
|
Chris@16
|
164 typedef TagT tag_type;
|
Chris@16
|
165 //! Fallback policy
|
Chris@16
|
166 typedef FallbackPolicyT fallback_policy;
|
Chris@16
|
167 //! Base terminal type
|
Chris@16
|
168 typedef attribute_terminal< T, fallback_policy, tag_type > terminal_type;
|
Chris@16
|
169 //! Attribute value type
|
Chris@16
|
170 typedef typename terminal_type::value_type value_type;
|
Chris@16
|
171
|
Chris@16
|
172 //! Base actor type
|
Chris@16
|
173 typedef ActorT< terminal_type > base_type;
|
Chris@16
|
174
|
Chris@16
|
175 public:
|
Chris@16
|
176 //! Initializing constructor
|
Chris@16
|
177 explicit attribute_actor(base_type const& act) : base_type(act)
|
Chris@16
|
178 {
|
Chris@16
|
179 }
|
Chris@16
|
180
|
Chris@16
|
181 /*!
|
Chris@16
|
182 * \returns The attribute name
|
Chris@16
|
183 */
|
Chris@16
|
184 attribute_name get_name() const
|
Chris@16
|
185 {
|
Chris@16
|
186 return this->proto_expr_.child0.get_name();
|
Chris@16
|
187 }
|
Chris@16
|
188
|
Chris@16
|
189 /*!
|
Chris@16
|
190 * \returns Fallback policy
|
Chris@16
|
191 */
|
Chris@16
|
192 fallback_policy const& get_fallback_policy() const
|
Chris@16
|
193 {
|
Chris@16
|
194 return this->proto_expr_.child0.get_fallback_policy();
|
Chris@16
|
195 }
|
Chris@16
|
196
|
Chris@16
|
197 //! Expression with cached attribute name
|
Chris@16
|
198 typedef attribute_actor< value_type, fallback_to_none, tag_type, ActorT > or_none_result_type;
|
Chris@16
|
199
|
Chris@16
|
200 //! Generates an expression that extracts the attribute value or a default value
|
Chris@16
|
201 or_none_result_type or_none() const
|
Chris@16
|
202 {
|
Chris@16
|
203 typedef typename or_none_result_type::terminal_type result_terminal;
|
Chris@16
|
204 typename or_none_result_type::base_type act = {{ result_terminal(get_name()) }};
|
Chris@16
|
205 return or_none_result_type(act);
|
Chris@16
|
206 }
|
Chris@16
|
207
|
Chris@16
|
208 //! Expression with cached attribute name
|
Chris@16
|
209 typedef attribute_actor< value_type, fallback_to_throw, tag_type, ActorT > or_throw_result_type;
|
Chris@16
|
210
|
Chris@16
|
211 //! Generates an expression that extracts the attribute value or throws an exception
|
Chris@16
|
212 or_throw_result_type or_throw() const
|
Chris@16
|
213 {
|
Chris@16
|
214 typedef typename or_throw_result_type::terminal_type result_terminal;
|
Chris@16
|
215 typename or_throw_result_type::base_type act = {{ result_terminal(get_name()) }};
|
Chris@16
|
216 return or_throw_result_type(act);
|
Chris@16
|
217 }
|
Chris@16
|
218
|
Chris@16
|
219 //! Generates an expression that extracts the attribute value or a default value
|
Chris@16
|
220 template< typename DefaultT >
|
Chris@16
|
221 attribute_actor< value_type, fallback_to_default< DefaultT >, tag_type, ActorT > or_default(DefaultT const& def_val) const
|
Chris@16
|
222 {
|
Chris@16
|
223 typedef attribute_actor< value_type, fallback_to_default< DefaultT >, tag_type, ActorT > or_default_result_type;
|
Chris@16
|
224 typedef typename or_default_result_type::terminal_type result_terminal;
|
Chris@16
|
225 typename or_default_result_type::base_type act = {{ result_terminal(get_name(), def_val) }};
|
Chris@16
|
226 return or_default_result_type(act);
|
Chris@16
|
227 }
|
Chris@16
|
228 };
|
Chris@16
|
229
|
Chris@16
|
230 /*!
|
Chris@16
|
231 * The function generates a terminal node in a template expression. The node will extract the value of the attribute
|
Chris@16
|
232 * with the specified name and type.
|
Chris@16
|
233 */
|
Chris@16
|
234 template< typename AttributeValueT >
|
Chris@16
|
235 BOOST_FORCEINLINE attribute_actor< AttributeValueT > attr(attribute_name const& name)
|
Chris@16
|
236 {
|
Chris@16
|
237 typedef attribute_actor< AttributeValueT > result_type;
|
Chris@16
|
238 typedef typename result_type::terminal_type result_terminal;
|
Chris@16
|
239 typename result_type::base_type act = {{ result_terminal(name) }};
|
Chris@16
|
240 return result_type(act);
|
Chris@16
|
241 }
|
Chris@16
|
242
|
Chris@16
|
243 /*!
|
Chris@16
|
244 * The function generates a terminal node in a template expression. The node will extract the value of the attribute
|
Chris@16
|
245 * with the specified name and type.
|
Chris@16
|
246 */
|
Chris@16
|
247 template< typename AttributeValueT, typename TagT >
|
Chris@16
|
248 BOOST_FORCEINLINE attribute_actor< AttributeValueT, fallback_to_none, TagT > attr(attribute_name const& name)
|
Chris@16
|
249 {
|
Chris@16
|
250 typedef attribute_actor< AttributeValueT, fallback_to_none, TagT > result_type;
|
Chris@16
|
251 typedef typename result_type::terminal_type result_terminal;
|
Chris@16
|
252 typename result_type::base_type act = {{ result_terminal(name) }};
|
Chris@16
|
253 return result_type(act);
|
Chris@16
|
254 }
|
Chris@16
|
255
|
Chris@16
|
256 } // namespace expressions
|
Chris@16
|
257
|
Chris@16
|
258 BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
Chris@16
|
259
|
Chris@16
|
260 #ifndef BOOST_LOG_DOXYGEN_PASS
|
Chris@16
|
261
|
Chris@16
|
262 namespace phoenix {
|
Chris@16
|
263
|
Chris@16
|
264 namespace result_of {
|
Chris@16
|
265
|
Chris@16
|
266 template< typename T, typename FallbackPolicyT, typename TagT >
|
Chris@16
|
267 struct is_nullary< custom_terminal< boost::log::expressions::attribute_terminal< T, FallbackPolicyT, TagT > > > :
|
Chris@16
|
268 public mpl::false_
|
Chris@16
|
269 {
|
Chris@16
|
270 };
|
Chris@16
|
271
|
Chris@16
|
272 } // namespace result_of
|
Chris@16
|
273
|
Chris@16
|
274 } // namespace phoenix
|
Chris@16
|
275
|
Chris@16
|
276 #endif
|
Chris@16
|
277
|
Chris@16
|
278 } // namespace boost
|
Chris@16
|
279
|
Chris@16
|
280 #include <boost/log/detail/footer.hpp>
|
Chris@16
|
281 #if defined(BOOST_LOG_EXPRESSIONS_FORMATTERS_STREAM_HPP_INCLUDED_)
|
Chris@16
|
282 #include <boost/log/detail/attr_output_impl.hpp>
|
Chris@16
|
283 #endif
|
Chris@16
|
284
|
Chris@16
|
285 #endif // BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
|