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