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 formatters/date_time.hpp
|
Chris@16
|
9 * \author Andrey Semashev
|
Chris@16
|
10 * \date 16.09.2012
|
Chris@16
|
11 *
|
Chris@16
|
12 * The header contains a formatter function for date and time attribute values.
|
Chris@16
|
13 */
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_DATE_TIME_HPP_INCLUDED_
|
Chris@16
|
16 #define BOOST_LOG_EXPRESSIONS_FORMATTERS_DATE_TIME_HPP_INCLUDED_
|
Chris@16
|
17
|
Chris@16
|
18 #include <string>
|
Chris@16
|
19 #include <boost/move/core.hpp>
|
Chris@16
|
20 #include <boost/move/utility.hpp>
|
Chris@16
|
21 #include <boost/phoenix/core/actor.hpp>
|
Chris@16
|
22 #include <boost/phoenix/core/terminal_fwd.hpp>
|
Chris@16
|
23 #include <boost/phoenix/core/is_nullary.hpp>
|
Chris@16
|
24 #include <boost/phoenix/core/environment.hpp>
|
Chris@16
|
25 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
Chris@16
|
26 #include <boost/log/detail/config.hpp>
|
Chris@16
|
27 #include <boost/log/attributes/attribute_name.hpp>
|
Chris@16
|
28 #include <boost/log/attributes/fallback_policy.hpp>
|
Chris@16
|
29 #include <boost/log/attributes/value_visitation.hpp>
|
Chris@16
|
30 #include <boost/log/detail/light_function.hpp>
|
Chris@16
|
31 #include <boost/log/detail/date_time_fmt_gen_traits_fwd.hpp>
|
Chris@16
|
32 #include <boost/log/detail/custom_terminal_spec.hpp>
|
Chris@16
|
33 #include <boost/log/detail/attr_output_terminal.hpp>
|
Chris@16
|
34 #include <boost/log/expressions/attr_fwd.hpp>
|
Chris@16
|
35 #include <boost/log/expressions/keyword_fwd.hpp>
|
Chris@16
|
36 #include <boost/log/utility/formatting_ostream.hpp>
|
Chris@16
|
37 #include <boost/log/utility/functional/bind.hpp>
|
Chris@16
|
38 #include <boost/log/detail/header.hpp>
|
Chris@16
|
39
|
Chris@16
|
40 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@16
|
41 #pragma once
|
Chris@16
|
42 #endif
|
Chris@16
|
43
|
Chris@16
|
44 namespace boost {
|
Chris@16
|
45
|
Chris@16
|
46 BOOST_LOG_OPEN_NAMESPACE
|
Chris@16
|
47
|
Chris@16
|
48 namespace expressions {
|
Chris@16
|
49
|
Chris@16
|
50 /*!
|
Chris@16
|
51 * Date and time formatter terminal.
|
Chris@16
|
52 */
|
Chris@16
|
53 template< typename T, typename FallbackPolicyT, typename CharT >
|
Chris@16
|
54 class format_date_time_terminal
|
Chris@16
|
55 {
|
Chris@16
|
56 public:
|
Chris@16
|
57 //! Internal typedef for type categorization
|
Chris@16
|
58 typedef void _is_boost_log_terminal;
|
Chris@16
|
59
|
Chris@16
|
60 //! Attribute value type
|
Chris@16
|
61 typedef T value_type;
|
Chris@16
|
62 //! Fallback policy
|
Chris@16
|
63 typedef FallbackPolicyT fallback_policy;
|
Chris@16
|
64 //! Character type
|
Chris@16
|
65 typedef CharT char_type;
|
Chris@16
|
66 //! String type
|
Chris@16
|
67 typedef std::basic_string< char_type > string_type;
|
Chris@16
|
68 //! Formatting stream type
|
Chris@16
|
69 typedef basic_formatting_ostream< char_type > stream_type;
|
Chris@16
|
70
|
Chris@16
|
71 //! Formatter function
|
Chris@16
|
72 typedef boost::log::aux::light_function< void (stream_type&, value_type const&) > formatter_function_type;
|
Chris@16
|
73
|
Chris@16
|
74 //! Function result type
|
Chris@16
|
75 typedef string_type result_type;
|
Chris@16
|
76
|
Chris@16
|
77 private:
|
Chris@16
|
78 //! Formatter generator traits
|
Chris@16
|
79 typedef aux::date_time_formatter_generator_traits< value_type, char_type > formatter_generator;
|
Chris@16
|
80 //! Attribute value visitor invoker
|
Chris@16
|
81 typedef value_visitor_invoker< value_type, fallback_policy > visitor_invoker_type;
|
Chris@16
|
82
|
Chris@16
|
83 private:
|
Chris@16
|
84 //! Attribute name
|
Chris@16
|
85 attribute_name m_name;
|
Chris@16
|
86 //! Formattr function
|
Chris@16
|
87 formatter_function_type m_formatter;
|
Chris@16
|
88 //! Attribute value visitor invoker
|
Chris@16
|
89 visitor_invoker_type m_visitor_invoker;
|
Chris@16
|
90
|
Chris@16
|
91 public:
|
Chris@16
|
92 //! Initializing constructor
|
Chris@16
|
93 format_date_time_terminal(attribute_name const& name, fallback_policy const& fallback, string_type const& format) :
|
Chris@16
|
94 m_name(name), m_formatter(formatter_generator::parse(format)), m_visitor_invoker(fallback)
|
Chris@16
|
95 {
|
Chris@16
|
96 }
|
Chris@16
|
97 //! Copy constructor
|
Chris@16
|
98 format_date_time_terminal(format_date_time_terminal const& that) :
|
Chris@16
|
99 m_name(that.m_name), m_formatter(that.m_formatter), m_visitor_invoker(that.m_visitor_invoker)
|
Chris@16
|
100 {
|
Chris@16
|
101 }
|
Chris@16
|
102
|
Chris@16
|
103 //! Returns attribute name
|
Chris@16
|
104 attribute_name get_name() const
|
Chris@16
|
105 {
|
Chris@16
|
106 return m_name;
|
Chris@16
|
107 }
|
Chris@16
|
108
|
Chris@16
|
109 //! Returns fallback policy
|
Chris@16
|
110 fallback_policy const& get_fallback_policy() const
|
Chris@16
|
111 {
|
Chris@16
|
112 return m_visitor_invoker.get_fallback_policy();
|
Chris@16
|
113 }
|
Chris@16
|
114
|
Chris@16
|
115 //! Retruns formatter function
|
Chris@16
|
116 formatter_function_type const& get_formatter_function() const
|
Chris@16
|
117 {
|
Chris@16
|
118 return m_formatter;
|
Chris@16
|
119 }
|
Chris@16
|
120
|
Chris@16
|
121 //! Invokation operator
|
Chris@16
|
122 template< typename ContextT >
|
Chris@16
|
123 result_type operator() (ContextT const& ctx)
|
Chris@16
|
124 {
|
Chris@16
|
125 string_type str;
|
Chris@16
|
126 stream_type strm(str);
|
Chris@16
|
127 m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type&, stream_type& >(m_formatter, strm));
|
Chris@16
|
128 strm.flush();
|
Chris@16
|
129 return boost::move(str);
|
Chris@16
|
130 }
|
Chris@16
|
131
|
Chris@16
|
132 //! Invokation operator
|
Chris@16
|
133 template< typename ContextT >
|
Chris@16
|
134 result_type operator() (ContextT const& ctx) const
|
Chris@16
|
135 {
|
Chris@16
|
136 string_type str;
|
Chris@16
|
137 stream_type strm(str);
|
Chris@16
|
138 m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type const&, stream_type& >(m_formatter, strm));
|
Chris@16
|
139 strm.flush();
|
Chris@16
|
140 return boost::move(str);
|
Chris@16
|
141 }
|
Chris@16
|
142
|
Chris@16
|
143 BOOST_DELETED_FUNCTION(format_date_time_terminal())
|
Chris@16
|
144 };
|
Chris@16
|
145
|
Chris@16
|
146 /*!
|
Chris@16
|
147 * Date and time formatter actor.
|
Chris@16
|
148 */
|
Chris@16
|
149 template< typename T, typename FallbackPolicyT, typename CharT, template< typename > class ActorT = phoenix::actor >
|
Chris@16
|
150 class format_date_time_actor :
|
Chris@16
|
151 public ActorT< format_date_time_terminal< T, FallbackPolicyT, CharT > >
|
Chris@16
|
152 {
|
Chris@16
|
153 public:
|
Chris@16
|
154 //! Attribute value type
|
Chris@16
|
155 typedef T value_type;
|
Chris@16
|
156 //! Character type
|
Chris@16
|
157 typedef CharT char_type;
|
Chris@16
|
158 //! Fallback policy
|
Chris@16
|
159 typedef FallbackPolicyT fallback_policy;
|
Chris@16
|
160 //! Base terminal type
|
Chris@16
|
161 typedef format_date_time_terminal< value_type, fallback_policy, char_type > terminal_type;
|
Chris@16
|
162 //! Formatter function
|
Chris@16
|
163 typedef typename terminal_type::formatter_function_type formatter_function_type;
|
Chris@16
|
164
|
Chris@16
|
165 //! Base actor type
|
Chris@16
|
166 typedef ActorT< terminal_type > base_type;
|
Chris@16
|
167
|
Chris@16
|
168 public:
|
Chris@16
|
169 //! Initializing constructor
|
Chris@16
|
170 explicit format_date_time_actor(base_type const& act) : base_type(act)
|
Chris@16
|
171 {
|
Chris@16
|
172 }
|
Chris@16
|
173
|
Chris@16
|
174 /*!
|
Chris@16
|
175 * \returns The attribute name
|
Chris@16
|
176 */
|
Chris@16
|
177 attribute_name get_name() const
|
Chris@16
|
178 {
|
Chris@16
|
179 return this->proto_expr_.child0.get_name();
|
Chris@16
|
180 }
|
Chris@16
|
181
|
Chris@16
|
182 /*!
|
Chris@16
|
183 * \returns Fallback policy
|
Chris@16
|
184 */
|
Chris@16
|
185 fallback_policy const& get_fallback_policy() const
|
Chris@16
|
186 {
|
Chris@16
|
187 return this->proto_expr_.child0.get_fallback_policy();
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 /*!
|
Chris@16
|
191 * \returns Formatter function
|
Chris@16
|
192 */
|
Chris@16
|
193 formatter_function_type const& get_formatter_function() const
|
Chris@16
|
194 {
|
Chris@16
|
195 return this->proto_expr_.child0.get_formatter_function();
|
Chris@16
|
196 }
|
Chris@16
|
197 };
|
Chris@16
|
198
|
Chris@16
|
199 #ifndef BOOST_LOG_DOXYGEN_PASS
|
Chris@16
|
200
|
Chris@16
|
201 #define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
|
Chris@16
|
202 template< typename LeftExprT, typename T, typename FallbackPolicyT, typename CharT >\
|
Chris@16
|
203 BOOST_FORCEINLINE phoenix::actor< aux::attribute_output_terminal< phoenix::actor< LeftExprT >, T, FallbackPolicyT, typename format_date_time_actor< T, FallbackPolicyT, CharT >::formatter_function_type > >\
|
Chris@16
|
204 operator<< (phoenix::actor< LeftExprT > left_ref left, format_date_time_actor< T, FallbackPolicyT, CharT > right_ref right)\
|
Chris@16
|
205 {\
|
Chris@16
|
206 typedef aux::attribute_output_terminal< phoenix::actor< LeftExprT >, T, FallbackPolicyT, typename format_date_time_actor< T, FallbackPolicyT, CharT >::formatter_function_type > terminal_type;\
|
Chris@16
|
207 phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_name(), right.get_formatter_function(), right.get_fallback_policy()) }};\
|
Chris@16
|
208 return actor;\
|
Chris@16
|
209 }
|
Chris@16
|
210
|
Chris@16
|
211 #include <boost/log/detail/generate_overloads.hpp>
|
Chris@16
|
212
|
Chris@16
|
213 #undef BOOST_LOG_AUX_OVERLOAD
|
Chris@16
|
214
|
Chris@16
|
215 #endif // BOOST_LOG_DOXYGEN_PASS
|
Chris@16
|
216
|
Chris@16
|
217 /*!
|
Chris@16
|
218 * The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
Chris@16
|
219 * expression (stream output or \c format placeholder filler).
|
Chris@16
|
220 *
|
Chris@16
|
221 * \param name Attribute name
|
Chris@16
|
222 * \param format Format string
|
Chris@16
|
223 */
|
Chris@16
|
224 template< typename AttributeValueT, typename CharT >
|
Chris@16
|
225 BOOST_FORCEINLINE format_date_time_actor< AttributeValueT, fallback_to_none, CharT > format_date_time(attribute_name const& name, const CharT* format)
|
Chris@16
|
226 {
|
Chris@16
|
227 typedef format_date_time_actor< AttributeValueT, fallback_to_none, CharT > actor_type;
|
Chris@16
|
228 typedef typename actor_type::terminal_type terminal_type;
|
Chris@16
|
229 typename actor_type::base_type act = {{ terminal_type(name, fallback_to_none(), format) }};
|
Chris@16
|
230 return actor_type(act);
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 /*!
|
Chris@16
|
234 * The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
Chris@16
|
235 * expression (stream output or \c format placeholder filler).
|
Chris@16
|
236 *
|
Chris@16
|
237 * \param name Attribute name
|
Chris@16
|
238 * \param format Format string
|
Chris@16
|
239 */
|
Chris@16
|
240 template< typename AttributeValueT, typename CharT >
|
Chris@16
|
241 BOOST_FORCEINLINE format_date_time_actor< AttributeValueT, fallback_to_none, CharT > format_date_time(attribute_name const& name, std::basic_string< CharT > const& format)
|
Chris@16
|
242 {
|
Chris@16
|
243 typedef format_date_time_actor< AttributeValueT, fallback_to_none, CharT > actor_type;
|
Chris@16
|
244 typedef typename actor_type::terminal_type terminal_type;
|
Chris@16
|
245 typename actor_type::base_type act = {{ terminal_type(name, fallback_to_none(), format) }};
|
Chris@16
|
246 return actor_type(act);
|
Chris@16
|
247 }
|
Chris@16
|
248
|
Chris@16
|
249 /*!
|
Chris@16
|
250 * The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
Chris@16
|
251 * expression (stream output or \c format placeholder filler).
|
Chris@16
|
252 *
|
Chris@16
|
253 * \param keyword Attribute keyword
|
Chris@16
|
254 * \param format Format string
|
Chris@16
|
255 */
|
Chris@16
|
256 template< typename DescriptorT, template< typename > class ActorT, typename CharT >
|
Chris@16
|
257 BOOST_FORCEINLINE format_date_time_actor< typename DescriptorT::value_type, fallback_to_none, CharT, ActorT >
|
Chris@16
|
258 format_date_time(attribute_keyword< DescriptorT, ActorT > const& keyword, const CharT* format)
|
Chris@16
|
259 {
|
Chris@16
|
260 typedef format_date_time_actor< typename DescriptorT::value_type, fallback_to_none, CharT, ActorT > actor_type;
|
Chris@16
|
261 typedef typename actor_type::terminal_type terminal_type;
|
Chris@16
|
262 typename actor_type::base_type act = {{ terminal_type(keyword.get_name(), fallback_to_none(), format) }};
|
Chris@16
|
263 return actor_type(act);
|
Chris@16
|
264 }
|
Chris@16
|
265
|
Chris@16
|
266 /*!
|
Chris@16
|
267 * The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
Chris@16
|
268 * expression (stream output or \c format placeholder filler).
|
Chris@16
|
269 *
|
Chris@16
|
270 * \param keyword Attribute keyword
|
Chris@16
|
271 * \param format Format string
|
Chris@16
|
272 */
|
Chris@16
|
273 template< typename DescriptorT, template< typename > class ActorT, typename CharT >
|
Chris@16
|
274 BOOST_FORCEINLINE format_date_time_actor< typename DescriptorT::value_type, fallback_to_none, CharT, ActorT >
|
Chris@16
|
275 format_date_time(attribute_keyword< DescriptorT, ActorT > const& keyword, std::basic_string< CharT > const& format)
|
Chris@16
|
276 {
|
Chris@16
|
277 typedef format_date_time_actor< typename DescriptorT::value_type, fallback_to_none, CharT, ActorT > actor_type;
|
Chris@16
|
278 typedef typename actor_type::terminal_type terminal_type;
|
Chris@16
|
279 typename actor_type::base_type act = {{ terminal_type(keyword.get_name(), fallback_to_none(), format) }};
|
Chris@16
|
280 return actor_type(act);
|
Chris@16
|
281 }
|
Chris@16
|
282
|
Chris@16
|
283 /*!
|
Chris@16
|
284 * The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
Chris@16
|
285 * expression (stream output or \c format placeholder filler).
|
Chris@16
|
286 *
|
Chris@16
|
287 * \param placeholder Attribute placeholder
|
Chris@16
|
288 * \param format Format string
|
Chris@16
|
289 */
|
Chris@16
|
290 template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT, typename CharT >
|
Chris@16
|
291 BOOST_FORCEINLINE format_date_time_actor< T, FallbackPolicyT, CharT, ActorT >
|
Chris@16
|
292 format_date_time(attribute_actor< T, FallbackPolicyT, TagT, ActorT > const& placeholder, const CharT* format)
|
Chris@16
|
293 {
|
Chris@16
|
294 typedef format_date_time_actor< T, FallbackPolicyT, CharT, ActorT > actor_type;
|
Chris@16
|
295 typedef typename actor_type::terminal_type terminal_type;
|
Chris@16
|
296 typename actor_type::base_type act = {{ terminal_type(placeholder.get_name(), placeholder.get_fallback_policy(), format) }};
|
Chris@16
|
297 return actor_type(act);
|
Chris@16
|
298 }
|
Chris@16
|
299
|
Chris@16
|
300 /*!
|
Chris@16
|
301 * The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
Chris@16
|
302 * expression (stream output or \c format placeholder filler).
|
Chris@16
|
303 *
|
Chris@16
|
304 * \param placeholder Attribute placeholder
|
Chris@16
|
305 * \param format Format string
|
Chris@16
|
306 */
|
Chris@16
|
307 template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT, typename CharT >
|
Chris@16
|
308 BOOST_FORCEINLINE format_date_time_actor< T, FallbackPolicyT, CharT, ActorT >
|
Chris@16
|
309 format_date_time(attribute_actor< T, FallbackPolicyT, TagT, ActorT > const& placeholder, std::basic_string< CharT > const& format)
|
Chris@16
|
310 {
|
Chris@16
|
311 typedef format_date_time_actor< T, FallbackPolicyT, CharT, ActorT > actor_type;
|
Chris@16
|
312 typedef typename actor_type::terminal_type terminal_type;
|
Chris@16
|
313 typename actor_type::base_type act = {{ terminal_type(placeholder.get_name(), placeholder.get_fallback_policy(), format) }};
|
Chris@16
|
314 return actor_type(act);
|
Chris@16
|
315 }
|
Chris@16
|
316
|
Chris@16
|
317 } // namespace expressions
|
Chris@16
|
318
|
Chris@16
|
319 BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
Chris@16
|
320
|
Chris@101
|
321 #ifndef BOOST_LOG_DOXYGEN_PASS
|
Chris@101
|
322
|
Chris@101
|
323 namespace phoenix {
|
Chris@101
|
324
|
Chris@101
|
325 namespace result_of {
|
Chris@101
|
326
|
Chris@101
|
327 template< typename T, typename FallbackPolicyT, typename CharT >
|
Chris@101
|
328 struct is_nullary< custom_terminal< boost::log::expressions::format_date_time_terminal< T, FallbackPolicyT, CharT > > > :
|
Chris@101
|
329 public mpl::false_
|
Chris@101
|
330 {
|
Chris@101
|
331 };
|
Chris@101
|
332
|
Chris@101
|
333 } // namespace result_of
|
Chris@101
|
334
|
Chris@101
|
335 } // namespace phoenix
|
Chris@101
|
336
|
Chris@101
|
337 #endif // BOOST_LOG_DOXYGEN_PASS
|
Chris@101
|
338
|
Chris@16
|
339 } // namespace boost
|
Chris@16
|
340
|
Chris@16
|
341 #include <boost/log/detail/footer.hpp>
|
Chris@16
|
342
|
Chris@16
|
343 #endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_DATE_TIME_HPP_INCLUDED_
|