• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Lambda expressions</title>
5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../../index.html" title="Chapter 1. Boost.Log v2">
8<link rel="up" href="../detailed.html" title="Detailed features description">
9<link rel="prev" href="sink_backends.html" title="Sink backends">
10<link rel="next" href="attributes.html" title="Attributes">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td></tr></table>
14<hr>
15<div class="spirit-nav">
16<a accesskey="p" href="sink_backends.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../detailed.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="attributes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
17</div>
18<div class="section">
19<div class="titlepage"><div><div><h3 class="title">
20<a name="log.detailed.expressions"></a><a class="link" href="expressions.html" title="Lambda expressions">Lambda expressions</a>
21</h3></div></div></div>
22<div class="toc"><dl class="toc">
23<dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr">Generic attribute placeholder</a></span></dt>
24<dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr_keywords">Defining attribute
25        keywords</a></span></dt>
26<dt><span class="section"><a href="expressions.html#log.detailed.expressions.record">Record placeholder</a></span></dt>
27<dt><span class="section"><a href="expressions.html#log.detailed.expressions.message">Message text placeholders</a></span></dt>
28<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates">Predicate expressions</a></span></dt>
29<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters">Formatting expressions</a></span></dt>
30</dl></div>
31<p>
32        As it was pointed out in <a class="link" href="../tutorial.html" title="Tutorial">tutorial</a>, filters
33        and formatters can be specified as Lambda expressions with placeholders for
34        attribute values. This section will describe the placeholders that can be
35        used to build more complex Lambda expressions.
36      </p>
37<p>
38        There is also a way to specify the filter in the form of a string template.
39        This can be useful for initialization from the application settings. This
40        part of the library is described <a class="link" href="utilities.html#log.detailed.utilities.setup.filter_formatter" title="Filter and formatter parsers">here</a>.
41      </p>
42<div class="section">
43<div class="titlepage"><div><div><h4 class="title">
44<a name="log.detailed.expressions.attr"></a><a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder">Generic attribute placeholder</a>
45</h4></div></div></div>
46<div class="toc"><dl class="toc">
47<dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr.fallback_policies">Customizing
48          fallback policy</a></span></dt>
49<dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr.tags">Attribute tags
50          and custom formatting operators</a></span></dt>
51</dl></div>
52<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.attr_fwd_hpp" title="Header &lt;boost/log/expressions/attr_fwd.hpp&gt;">boost/log/expressions/attr_fwd.hpp</a></code><span class="special">&gt;</span>
53<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.attr_hpp" title="Header &lt;boost/log/expressions/attr.hpp&gt;">boost/log/expressions/attr.hpp</a></code><span class="special">&gt;</span>
54</pre>
55<p>
56          The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/attr_idm46079581366752.html" title="Function template attr">attr</a></code>
57          placeholder represents an attribute value in template expressions. Given
58          the record view or a set of attribute values, the placeholder will attempt
59          to extract the specified attribute value from the argument upon invocation.
60          This can be roughly described with the following pseudo-code:
61        </p>
62<pre class="programlisting"><span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">TagT</span> <span class="special">&gt;</span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">TagT</span> <span class="special">&gt;(</span><span class="identifier">name</span><span class="special">)(</span><span class="identifier">rec</span><span class="special">);</span>
63</pre>
64<p>
65          where <code class="computeroutput"><span class="identifier">val</span></code> is the <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper">reference</a> to the extracted
66          value, <code class="computeroutput"><span class="identifier">name</span></code> and <code class="computeroutput"><span class="identifier">T</span></code> are the attribute value <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">name</a>
67          and type, <code class="computeroutput"><span class="identifier">TagT</span></code> is an optional
68          tag (we'll return to it in a moment) and <code class="computeroutput"><span class="identifier">rec</span></code>
69          is the log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">record view</a>
70          or <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">attribute
71          value set</a>. <code class="computeroutput"><span class="identifier">T</span></code> can
72          be a <a href="http://www.boost.org/doc/libs/release/libs/mpl/doc/index.html" target="_top">Boost.MPL</a>
73          type sequence with possible expected types of the value; the extraction
74          will succeed if the type of the value matches one of the types in the sequence.
75        </p>
76<p>
77          The <code class="computeroutput"><span class="identifier">attr</span></code> placeholder can
78          be used in <a href="http://www.boost.org/doc/libs/release/libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
79          expressions, including the <code class="computeroutput"><span class="identifier">bind</span></code>
80          expression.
81        </p>
82<p>
83</p>
84<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">my_filter</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">level</span><span class="special">,</span>
85               <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">tag_attr</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">tag</span><span class="special">)</span>
86<span class="special">{</span>
87    <span class="keyword">return</span> <span class="identifier">level</span> <span class="special">&gt;=</span> <span class="identifier">warning</span> <span class="special">||</span> <span class="identifier">tag</span> <span class="special">==</span> <span class="string">"IMPORTANT_MESSAGE"</span><span class="special">;</span>
88<span class="special">}</span>
89
90<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
91<span class="special">{</span>
92    <span class="comment">// ...</span>
93
94    <span class="keyword">namespace</span> <span class="identifier">phoenix</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">;</span>
95    <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">my_filter</span><span class="special">,</span> <span class="identifier">severity</span><span class="special">.</span><span class="identifier">or_none</span><span class="special">(),</span> <span class="identifier">tag_attr</span><span class="special">.</span><span class="identifier">or_none</span><span class="special">()));</span>
96
97    <span class="comment">// ...</span>
98<span class="special">}</span>
99</pre>
100<p>
101        </p>
102<p>
103          The placeholder can be used both in filters and formatters:
104        </p>
105<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span>
106<span class="special">(</span>
107    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">)</span> <span class="special">&gt;=</span> <span class="number">5</span> <span class="special">&amp;&amp;</span>
108    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Channel"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"net"</span>
109<span class="special">);</span>
110
111<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
112<span class="special">(</span>
113    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
114        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">)</span>
115        <span class="special">&lt;&lt;</span> <span class="string">" ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Channel"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"] "</span>
116        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
117<span class="special">);</span>
118</pre>
119<p>
120          The call to <code class="computeroutput"><span class="identifier">set_filter</span></code>
121          registers a composite filter that consists of two elementary subfilters:
122          the first one checks the severity level, and the second checks the channel
123          name. The call to <code class="computeroutput"><span class="identifier">set_formatter</span></code>
124          installs a formatter that composes a string containing the severity level
125          and the channel name along with the message text.
126        </p>
127<div class="section">
128<div class="titlepage"><div><div><h5 class="title">
129<a name="log.detailed.expressions.attr.fallback_policies"></a><a class="link" href="expressions.html#log.detailed.expressions.attr.fallback_policies" title="Customizing fallback policy">Customizing
130          fallback policy</a>
131</h5></div></div></div>
132<p>
133            By default, when the requested attribute value is not found in the record,
134            <code class="computeroutput"><span class="identifier">attr</span></code> will return an empty
135            reference. In case of filters, this will result in <code class="computeroutput"><span class="keyword">false</span></code>
136            in any ordering expressions, and in case of formatters the output from
137            the placeholder will be empty. This behavior can be changed:
138          </p>
139<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
140                To throw an exception (<code class="computeroutput"><a class="link" href="../../boost/log/missing_value.html" title="Class missing_value">missing_value</a></code>
141                or <code class="computeroutput"><a class="link" href="../../boost/log/invalid_type.html" title="Class invalid_type">invalid_type</a></code>,
142                depending on the reason of the failure). Add the <code class="computeroutput"><span class="identifier">or_throw</span></code>
143                modifier:
144              </li></ul></div>
145<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span>
146<span class="special">(</span>
147    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">).</span><span class="identifier">or_throw</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="number">5</span> <span class="special">&amp;&amp;</span>
148    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Channel"</span><span class="special">).</span><span class="identifier">or_throw</span><span class="special">()</span> <span class="special">==</span> <span class="string">"net"</span>
149<span class="special">);</span>
150</pre>
151<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
152                To use a default value instead. Add the <code class="computeroutput"><span class="identifier">or_default</span></code>
153                modifier with the desired default value:
154              </li></ul></div>
155<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span>
156<span class="special">(</span>
157    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">).</span><span class="identifier">or_default</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">&gt;=</span> <span class="number">5</span> <span class="special">&amp;&amp;</span>
158    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Channel"</span><span class="special">).</span><span class="identifier">or_default</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"general"</span><span class="special">))</span> <span class="special">==</span> <span class="string">"net"</span>
159<span class="special">);</span>
160</pre>
161<div class="tip"><table border="0" summary="Tip">
162<tr>
163<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
164<th align="left">Tip</th>
165</tr>
166<tr><td align="left" valign="top"><p>
167              You can also use the <a class="link" href="expressions.html#log.detailed.expressions.predicates.has_attr" title="Attribute presence filter"><code class="computeroutput"><span class="identifier">has_attr</span></code></a> predicate to implement
168              filters and formatters conditional on the attribute value presence.
169            </p></td></tr>
170</table></div>
171<p>
172            The default behavior is also accessible through the <code class="computeroutput"><span class="identifier">or_none</span></code>
173            modifier. The modified placeholders can be used in filters and formatters
174            just the same way as the unmodified ones.
175          </p>
176<p>
177            In <code class="computeroutput"><span class="identifier">bind</span></code> expressions,
178            the bound function object will still receive the <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a>-wrapped values in
179            place of the modified <code class="computeroutput"><span class="identifier">attr</span></code>
180            placeholder. Even though both <code class="computeroutput"><span class="identifier">or_throw</span></code>
181            and <code class="computeroutput"><span class="identifier">or_default</span></code> modifiers
182            guarantee that the bound function will receive a filled reference, <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a>
183            is still needed if the value type is specified as a type sequence. Also,
184            the reference wrapper may contain a tag type which may be useful for
185            formatting customization.
186          </p>
187</div>
188<div class="section">
189<div class="titlepage"><div><div><h5 class="title">
190<a name="log.detailed.expressions.attr.tags"></a><a class="link" href="expressions.html#log.detailed.expressions.attr.tags" title="Attribute tags and custom formatting operators">Attribute tags
191          and custom formatting operators</a>
192</h5></div></div></div>
193<p>
194            The <code class="computeroutput"><span class="identifier">TagT</span></code> type in the
195            <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder">abstract description</a>
196            of <code class="computeroutput"><span class="identifier">attr</span></code> above is optional
197            and by default is <code class="computeroutput"><span class="keyword">void</span></code>.
198            This is an attribute tag which can be used to customize the output formatters
199            produce for different attributes. This tag is forwarded to the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.to_log" title="Customized logging manipulator"><code class="computeroutput"><span class="identifier">to_log</span></code></a>
200            manipulator when the extracted attribute value is put to a stream (this
201            behavior is warranted by <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a> implementation). Here's
202            a quick example:
203          </p>
204<p>
205</p>
206<pre class="programlisting"><span class="comment">// We define our own severity levels</span>
207<span class="keyword">enum</span> <span class="identifier">severity_level</span>
208<span class="special">{</span>
209    <span class="identifier">normal</span><span class="special">,</span>
210    <span class="identifier">notification</span><span class="special">,</span>
211    <span class="identifier">warning</span><span class="special">,</span>
212    <span class="identifier">error</span><span class="special">,</span>
213    <span class="identifier">critical</span>
214<span class="special">};</span>
215
216<span class="comment">// The operator is used for regular stream formatting</span>
217<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">)</span>
218<span class="special">{</span>
219    <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span>
220    <span class="special">{</span>
221        <span class="string">"normal"</span><span class="special">,</span>
222        <span class="string">"notification"</span><span class="special">,</span>
223        <span class="string">"warning"</span><span class="special">,</span>
224        <span class="string">"error"</span><span class="special">,</span>
225        <span class="string">"critical"</span>
226    <span class="special">};</span>
227
228    <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">&gt;(</span><span class="identifier">level</span><span class="special">)</span> <span class="special">&lt;</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span>
229        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span>
230    <span class="keyword">else</span>
231        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="identifier">level</span><span class="special">);</span>
232
233    <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span>
234<span class="special">}</span>
235
236<span class="comment">// Attribute value tag type</span>
237<span class="keyword">struct</span> <span class="identifier">severity_tag</span><span class="special">;</span>
238
239<span class="comment">// The operator is used when putting the severity level to log</span>
240<span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span>
241<span class="special">(</span>
242    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&amp;</span> <span class="identifier">strm</span><span class="special">,</span>
243    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">to_log_manip</span><span class="special">&lt;</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">severity_tag</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">manip</span>
244<span class="special">)</span>
245<span class="special">{</span>
246    <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span>
247    <span class="special">{</span>
248        <span class="string">"NORM"</span><span class="special">,</span>
249        <span class="string">"NTFY"</span><span class="special">,</span>
250        <span class="string">"WARN"</span><span class="special">,</span>
251        <span class="string">"ERRR"</span><span class="special">,</span>
252        <span class="string">"CRIT"</span>
253    <span class="special">};</span>
254
255    <span class="identifier">severity_level</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">manip</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
256    <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">&gt;(</span><span class="identifier">level</span><span class="special">)</span> <span class="special">&lt;</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span>
257        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span>
258    <span class="keyword">else</span>
259        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="identifier">level</span><span class="special">);</span>
260
261    <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span>
262<span class="special">}</span>
263
264<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
265<span class="special">{</span>
266    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span>
267    <span class="special">(</span>
268        <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span>
269        <span class="comment">// This makes the sink to write log records that look like this:</span>
270        <span class="comment">// 1: &lt;NORM&gt; A normal severity message</span>
271        <span class="comment">// 2: &lt;ERRR&gt; An error severity message</span>
272        <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span>
273        <span class="special">(</span>
274            <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
275                <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">)</span>
276                <span class="special">&lt;&lt;</span> <span class="string">": &lt;"</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">severity_tag</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">)</span>
277                <span class="special">&lt;&lt;</span> <span class="string">"&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
278        <span class="special">)</span>
279    <span class="special">);</span>
280<span class="special">}</span>
281</pre>
282<p>
283          </p>
284<p>
285            <a href="../../../../../../libs/log/example/doc/expressions_attr_fmt_tag.cpp" target="_top">See
286            the complete code</a>.
287          </p>
288<p>
289            Here we specify a different formatting operator for the severity level
290            wrapped in the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.to_log" title="Customized logging manipulator"><code class="computeroutput"><span class="identifier">to_log_manip</span></code></a> manipulator marked
291            with the tag <code class="computeroutput"><span class="identifier">severity_tag</span></code>.
292            This operator will be called when log records are formatted while the
293            regular <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>
294            will be used in other contexts.
295          </p>
296</div>
297</div>
298<div class="section">
299<div class="titlepage"><div><div><h4 class="title">
300<a name="log.detailed.expressions.attr_keywords"></a><a class="link" href="expressions.html#log.detailed.expressions.attr_keywords" title="Defining attribute keywords">Defining attribute
301        keywords</a>
302</h4></div></div></div>
303<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.keyword_fwd_hpp" title="Header &lt;boost/log/expressions/keyword_fwd.hpp&gt;">boost/log/expressions/keyword_fwd.hpp</a></code><span class="special">&gt;</span>
304<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.keyword_hpp" title="Header &lt;boost/log/expressions/keyword.hpp&gt;">boost/log/expressions/keyword.hpp</a></code><span class="special">&gt;</span>
305</pre>
306<p>
307          Attribute keywords can be used as replacements for the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholders in filters and
308          formatters while providing a more concise and less error prone syntax.
309          An attribute keyword can be declared with the <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm46079578189088.html" title="Macro BOOST_LOG_ATTRIBUTE_KEYWORD">BOOST_LOG_ATTRIBUTE_KEYWORD</a></code>
310          macro:
311        </p>
312<pre class="programlisting"><span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">keyword</span><span class="special">,</span> <span class="string">"Keyword"</span><span class="special">,</span> <span class="identifier">type</span><span class="special">)</span>
313</pre>
314<p>
315          Here the macro declares a keyword <code class="computeroutput"><span class="identifier">keyword</span></code>
316          for an attribute named "Keyword" with the value type of <code class="computeroutput"><span class="identifier">type</span></code>. Additionally, the macro defines
317          an attribute tag type <code class="computeroutput"><span class="identifier">keyword</span></code>
318          within the <code class="computeroutput"><span class="identifier">tag</span></code> namespace.
319          We can rewrite the previous example in the following way:
320        </p>
321<p>
322</p>
323<pre class="programlisting"><span class="comment">// We define our own severity levels</span>
324<span class="keyword">enum</span> <span class="identifier">severity_level</span>
325<span class="special">{</span>
326    <span class="identifier">normal</span><span class="special">,</span>
327    <span class="identifier">notification</span><span class="special">,</span>
328    <span class="identifier">warning</span><span class="special">,</span>
329    <span class="identifier">error</span><span class="special">,</span>
330    <span class="identifier">critical</span>
331<span class="special">};</span>
332
333<span class="comment">// Define the attribute keywords</span>
334<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">line_id</span><span class="special">,</span> <span class="string">"LineID"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span>
335<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">severity_level</span><span class="special">)</span>
336
337<span class="comment">// The operator is used for regular stream formatting</span>
338<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">)</span>
339<span class="special">{</span>
340    <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span>
341    <span class="special">{</span>
342        <span class="string">"normal"</span><span class="special">,</span>
343        <span class="string">"notification"</span><span class="special">,</span>
344        <span class="string">"warning"</span><span class="special">,</span>
345        <span class="string">"error"</span><span class="special">,</span>
346        <span class="string">"critical"</span>
347    <span class="special">};</span>
348
349    <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">&gt;(</span><span class="identifier">level</span><span class="special">)</span> <span class="special">&lt;</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span>
350        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span>
351    <span class="keyword">else</span>
352        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="identifier">level</span><span class="special">);</span>
353
354    <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span>
355<span class="special">}</span>
356
357<span class="comment">// The operator is used when putting the severity level to log</span>
358<span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span>
359<span class="special">(</span>
360    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&amp;</span> <span class="identifier">strm</span><span class="special">,</span>
361    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">to_log_manip</span><span class="special">&lt;</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">manip</span>
362<span class="special">)</span>
363<span class="special">{</span>
364    <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span>
365    <span class="special">{</span>
366        <span class="string">"NORM"</span><span class="special">,</span>
367        <span class="string">"NTFY"</span><span class="special">,</span>
368        <span class="string">"WARN"</span><span class="special">,</span>
369        <span class="string">"ERRR"</span><span class="special">,</span>
370        <span class="string">"CRIT"</span>
371    <span class="special">};</span>
372
373    <span class="identifier">severity_level</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">manip</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
374    <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">&gt;(</span><span class="identifier">level</span><span class="special">)</span> <span class="special">&lt;</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span>
375        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span>
376    <span class="keyword">else</span>
377        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="identifier">level</span><span class="special">);</span>
378
379    <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span>
380<span class="special">}</span>
381
382<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
383<span class="special">{</span>
384    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span>
385    <span class="special">(</span>
386        <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span>
387        <span class="comment">// This makes the sink to write log records that look like this:</span>
388        <span class="comment">// 1: &lt;NORM&gt; A normal severity message</span>
389        <span class="comment">// 2: &lt;ERRR&gt; An error severity message</span>
390        <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span>
391        <span class="special">(</span>
392            <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
393                <span class="special">&lt;&lt;</span> <span class="identifier">line_id</span>
394                <span class="special">&lt;&lt;</span> <span class="string">": &lt;"</span> <span class="special">&lt;&lt;</span> <span class="identifier">severity</span>
395                <span class="special">&lt;&lt;</span> <span class="string">"&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
396        <span class="special">)</span>
397    <span class="special">);</span>
398<span class="special">}</span>
399</pre>
400<p>
401        </p>
402<p>
403          Attribute keywords behave the same way as the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholders and can be used
404          both in filters and formatters. The <code class="computeroutput"><span class="identifier">or_throw</span></code>
405          and <code class="computeroutput"><span class="identifier">or_default</span></code> modifiers
406          are also supported.
407        </p>
408<p>
409          Keywords can also be used in attribute value lookup expressions in log
410          records and attribute value sets:
411        </p>
412<p>
413</p>
414<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">print_severity</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
415<span class="special">{</span>
416    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">&gt;</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">severity</span><span class="special">];</span>
417    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">level</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
418<span class="special">}</span>
419</pre>
420<p>
421        </p>
422</div>
423<div class="section">
424<div class="titlepage"><div><div><h4 class="title">
425<a name="log.detailed.expressions.record"></a><a class="link" href="expressions.html#log.detailed.expressions.record" title="Record placeholder">Record placeholder</a>
426</h4></div></div></div>
427<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.record_hpp" title="Header &lt;boost/log/expressions/record.hpp&gt;">boost/log/expressions/record.hpp</a></code><span class="special">&gt;</span>
428</pre>
429<p>
430          The <code class="computeroutput"><span class="identifier">record</span></code> placeholder
431          can be used in <code class="computeroutput"><span class="identifier">bind</span></code> expressions
432          to pass the whole log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">record view</a>
433          to the bound function object.
434        </p>
435<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">my_formatter</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&amp;</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
436<span class="special">{</span>
437    <span class="comment">// ...</span>
438<span class="special">}</span>
439
440<span class="keyword">namespace</span> <span class="identifier">phoenix</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">;</span>
441<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">my_formatter</span><span class="special">,</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span><span class="special">,</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">record</span><span class="special">));</span>
442</pre>
443<div class="note"><table border="0" summary="Note">
444<tr>
445<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
446<th align="left">Note</th>
447</tr>
448<tr><td align="left" valign="top"><p>
449            In case of filters, the placeholder will correspond to the <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">set
450            of attribute values</a> rather than the log record itself. This is
451            because the record is not constructed yet at the point of filtering,
452            and filters only operate on the set of attribute values.
453          </p></td></tr>
454</table></div>
455</div>
456<div class="section">
457<div class="titlepage"><div><div><h4 class="title">
458<a name="log.detailed.expressions.message"></a><a class="link" href="expressions.html#log.detailed.expressions.message" title="Message text placeholders">Message text placeholders</a>
459</h4></div></div></div>
460<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.message_hpp" title="Header &lt;boost/log/expressions/message.hpp&gt;">boost/log/expressions/message.hpp</a></code><span class="special">&gt;</span>
461</pre>
462<p>
463          Log records typically contain a special attribute "Message" with
464          the value of one of the string types (more specifically, an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span></code> specialization). This attribute
465          contains the text of the log message that is constructed at the point of
466          the record creation. This attribute is only constructed after filtering,
467          so filters cannot use it. There are several keywords to access this attribute
468          value:
469        </p>
470<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
471<li class="listitem">
472              <code class="computeroutput"><span class="identifier">smessage</span></code> - the attribute
473              value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
474            </li>
475<li class="listitem">
476              <code class="computeroutput"><span class="identifier">wmessage</span></code> - the attribute
477              value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code>
478            </li>
479<li class="listitem">
480              <code class="computeroutput"><span class="identifier">message</span></code> - the attribute
481              value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
482              or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code>
483            </li>
484</ul></div>
485<p>
486          The <code class="computeroutput"><span class="identifier">message</span></code> keyword has
487          to dispatch between different string types, so it is slightly less efficient
488          than the other two keywords. If the application is able to guarantee the
489          fixed character type of log messages, it is advised to use the corresponding
490          keyword for better performance.
491        </p>
492<pre class="programlisting"><span class="comment">// Sets up a formatter that will ignore all attributes and only print log record text</span>
493<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span><span class="special">);</span>
494</pre>
495</div>
496<div class="section">
497<div class="titlepage"><div><div><h4 class="title">
498<a name="log.detailed.expressions.predicates"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates" title="Predicate expressions">Predicate expressions</a>
499</h4></div></div></div>
500<div class="toc"><dl class="toc">
501<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.has_attr">Attribute
502          presence filter</a></span></dt>
503<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.is_in_range">Range
504          checking filter</a></span></dt>
505<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.simple_string_matching">Simple
506          string matching filters</a></span></dt>
507<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.advanced_string_matching">Advanced
508          string matching filter</a></span></dt>
509<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.channel_severity_filter">Severity
510          threshold per channel filter</a></span></dt>
511<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.is_debugger_present">Debugger
512          presence filter</a></span></dt>
513</dl></div>
514<p>
515          This section describes several expressions that can be used as predicates
516          in filtering expressions.
517        </p>
518<div class="section">
519<div class="titlepage"><div><div><h5 class="title">
520<a name="log.detailed.expressions.predicates.has_attr"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.has_attr" title="Attribute presence filter">Attribute
521          presence filter</a>
522</h5></div></div></div>
523<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.has_attr_hpp" title="Header &lt;boost/log/expressions/predicates/has_attr.hpp&gt;">boost/log/expressions/predicates/has_attr.hpp</a></code><span class="special">&gt;</span>
524</pre>
525<p>
526            The filter <code class="computeroutput"><a class="link" href="../../boost/log/expressions/has_attr_idm46079577821792.html" title="Function template has_attr">has_attr</a></code> checks if an
527            attribute value with the specified name and, optionally, type is attached
528            to a log record. If no type specified to the filter, the filter returns
529            <code class="computeroutput"><span class="keyword">true</span></code> if any value with the
530            specified name is found. If an MPL-compatible type sequence in specified
531            as a value type, the filter returns <code class="computeroutput"><span class="keyword">true</span></code>
532            if a value with the specified name and one of the specified types is
533            found.
534          </p>
535<p>
536            This filter is usually used in conjunction with <a class="link" href="expressions.html#log.detailed.expressions.formatters.conditional" title="Conditional formatters">conditional
537            formatters</a>, but it also can be used as a quick filter based on
538            the log record structure. For example, one can use this filter to extract
539            statistic records and route them to a specific sink.
540          </p>
541<p>
542</p>
543<pre class="programlisting"><span class="comment">// Declare attribute keywords</span>
544<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">stat_stream</span><span class="special">,</span> <span class="string">"StatisticStream"</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)</span>
545<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">change</span><span class="special">,</span> <span class="string">"Change"</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span>
546
547<span class="comment">// A simple sink backend to accumulate statistic information</span>
548<span class="keyword">class</span> <span class="identifier">my_stat_accumulator</span> <span class="special">:</span>
549    <span class="keyword">public</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">basic_sink_backend</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronized_feeding</span> <span class="special">&gt;</span>
550<span class="special">{</span>
551    <span class="comment">// A map of accumulated statistic values,</span>
552    <span class="comment">// ordered by the statistic information stream name</span>
553    <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">stat_info_map</span><span class="special">;</span>
554    <span class="identifier">stat_info_map</span> <span class="identifier">m_stat_info</span><span class="special">;</span>
555
556<span class="keyword">public</span><span class="special">:</span>
557    <span class="comment">// Destructor</span>
558    <span class="special">~</span><span class="identifier">my_stat_accumulator</span><span class="special">()</span>
559    <span class="special">{</span>
560        <span class="comment">// Display the accumulated data</span>
561        <span class="identifier">stat_info_map</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">m_stat_info</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">end</span> <span class="special">=</span> <span class="identifier">m_stat_info</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span>
562        <span class="keyword">for</span> <span class="special">(;</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">;</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span>
563        <span class="special">{</span>
564            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Statistic stream: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</span><span class="special">-&gt;</span><span class="identifier">first</span>
565                <span class="special">&lt;&lt;</span> <span class="string">", accumulated value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">it</span><span class="special">-&gt;</span><span class="identifier">second</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
566        <span class="special">}</span>
567        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">flush</span><span class="special">();</span>
568    <span class="special">}</span>
569
570    <span class="comment">// The method is called for every log record being put into the sink backend</span>
571    <span class="keyword">void</span> <span class="identifier">consume</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
572    <span class="special">{</span>
573        <span class="comment">// First, acquire statistic information stream name</span>
574        <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">stat_stream</span> <span class="special">&gt;</span> <span class="identifier">name</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">stat_stream</span><span class="special">];</span>
575        <span class="keyword">if</span> <span class="special">(</span><span class="identifier">name</span><span class="special">)</span>
576        <span class="special">{</span>
577            <span class="comment">// Next, get the statistic value change</span>
578            <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">change</span> <span class="special">&gt;</span> <span class="identifier">change_amount</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">change</span><span class="special">];</span>
579            <span class="keyword">if</span> <span class="special">(</span><span class="identifier">change_amount</span><span class="special">)</span>
580            <span class="special">{</span>
581                <span class="comment">// Accumulate the statistic data</span>
582                <span class="identifier">m_stat_info</span><span class="special">[</span><span class="identifier">name</span><span class="special">.</span><span class="identifier">get</span><span class="special">()]</span> <span class="special">+=</span> <span class="identifier">change_amount</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
583            <span class="special">}</span>
584        <span class="special">}</span>
585    <span class="special">}</span>
586<span class="special">};</span>
587
588<span class="comment">// The function registers two sinks - one for statistic information,</span>
589<span class="comment">// and another one for other records</span>
590<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
591<span class="special">{</span>
592    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>
593
594    <span class="comment">// Create a backend and attach a stream to it</span>
595    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span> <span class="special">=</span>
596        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;();</span>
597    <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
598        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&gt;(</span><span class="keyword">new</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span><span class="special">(</span><span class="string">"test.log"</span><span class="special">)));</span>
599
600    <span class="comment">// Create a frontend and setup filtering</span>
601    <span class="keyword">typedef</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronous_sink</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">log_sink_type</span><span class="special">;</span>
602    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">log_sink_type</span> <span class="special">&gt;</span> <span class="identifier">log_sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">log_sink_type</span><span class="special">(</span><span class="identifier">backend</span><span class="special">));</span>
603    <span class="comment">// All records that don't have a "StatisticStream" attribute attached</span>
604    <span class="comment">// will go to the "test.log" file</span>
605    <span class="identifier">log_sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span><span class="special">(!</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">has_attr</span><span class="special">(</span><span class="identifier">stat_stream</span><span class="special">));</span>
606
607    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">log_sink</span><span class="special">);</span>
608
609    <span class="comment">// Create another sink that will receive all statistic data</span>
610    <span class="keyword">typedef</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronous_sink</span><span class="special">&lt;</span> <span class="identifier">my_stat_accumulator</span> <span class="special">&gt;</span> <span class="identifier">stat_sink_type</span><span class="special">;</span>
611    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">stat_sink_type</span> <span class="special">&gt;</span> <span class="identifier">stat_sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">stat_sink_type</span><span class="special">());</span>
612    <span class="comment">// All records with a "StatisticStream" string attribute attached</span>
613    <span class="comment">// will go to the my_stat_accumulator sink</span>
614    <span class="identifier">stat_sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">has_attr</span><span class="special">(</span><span class="identifier">stat_stream</span><span class="special">));</span>
615
616    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">stat_sink</span><span class="special">);</span>
617<span class="special">}</span>
618
619<span class="comment">// This simple macro will simplify putting statistic data into a logger</span>
620<span class="preprocessor">#define</span> <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">stat_stream_name</span><span class="special">,</span> <span class="identifier">change</span><span class="special">)\</span>
621    <span class="keyword">if</span> <span class="special">(</span><span class="keyword">true</span><span class="special">)</span> <span class="special">{\</span>
622        <span class="identifier">BOOST_LOG_SCOPED_LOGGER_TAG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StatisticStream"</span><span class="special">,</span> <span class="identifier">stat_stream_name</span><span class="special">);\</span>
623        <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_value</span><span class="special">(</span><span class="string">"Change"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)(</span><span class="identifier">change</span><span class="special">));\</span>
624    <span class="special">}</span> <span class="keyword">else</span> <span class="special">((</span><span class="keyword">void</span><span class="special">)</span><span class="number">0</span><span class="special">)</span>
625
626<span class="keyword">void</span> <span class="identifier">logging_function</span><span class="special">()</span>
627<span class="special">{</span>
628    <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span>
629
630    <span class="comment">// Put a regular log record, it will go to the "test.log" file</span>
631    <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"A regular log record"</span><span class="special">;</span>
632
633    <span class="comment">// Put some statistic data</span>
634    <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamOne"</span><span class="special">,</span> <span class="number">10</span><span class="special">);</span>
635    <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamTwo"</span><span class="special">,</span> <span class="number">20</span><span class="special">);</span>
636    <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamOne"</span><span class="special">,</span> <span class="special">-</span><span class="number">5</span><span class="special">);</span>
637<span class="special">}</span>
638</pre>
639<p>
640          </p>
641<p>
642            <a href="../../../../../../libs/log/example/doc/expressions_has_attr_stat_accum.cpp" target="_top">See
643            the complete code</a>.
644          </p>
645<p>
646            In this example, log records emitted with the <code class="computeroutput"><span class="identifier">PUT_STAT</span></code>
647            macro will be directed to the <code class="computeroutput"><span class="identifier">my_stat_accumulator</span></code>
648            sink backend, which will accumulate the changes passed in the "Change"
649            attribute values. All other records (even those made through the same
650            logger) will be passed to the filter sink. This is achieved with the
651            mutually exclusive filters set for the two sinks.
652          </p>
653<p>
654            Please note that in the example above we extended the library in two
655            ways: we defined a new sink backend <code class="computeroutput"><span class="identifier">my_stat_accumulator</span></code>
656            and a new macro <code class="computeroutput"><span class="identifier">PUT_STAT</span></code>.
657            Also note that <code class="computeroutput"><span class="identifier">has_attr</span></code>
658            can accept attribute keywords to identify the attribute to check.
659          </p>
660</div>
661<div class="section">
662<div class="titlepage"><div><div><h5 class="title">
663<a name="log.detailed.expressions.predicates.is_in_range"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.is_in_range" title="Range checking filter">Range
664          checking filter</a>
665</h5></div></div></div>
666<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.is_in_range_hpp" title="Header &lt;boost/log/expressions/predicates/is_in_range.hpp&gt;">boost/log/expressions/predicates/is_in_range.hpp</a></code><span class="special">&gt;</span>
667</pre>
668<p>
669            The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/is_in_ra_idm46079577805680.html" title="Function template is_in_range">is_in_range</a></code> predicate
670            checks that the attribute value fits in the half-open range (i.e. it
671            returns <code class="computeroutput"><span class="keyword">true</span></code> if the attribute
672            value <code class="computeroutput"><span class="identifier">x</span></code> satisfies the
673            following condition: <code class="computeroutput"><span class="identifier">left</span> <span class="special">&lt;=</span> <span class="identifier">x</span> <span class="special">&lt;</span> <span class="identifier">right</span></code>).
674            For example:
675          </p>
676<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span>
677<span class="special">(</span>
678    <span class="comment">// drops all records that have level below 3 or greater than 4</span>
679    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">),</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
680<span class="special">);</span>
681</pre>
682<p>
683            The attribute can also be identified by an attribute keyword or name
684            and type:
685          </p>
686<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span>
687<span class="special">(</span>
688    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
689<span class="special">);</span>
690
691<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span>
692<span class="special">(</span>
693    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
694<span class="special">);</span>
695</pre>
696</div>
697<div class="section">
698<div class="titlepage"><div><div><h5 class="title">
699<a name="log.detailed.expressions.predicates.simple_string_matching"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.simple_string_matching" title="Simple string matching filters">Simple
700          string matching filters</a>
701</h5></div></div></div>
702<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.begins_with_hpp" title="Header &lt;boost/log/expressions/predicates/begins_with.hpp&gt;">boost/log/expressions/predicates/begins_with.hpp</a></code><span class="special">&gt;</span>
703<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.ends_with_hpp" title="Header &lt;boost/log/expressions/predicates/ends_with.hpp&gt;">boost/log/expressions/predicates/ends_with.hpp</a></code><span class="special">&gt;</span>
704<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.contains_hpp" title="Header &lt;boost/log/expressions/predicates/contains.hpp&gt;">boost/log/expressions/predicates/contains.hpp</a></code><span class="special">&gt;</span>
705</pre>
706<p>
707            Predicates <code class="computeroutput"><a class="link" href="../../boost/log/expressions/begins_w_idm46079578131920.html" title="Function template begins_with">begins_with</a></code>, <code class="computeroutput"><a class="link" href="../../boost/log/expressions/ends_wit_idm46079577870368.html" title="Function template ends_with">ends_with</a></code>
708            and <code class="computeroutput"><a class="link" href="../../boost/log/expressions/contains_idm46079577892816.html" title="Function template contains">contains</a></code> provide an
709            easy way of matching string attribute values. As follows from their names,
710            the functions construct filters that return <code class="computeroutput"><span class="keyword">true</span></code>
711            if an attribute value begins with, ends with or contains the specified
712            substring, respectively. The string comparison is case sensitive.
713          </p>
714<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span>
715<span class="special">(</span>
716    <span class="comment">// selects only records that are related to Russian web domains</span>
717    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Domain"</span><span class="special">),</span> <span class="string">".ru"</span><span class="special">)</span>
718<span class="special">);</span>
719</pre>
720<p>
721            The attribute can also be identified by an attribute keyword or name
722            and type.
723          </p>
724</div>
725<div class="section">
726<div class="titlepage"><div><div><h5 class="title">
727<a name="log.detailed.expressions.predicates.advanced_string_matching"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.advanced_string_matching" title="Advanced string matching filter">Advanced
728          string matching filter</a>
729</h5></div></div></div>
730<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.matches_hpp" title="Header &lt;boost/log/expressions/predicates/matches.hpp&gt;">boost/log/expressions/predicates/matches.hpp</a></code><span class="special">&gt;</span>
731
732<span class="comment">// Supporting headers</span>
733<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.regex_hpp" title="Header &lt;boost/log/support/regex.hpp&gt;">boost/log/support/regex.hpp</a></code><span class="special">&gt;</span>
734<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.std_regex_hpp" title="Header &lt;boost/log/support/std_regex.hpp&gt;">boost/log/support/std_regex.hpp</a></code><span class="special">&gt;</span>
735<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.xpressive_hpp" title="Header &lt;boost/log/support/xpressive.hpp&gt;">boost/log/support/xpressive.hpp</a></code><span class="special">&gt;</span>
736<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.spirit_qi_hpp" title="Header &lt;boost/log/support/spirit_qi.hpp&gt;">boost/log/support/spirit_qi.hpp</a></code><span class="special">&gt;</span>
737<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.spirit_classic_hpp" title="Header &lt;boost/log/support/spirit_classic.hpp&gt;">boost/log/support/spirit_classic.hpp</a></code><span class="special">&gt;</span>
738</pre>
739<p>
740            The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/matches_idm46079577768640.html" title="Function template matches">matches</a></code> function creates
741            a filter that apples a regular expression or a parser to a string attribute
742            value. The regular expression can be provided by <a href="http://www.boost.org/doc/libs/release/libs/regex/index.html" target="_top">Boost.Regex</a>
743            or <a href="http://www.boost.org/doc/libs/release/doc/html/xpressive.html" target="_top">Boost.Xpressive</a>.
744            Parsers from <a href="http://www.boost.org/doc/libs/release/libs/spirit/classic/index.html" target="_top">Boost.Spirit</a>
745            and <a href="http://www.boost.org/doc/libs/release/libs/spirit/doc/html/index.html" target="_top">Boost.Spirit2</a>
746            are also supported. The filter returns <code class="computeroutput"><span class="keyword">true</span></code>
747            if the regular expression matches or the parser successfully parses the
748            attribute value.
749          </p>
750<div class="note"><table border="0" summary="Note">
751<tr>
752<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
753<th align="left">Note</th>
754</tr>
755<tr><td align="left" valign="top"><p>
756              In order to use this predicate, a corresponding supporting header should
757              also be included.
758            </p></td></tr>
759</table></div>
760<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span>
761<span class="special">(</span>
762    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">matches</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Domain"</span><span class="special">),</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">regex</span><span class="special">(</span><span class="string">"www\\..*\\.ru"</span><span class="special">))</span>
763<span class="special">);</span>
764</pre>
765<p>
766            The attribute can also be identified by an attribute keyword or name
767            and type.
768          </p>
769</div>
770<div class="section">
771<div class="titlepage"><div><div><h5 class="title">
772<a name="log.detailed.expressions.predicates.channel_severity_filter"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.channel_severity_filter" title="Severity threshold per channel filter">Severity
773          threshold per channel filter</a>
774</h5></div></div></div>
775<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.channel_severity_filter_hpp" title="Header &lt;boost/log/expressions/predicates/channel_severity_filter.hpp&gt;">boost/log/expressions/predicates/channel_severity_filter.hpp</a></code><span class="special">&gt;</span>
776</pre>
777<p>
778            This filter is aimed for a specific but commonly encountered use case.
779            The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel_severity_filter.html" title="Function channel_severity_filter">channel_severity_filter</a></code>
780            function creates a predicate that will check log record severity levels
781            against a threshold. The predicate allows setting different thresholds
782            for different channels. The mapping between channel names and severity
783            thresholds can be filled in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code>
784            style by using the subscript operator or by calling <code class="computeroutput"><span class="identifier">add</span></code>
785            method on the filter itself (the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
786            instance). Let's see an example:
787          </p>
788<p>
789</p>
790<pre class="programlisting"><span class="comment">// We define our own severity levels</span>
791<span class="keyword">enum</span> <span class="identifier">severity_level</span>
792<span class="special">{</span>
793    <span class="identifier">normal</span><span class="special">,</span>
794    <span class="identifier">notification</span><span class="special">,</span>
795    <span class="identifier">warning</span><span class="special">,</span>
796    <span class="identifier">error</span><span class="special">,</span>
797    <span class="identifier">critical</span>
798<span class="special">};</span>
799
800<span class="comment">// Define the attribute keywords</span>
801<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">line_id</span><span class="special">,</span> <span class="string">"LineID"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span>
802<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">severity_level</span><span class="special">)</span>
803<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">channel</span><span class="special">,</span> <span class="string">"Channel"</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)</span>
804
805
806<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
807<span class="special">{</span>
808    <span class="comment">// Create a minimal severity table filter</span>
809    <span class="keyword">typedef</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">channel_severity_filter_actor</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="special">&gt;</span> <span class="identifier">min_severity_filter</span><span class="special">;</span>
810    <span class="identifier">min_severity_filter</span> <span class="identifier">min_severity</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">channel_severity_filter</span><span class="special">(</span><span class="identifier">channel</span><span class="special">,</span> <span class="identifier">severity</span><span class="special">);</span>
811
812    <span class="comment">// Set up the minimum severity levels for different channels</span>
813    <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"general"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">notification</span><span class="special">;</span>
814    <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"network"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">warning</span><span class="special">;</span>
815    <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"gui"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">error</span><span class="special">;</span>
816
817    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span>
818    <span class="special">(</span>
819        <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span>
820        <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">filter</span> <span class="special">=</span> <span class="identifier">min_severity</span> <span class="special">||</span> <span class="identifier">severity</span> <span class="special">&gt;=</span> <span class="identifier">critical</span><span class="special">,</span>
821        <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span>
822        <span class="special">(</span>
823            <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
824                <span class="special">&lt;&lt;</span> <span class="identifier">line_id</span>
825                <span class="special">&lt;&lt;</span> <span class="string">": &lt;"</span> <span class="special">&lt;&lt;</span> <span class="identifier">severity</span>
826                <span class="special">&lt;&lt;</span> <span class="string">"&gt; ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">channel</span> <span class="special">&lt;&lt;</span> <span class="string">"] "</span>
827                <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
828        <span class="special">)</span>
829    <span class="special">);</span>
830<span class="special">}</span>
831
832<span class="comment">// Define our logger type</span>
833<span class="keyword">typedef</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">severity_channel_logger</span><span class="special">&lt;</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">logger_type</span><span class="special">;</span>
834
835<span class="keyword">void</span> <span class="identifier">test_logging</span><span class="special">(</span><span class="identifier">logger_type</span><span class="special">&amp;</span> <span class="identifier">lg</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">channel_name</span><span class="special">)</span>
836<span class="special">{</span>
837    <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">normal</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"A normal severity level message"</span><span class="special">;</span>
838    <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">notification</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"A notification severity level message"</span><span class="special">;</span>
839    <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">warning</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"A warning severity level message"</span><span class="special">;</span>
840    <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">error</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"An error severity level message"</span><span class="special">;</span>
841    <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">critical</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"A critical severity level message"</span><span class="special">;</span>
842<span class="special">}</span>
843</pre>
844<p>
845          </p>
846<p>
847            <a href="../../../../../../libs/log/example/doc/expressions_channel_severity_filter.cpp" target="_top">See
848            the complete code</a>.
849          </p>
850<p>
851            The filter for the console sink is composed from the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
852            filter and a general severity level check. This general check will be
853            used when log records do not have a channel attribute or the channel
854            name is not one of those specified in <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
855            initialization. It should be noted that it is possible to set the default
856            result of the threshold filter that will be used in this case; the default
857            result can be set by the <code class="computeroutput"><span class="identifier">set_default</span></code>
858            method. The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
859            filter is set up to limit record severity levels for channels "general",
860            "network" and "gui" - all records in these channels
861            with levels below the specified thresholds will not pass the filter and
862            will be ignored.
863          </p>
864<p>
865            The threshold filter is implemented as an equivalent to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> over the channels, which means
866            that the channel value type must support partial ordering. Obviously,
867            the severity level type must also support ordering to be able to be compared
868            against thresholds. By default the predicate will use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span></code>
869            equivalent for channel name ordering and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">greater_equal</span></code>
870            equivalent to compare severity levels. It is possible to customize the
871            ordering predicates. Consult the reference of the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
872            class and <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel_severity_filter.html" title="Function channel_severity_filter">channel_severity_filter</a></code>
873            generator to see the relevant template parameters.
874          </p>
875</div>
876<div class="section">
877<div class="titlepage"><div><div><h5 class="title">
878<a name="log.detailed.expressions.predicates.is_debugger_present"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.is_debugger_present" title="Debugger presence filter">Debugger
879          presence filter</a>
880</h5></div></div></div>
881<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.is_debugger_present_hpp" title="Header &lt;boost/log/expressions/predicates/is_debugger_present.hpp&gt;">boost/log/expressions/predicates/is_debugger_present.hpp</a></code><span class="special">&gt;</span>
882</pre>
883<p>
884            This filter is implemented for Windows only. The <code class="computeroutput"><span class="identifier">is_debugger_present</span></code>
885            filter returns <code class="computeroutput"><span class="keyword">true</span></code> if the
886            application is run under a debugger and <code class="computeroutput"><span class="keyword">false</span></code>
887            otherwise. It does not use any attribute values from the log record.
888            This predicate is typically used with the <a class="link" href="sink_backends.html#log.detailed.sink_backends.debugger" title="Windows debugger output backend">debugger
889            output</a> sink.
890          </p>
891<p>
892</p>
893<pre class="programlisting"><span class="comment">// Complete sink type</span>
894<span class="keyword">typedef</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronous_sink</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">debug_output_backend</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
895
896<span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
897<span class="special">{</span>
898    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>
899
900    <span class="comment">// Create the sink. The backend requires synchronization in the frontend.</span>
901    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sink_t</span><span class="special">());</span>
902
903    <span class="comment">// Set the special filter to the frontend</span>
904    <span class="comment">// in order to skip the sink when no debugger is available</span>
905    <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_debugger_present</span><span class="special">());</span>
906
907    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
908<span class="special">}</span>
909</pre>
910<p>
911          </p>
912<p>
913            <a href="../../../../../../libs/log/example/doc/sinks_debugger.cpp" target="_top">See the complete
914            code</a>.
915          </p>
916</div>
917</div>
918<div class="section">
919<div class="titlepage"><div><div><h4 class="title">
920<a name="log.detailed.expressions.formatters"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters" title="Formatting expressions">Formatting expressions</a>
921</h4></div></div></div>
922<div class="toc"><dl class="toc">
923<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.date_time">Date
924          and time formatter</a></span></dt>
925<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.named_scope">Named
926          scope formatter</a></span></dt>
927<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.conditional">Conditional
928          formatters</a></span></dt>
929<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.auto_newline">Automatic
930          newline insertion</a></span></dt>
931<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.decorators">Character
932          decorators</a></span></dt>
933</dl></div>
934<p>
935          As was noted in the <a class="link" href="../tutorial/formatters.html" title="Log record formatting">tutorial</a>,
936          the library provides several ways of expressing formatters, most notable
937          being with a stream-style syntax and <a href="http://www.boost.org/doc/libs/release/libs/format/index.html" target="_top">Boost.Format</a>-style
938          expression. Which of the two formats is chosen is determined by the appropriate
939          anchor expression. To use stream-style syntax one should begin the formatter
940          definition with the <code class="computeroutput"><span class="identifier">stream</span></code>
941          keyword, like that:
942        </p>
943<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.stream_hpp" title="Header &lt;boost/log/expressions/formatters/stream.hpp&gt;">boost/log/expressions/formatters/stream.hpp</a></code><span class="special">&gt;</span>
944
945<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr1</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr2</span> <span class="special">&lt;&lt;</span> <span class="special">...</span> <span class="special">&lt;&lt;</span> <span class="identifier">exprN</span><span class="special">);</span>
946</pre>
947<p>
948          Here expressions <code class="computeroutput"><span class="identifier">expr1</span></code>
949          through <code class="computeroutput"><span class="identifier">exprN</span></code> may be either
950          manipulators, described in this section, or other expressions resulting
951          in an object that supports putting into an STL-stream.
952        </p>
953<p>
954          To use <a href="http://www.boost.org/doc/libs/release/libs/format/index.html" target="_top">Boost.Format</a>-style
955          syntax one should use <code class="computeroutput"><span class="identifier">format</span></code>
956          construct:
957        </p>
958<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.format_hpp" title="Header &lt;boost/log/expressions/formatters/format.hpp&gt;">boost/log/expressions/formatters/format.hpp</a></code><span class="special">&gt;</span>
959
960<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"format string"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">expr1</span> <span class="special">%</span> <span class="identifier">expr2</span> <span class="special">%</span> <span class="special">...</span> <span class="special">%</span> <span class="identifier">exprN</span><span class="special">);</span>
961</pre>
962<p>
963          The format string passed to the <code class="computeroutput"><span class="identifier">format</span></code>
964          keyword should contain positional placeholders for the appropriate expressions.
965          In the case of wide-character logging the format string should be wide.
966          Expressions <code class="computeroutput"><span class="identifier">expr1</span></code> through
967          <code class="computeroutput"><span class="identifier">exprN</span></code> have the same meaning
968          as in stream-like variant. It should be noted though that using stream-like
969          syntax usually results in a faster formatter than the one constructed with
970          the <code class="computeroutput"><span class="identifier">format</span></code> keyword.
971        </p>
972<p>
973          Another useful way of expressing formatters is by using string templates.
974          This part of the library is described in <a class="link" href="utilities.html#log.detailed.utilities.setup.filter_formatter" title="Filter and formatter parsers">this</a>
975          section and is mostly intended to support initialization from the application
976          settings.
977        </p>
978<div class="section">
979<div class="titlepage"><div><div><h5 class="title">
980<a name="log.detailed.expressions.formatters.date_time"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.date_time" title="Date and time formatter">Date
981          and time formatter</a>
982</h5></div></div></div>
983<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.date_time_hpp" title="Header &lt;boost/log/expressions/formatters/date_time.hpp&gt;">boost/log/expressions/formatters/date_time.hpp</a></code><span class="special">&gt;</span>
984
985<span class="comment">// Supporting headers</span>
986<span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.date_time_hpp" title="Header &lt;boost/log/support/date_time.hpp&gt;">boost/log/support/date_time.hpp</a></code><span class="special">&gt;</span>
987</pre>
988<p>
989            The library provides the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/format_d_idm46079578535872.html" title="Function template format_date_time">format_date_time</a></code> formatter
990            dedicated to date and time-related attribute value types. The function
991            accepts the attribute value name and the format string compatible with
992            <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>.
993          </p>
994<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
995<span class="special">(</span>
996    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_date_time</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span> <span class="special">&gt;(</span><span class="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S"</span><span class="special">)</span>
997<span class="special">);</span>
998</pre>
999<p>
1000            The attribute value can alternatively be identified with the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholder or the <a class="link" href="expressions.html#log.detailed.expressions.attr_keywords" title="Defining attribute keywords">attribute keyword</a>.
1001          </p>
1002<p>
1003            The following placeholders are supported in the format string:
1004          </p>
1005<div class="table">
1006<a name="log.detailed.expressions.formatters.date_time.date_format_placeholders"></a><p class="title"><b>Table 1.2. Date format placeholders</b></p>
1007<div class="table-contents"><table class="table" summary="Date format placeholders">
1008<colgroup>
1009<col>
1010<col>
1011<col>
1012</colgroup>
1013<thead><tr>
1014<th>
1015                    <p>
1016                      Placeholder
1017                    </p>
1018                  </th>
1019<th>
1020                    <p>
1021                      Meaning
1022                    </p>
1023                  </th>
1024<th>
1025                    <p>
1026                      Example
1027                    </p>
1028                  </th>
1029</tr></thead>
1030<tbody>
1031<tr>
1032<td>
1033                    <p>
1034                      %a
1035                    </p>
1036                  </td>
1037<td>
1038                    <p>
1039                      Abbreviated weekday name
1040                    </p>
1041                  </td>
1042<td>
1043                    <p>
1044                      "Mon" =&gt; Monday
1045                    </p>
1046                  </td>
1047</tr>
1048<tr>
1049<td>
1050                    <p>
1051                      %A
1052                    </p>
1053                  </td>
1054<td>
1055                    <p>
1056                      Long weekday name
1057                    </p>
1058                  </td>
1059<td>
1060                    <p>
1061                      "Monday"
1062                    </p>
1063                  </td>
1064</tr>
1065<tr>
1066<td>
1067                    <p>
1068                      %b
1069                    </p>
1070                  </td>
1071<td>
1072                    <p>
1073                      Abbreviated month name
1074                    </p>
1075                  </td>
1076<td>
1077                    <p>
1078                      "Feb" =&gt; February
1079                    </p>
1080                  </td>
1081</tr>
1082<tr>
1083<td>
1084                    <p>
1085                      %B
1086                    </p>
1087                  </td>
1088<td>
1089                    <p>
1090                      Long month name
1091                    </p>
1092                  </td>
1093<td>
1094                    <p>
1095                      "February"
1096                    </p>
1097                  </td>
1098</tr>
1099<tr>
1100<td>
1101                    <p>
1102                      %d
1103                    </p>
1104                  </td>
1105<td>
1106                    <p>
1107                      Numeric day of month with leading zero
1108                    </p>
1109                  </td>
1110<td>
1111                    <p>
1112                      "01"
1113                    </p>
1114                  </td>
1115</tr>
1116<tr>
1117<td>
1118                    <p>
1119                      %e
1120                    </p>
1121                  </td>
1122<td>
1123                    <p>
1124                      Numeric day of month with leading space
1125                    </p>
1126                  </td>
1127<td>
1128                    <p>
1129                      " 1"
1130                    </p>
1131                  </td>
1132</tr>
1133<tr>
1134<td>
1135                    <p>
1136                      %m
1137                    </p>
1138                  </td>
1139<td>
1140                    <p>
1141                      Numeric month, 01-12
1142                    </p>
1143                  </td>
1144<td>
1145                    <p>
1146                      "01"
1147                    </p>
1148                  </td>
1149</tr>
1150<tr>
1151<td>
1152                    <p>
1153                      %w
1154                    </p>
1155                  </td>
1156<td>
1157                    <p>
1158                      Numeric day of week, 1-7
1159                    </p>
1160                  </td>
1161<td>
1162                    <p>
1163                      "1"
1164                    </p>
1165                  </td>
1166</tr>
1167<tr>
1168<td>
1169                    <p>
1170                      %y
1171                    </p>
1172                  </td>
1173<td>
1174                    <p>
1175                      Short year
1176                    </p>
1177                  </td>
1178<td>
1179                    <p>
1180                      "12" =&gt; 2012
1181                    </p>
1182                  </td>
1183</tr>
1184<tr>
1185<td>
1186                    <p>
1187                      %Y
1188                    </p>
1189                  </td>
1190<td>
1191                    <p>
1192                      Long year
1193                    </p>
1194                  </td>
1195<td>
1196                    <p>
1197                      "2012"
1198                    </p>
1199                  </td>
1200</tr>
1201</tbody>
1202</table></div>
1203</div>
1204<br class="table-break"><div class="table">
1205<a name="log.detailed.expressions.formatters.date_time.time_format_placeholders"></a><p class="title"><b>Table 1.3. Time format placeholders</b></p>
1206<div class="table-contents"><table class="table" summary="Time format placeholders">
1207<colgroup>
1208<col>
1209<col>
1210<col>
1211</colgroup>
1212<thead><tr>
1213<th>
1214                    <p>
1215                      Placeholder
1216                    </p>
1217                  </th>
1218<th>
1219                    <p>
1220                      Meaning
1221                    </p>
1222                  </th>
1223<th>
1224                    <p>
1225                      Example
1226                    </p>
1227                  </th>
1228</tr></thead>
1229<tbody>
1230<tr>
1231<td>
1232                    <p>
1233                      %f
1234                    </p>
1235                  </td>
1236<td>
1237                    <p>
1238                      Fractional seconds with leading zeros
1239                    </p>
1240                  </td>
1241<td>
1242                    <p>
1243                      "000231"
1244                    </p>
1245                  </td>
1246</tr>
1247<tr>
1248<td>
1249                    <p>
1250                      %H, %O
1251                    </p>
1252                  </td>
1253<td>
1254                    <p>
1255                      Hours in 24 hour clock or hours in time duration types with
1256                      leading zero if less than 10
1257                    </p>
1258                  </td>
1259<td>
1260                    <p>
1261                      "07"
1262                    </p>
1263                  </td>
1264</tr>
1265<tr>
1266<td>
1267                    <p>
1268                      %I
1269                    </p>
1270                  </td>
1271<td>
1272                    <p>
1273                      Hours in 12 hour clock with leading zero if less than 10
1274                    </p>
1275                  </td>
1276<td>
1277                    <p>
1278                      "07"
1279                    </p>
1280                  </td>
1281</tr>
1282<tr>
1283<td>
1284                    <p>
1285                      %k
1286                    </p>
1287                  </td>
1288<td>
1289                    <p>
1290                      Hours in 24 hour clock or hours in time duration types with
1291                      leading space if less than 10
1292                    </p>
1293                  </td>
1294<td>
1295                    <p>
1296                      " 7"
1297                    </p>
1298                  </td>
1299</tr>
1300<tr>
1301<td>
1302                    <p>
1303                      %l
1304                    </p>
1305                  </td>
1306<td>
1307                    <p>
1308                      Hours in 12 hour clock with leading space if less than 10
1309                    </p>
1310                  </td>
1311<td>
1312                    <p>
1313                      " 7"
1314                    </p>
1315                  </td>
1316</tr>
1317<tr>
1318<td>
1319                    <p>
1320                      %M
1321                    </p>
1322                  </td>
1323<td>
1324                    <p>
1325                      Minutes
1326                    </p>
1327                  </td>
1328<td>
1329                    <p>
1330                      "32"
1331                    </p>
1332                  </td>
1333</tr>
1334<tr>
1335<td>
1336                    <p>
1337                      %p
1338                    </p>
1339                  </td>
1340<td>
1341                    <p>
1342                      AM/PM mark, uppercase
1343                    </p>
1344                  </td>
1345<td>
1346                    <p>
1347                      "AM"
1348                    </p>
1349                  </td>
1350</tr>
1351<tr>
1352<td>
1353                    <p>
1354                      %P
1355                    </p>
1356                  </td>
1357<td>
1358                    <p>
1359                      AM/PM mark, lowercase
1360                    </p>
1361                  </td>
1362<td>
1363                    <p>
1364                      "am"
1365                    </p>
1366                  </td>
1367</tr>
1368<tr>
1369<td>
1370                    <p>
1371                      %q
1372                    </p>
1373                  </td>
1374<td>
1375                    <p>
1376                      ISO time zone
1377                    </p>
1378                  </td>
1379<td>
1380                    <p>
1381                      "-0700" =&gt; Mountain Standard Time
1382                    </p>
1383                  </td>
1384</tr>
1385<tr>
1386<td>
1387                    <p>
1388                      %Q
1389                    </p>
1390                  </td>
1391<td>
1392                    <p>
1393                      Extended ISO time zone
1394                    </p>
1395                  </td>
1396<td>
1397                    <p>
1398                      "-05:00" =&gt; Eastern Standard Time
1399                    </p>
1400                  </td>
1401</tr>
1402<tr>
1403<td>
1404                    <p>
1405                      %S
1406                    </p>
1407                  </td>
1408<td>
1409                    <p>
1410                      Seconds
1411                    </p>
1412                  </td>
1413<td>
1414                    <p>
1415                      "26"
1416                    </p>
1417                  </td>
1418</tr>
1419</tbody>
1420</table></div>
1421</div>
1422<br class="table-break"><div class="table">
1423<a name="log.detailed.expressions.formatters.date_time.miscellaneous_placeholders"></a><p class="title"><b>Table 1.4. Miscellaneous placeholders</b></p>
1424<div class="table-contents"><table class="table" summary="Miscellaneous placeholders">
1425<colgroup>
1426<col>
1427<col>
1428<col>
1429</colgroup>
1430<thead><tr>
1431<th>
1432                    <p>
1433                      Placeholder
1434                    </p>
1435                  </th>
1436<th>
1437                    <p>
1438                      Meaning
1439                    </p>
1440                  </th>
1441<th>
1442                    <p>
1443                      Example
1444                    </p>
1445                  </th>
1446</tr></thead>
1447<tbody>
1448<tr>
1449<td>
1450                    <p>
1451                      %-
1452                    </p>
1453                  </td>
1454<td>
1455                    <p>
1456                      Negative sign in case of time duration, if the duration is
1457                      less than zero
1458                    </p>
1459                  </td>
1460<td>
1461                    <p>
1462                      "-"
1463                    </p>
1464                  </td>
1465</tr>
1466<tr>
1467<td>
1468                    <p>
1469                      %+
1470                    </p>
1471                  </td>
1472<td>
1473                    <p>
1474                      Sign of time duration, even if positive
1475                    </p>
1476                  </td>
1477<td>
1478                    <p>
1479                      "+"
1480                    </p>
1481                  </td>
1482</tr>
1483<tr>
1484<td>
1485                    <p>
1486                      %%
1487                    </p>
1488                  </td>
1489<td>
1490                    <p>
1491                      An escaped percent sign
1492                    </p>
1493                  </td>
1494<td>
1495                    <p>
1496                      "%"
1497                    </p>
1498                  </td>
1499</tr>
1500<tr>
1501<td>
1502                    <p>
1503                      %T
1504                    </p>
1505                  </td>
1506<td>
1507                    <p>
1508                      Extended ISO time, equivalent to "%H:%M:%S"
1509                    </p>
1510                  </td>
1511<td>
1512                    <p>
1513                      "07:32:26"
1514                    </p>
1515                  </td>
1516</tr>
1517</tbody>
1518</table></div>
1519</div>
1520<br class="table-break"><p>
1521            Note that in order to use this formatter you will also have to include
1522            a supporting header. When <code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.date_time_hpp" title="Header &lt;boost/log/support/date_time.hpp&gt;">boost/log/support/date_time.hpp</a></code>
1523            is included, the formatter supports the following types of <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>:
1524          </p>
1525<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1526<li class="listitem">
1527                Date and time types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span></code>
1528                and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">local_time</span><span class="special">::</span><span class="identifier">local_date_time</span></code>.
1529              </li>
1530<li class="listitem">
1531                Gregorian date type: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">gregorian</span><span class="special">::</span><span class="identifier">date</span></code>.
1532              </li>
1533<li class="listitem">
1534                Time duration types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">time_duration</span></code>
1535                as well as all the specialized time units such as <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">seconds</span></code>,
1536                including subsecond units.
1537              </li>
1538<li class="listitem">
1539                Date duration types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">gregorian</span><span class="special">::</span><span class="identifier">date_duration</span></code>.
1540              </li>
1541</ul></div>
1542<div class="tip"><table border="0" summary="Tip">
1543<tr>
1544<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
1545<th align="left">Tip</th>
1546</tr>
1547<tr><td align="left" valign="top"><p>
1548              <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>
1549              already provides formatting functionality implemented as a number of
1550              locale facets. This functionality can be used instead of this formatter,
1551              although the formatter is expected to provide better performance.
1552            </p></td></tr>
1553</table></div>
1554</div>
1555<div class="section">
1556<div class="titlepage"><div><div><h5 class="title">
1557<a name="log.detailed.expressions.formatters.named_scope"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.named_scope" title="Named scope formatter">Named
1558          scope formatter</a>
1559</h5></div></div></div>
1560<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.named_scope_hpp" title="Header &lt;boost/log/expressions/formatters/named_scope.hpp&gt;">boost/log/expressions/formatters/named_scope.hpp</a></code><span class="special">&gt;</span>
1561</pre>
1562<p>
1563            The formatter <code class="computeroutput"><a class="link" href="../../boost/log/expressions/format_n_idm46079578339104.html" title="Function template format_named_scope">format_named_scope</a></code> is
1564            intended to add support for flexible formatting of the <a class="link" href="attributes.html#log.detailed.attributes.named_scope" title="Named scopes">named
1565            scope</a> attribute values. The basic usage is quite straightforward
1566            and its result is similar to what <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> provides:
1567          </p>
1568<pre class="programlisting"><span class="comment">// Puts the scope stack from outer ones towards inner ones: outer scope -&gt; inner scope</span>
1569<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span><span class="string">"Scopes"</span><span class="special">,</span> <span class="string">"%n"</span><span class="special">));</span>
1570</pre>
1571<p>
1572            The first argument names the attribute and the second is the format string.
1573            The string can contain the following placeholders:
1574          </p>
1575<div class="table">
1576<a name="log.detailed.expressions.formatters.named_scope.named_scope_format_placeholders"></a><p class="title"><b>Table 1.5. Named scope format placeholders</b></p>
1577<div class="table-contents"><table class="table" summary="Named scope format placeholders">
1578<colgroup>
1579<col>
1580<col>
1581<col>
1582</colgroup>
1583<thead><tr>
1584<th>
1585                    <p>
1586                      Placeholder
1587                    </p>
1588                  </th>
1589<th>
1590                    <p>
1591                      Meaning
1592                    </p>
1593                  </th>
1594<th>
1595                    <p>
1596                      Example
1597                    </p>
1598                  </th>
1599</tr></thead>
1600<tbody>
1601<tr>
1602<td>
1603                    <p>
1604                      %n
1605                    </p>
1606                  </td>
1607<td>
1608                    <p>
1609                      Scope name
1610                    </p>
1611                  </td>
1612<td>
1613                    <p>
1614                      "void bar::foo()"
1615                    </p>
1616                  </td>
1617</tr>
1618<tr>
1619<td>
1620                    <p>
1621                      %c
1622                    </p>
1623                  </td>
1624<td>
1625                    <p>
1626                      Function name, if the scope is denoted with <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>,
1627                      otherwise the full scope name. See the note below.
1628                    </p>
1629                  </td>
1630<td>
1631                    <p>
1632                      "bar::foo"
1633                    </p>
1634                  </td>
1635</tr>
1636<tr>
1637<td>
1638                    <p>
1639                      %C
1640                    </p>
1641                  </td>
1642<td>
1643                    <p>
1644                      Function name, without the function scope, if the scope is
1645                      denoted with <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>,
1646                      otherwise the full scope name. See the note below.
1647                    </p>
1648                  </td>
1649<td>
1650                    <p>
1651                      "foo"
1652                    </p>
1653                  </td>
1654</tr>
1655<tr>
1656<td>
1657                    <p>
1658                      %f
1659                    </p>
1660                  </td>
1661<td>
1662                    <p>
1663                      Source file name of the scope
1664                    </p>
1665                  </td>
1666<td>
1667                    <p>
1668                      "/home/user/project/foo.cpp"
1669                    </p>
1670                  </td>
1671</tr>
1672<tr>
1673<td>
1674                    <p>
1675                      %F
1676                    </p>
1677                  </td>
1678<td>
1679                    <p>
1680                      Source file name of the scope, without the path
1681                    </p>
1682                  </td>
1683<td>
1684                    <p>
1685                      "foo.cpp"
1686                    </p>
1687                  </td>
1688</tr>
1689<tr>
1690<td>
1691                    <p>
1692                      %l
1693                    </p>
1694                  </td>
1695<td>
1696                    <p>
1697                      Line number in the source file
1698                    </p>
1699                  </td>
1700<td>
1701                    <p>
1702                      "45"
1703                    </p>
1704                  </td>
1705</tr>
1706</tbody>
1707</table></div>
1708</div>
1709<br class="table-break"><div class="note"><table border="0" summary="Note">
1710<tr>
1711<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
1712<th align="left">Note</th>
1713</tr>
1714<tr><td align="left" valign="top"><p>
1715              As described in the <a class="link" href="attributes.html#log.detailed.attributes.named_scope" title="Named scopes">named
1716              scope</a> attribute description, it is possible to use <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> macro to automatically
1717              generate scope names from the enclosing function name. Unfortunately,
1718              the actual format of the generated strings is compiler-dependent and
1719              in many cases it includes the complete signature of the function. When
1720              "%c" or "%C" format flag is specified, the library
1721              attempts to parse the generated string to extract the function name.
1722              Since C++ syntax is very context dependent and complex, it is not possible
1723              to parse function signature correctly in all cases, so the library
1724              is basically guessing. Depending on the string format, this may fail
1725              or produce incorrect results. In particular, type conversion operators
1726              can pose problems for the parser. In case if the parser fails to recognize
1727              the function signature the library falls back to using the whole string
1728              (i.e. behave equivalent to the "%n" flag). To alleviate the
1729              problem the user can replace the problematic <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>
1730              usage with the <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
1731              macro and explicitly write the desired scope name. Scope names denoted
1732              with <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
1733              will not be interpreted by the library and will be output as is. In
1734              general, for portability and runtime performance reasons it is preferable
1735              to always use <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
1736              and "%n" format flag.
1737            </p></td></tr>
1738</table></div>
1739<p>
1740            While the format string describes the presentation of each named scope
1741            in the list, the following named arguments allow to customize the list
1742            traversal and formatting:
1743          </p>
1744<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1745<li class="listitem">
1746                <code class="computeroutput"><span class="identifier">format</span></code>. The named
1747                scope format string, as described above. This parameter is used to
1748                specify the format when other named parameters are used.
1749              </li>
1750<li class="listitem">
1751                <code class="computeroutput"><span class="identifier">iteration</span></code>. The argument
1752                describes the direction of iteration through scopes. Can have values
1753                <code class="computeroutput"><span class="identifier">forward</span></code> (default)
1754                or <code class="computeroutput"><span class="identifier">reverse</span></code>.
1755              </li>
1756<li class="listitem">
1757                <code class="computeroutput"><span class="identifier">delimiter</span></code>. The argument
1758                can be used to specify the delimiters between scopes. The default
1759                delimiter depends on the <code class="computeroutput"><span class="identifier">iteration</span></code>
1760                argument. If <code class="computeroutput"><span class="identifier">iteration</span>
1761                <span class="special">==</span> <span class="identifier">forward</span></code>
1762                the default <code class="computeroutput"><span class="identifier">delimiter</span></code>
1763                will be "-&gt;", otherwise it will be "&lt;-".
1764              </li>
1765<li class="listitem">
1766                <code class="computeroutput"><span class="identifier">depth</span></code>. The argument
1767                can be used to limit the number of scopes to put to log. The formatter
1768                will print <code class="computeroutput"><span class="identifier">depth</span></code>
1769                innermost scopes and, if there are more scopes left, append an ellipsis
1770                to the written sequence. By default the formatter will write all
1771                scope names.
1772              </li>
1773<li class="listitem">
1774                <code class="computeroutput"><span class="identifier">incomplete_marker</span></code>.
1775                The argument can be used to specify the string that is used to indicate
1776                that the list has been limited by the <code class="computeroutput"><span class="identifier">depth</span></code>
1777                argument. By default the "..." string is used as the marker.
1778              </li>
1779<li class="listitem">
1780                <code class="computeroutput"><span class="identifier">empty_marker</span></code>. The
1781                argument can be used to specify the string to output in case if the
1782                scope list is empty. By default nothing is output in this case.
1783              </li>
1784</ul></div>
1785<p>
1786            Here are a few usage examples:
1787          </p>
1788<pre class="programlisting"><span class="comment">// Puts the scope stack in reverse order:</span>
1789<span class="comment">// inner scope (file:line) &lt;- outer scope (file:line)</span>
1790<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1791<span class="special">(</span>
1792    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1793        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span>
1794            <span class="string">"Scopes"</span><span class="special">,</span>
1795            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n (%f:%l)"</span><span class="special">,</span>
1796            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">)</span>
1797<span class="special">);</span>
1798
1799<span class="comment">// Puts the scope stack in reverse order with a custom delimiter:</span>
1800<span class="comment">// inner scope | outer scope</span>
1801<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1802<span class="special">(</span>
1803    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1804        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span>
1805            <span class="string">"Scopes"</span><span class="special">,</span>
1806            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span>
1807            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">,</span>
1808            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">delimiter</span> <span class="special">=</span> <span class="string">" | "</span><span class="special">)</span>
1809<span class="special">);</span>
1810
1811<span class="comment">// Puts the scope stack in forward order, no more than 2 inner scopes:</span>
1812<span class="comment">// ... outer scope -&gt; inner scope</span>
1813<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1814<span class="special">(</span>
1815    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1816        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span>
1817            <span class="string">"Scopes"</span><span class="special">,</span>
1818            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span>
1819            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">forward</span><span class="special">,</span>
1820            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">depth</span> <span class="special">=</span> <span class="number">2</span><span class="special">)</span>
1821<span class="special">);</span>
1822
1823<span class="comment">// Puts the scope stack in reverse order, no more than 2 inner scopes:</span>
1824<span class="comment">// inner scope &lt;- outer scope &lt;&lt;and more&gt;&gt;...</span>
1825<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1826<span class="special">(</span>
1827    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1828        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span>
1829            <span class="string">"Scopes"</span><span class="special">,</span>
1830            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span>
1831            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">,</span>
1832            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">incomplete_marker</span> <span class="special">=</span> <span class="string">" &lt;&lt;and more&gt;&gt;..."</span>
1833            <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">depth</span> <span class="special">=</span> <span class="number">2</span><span class="special">)</span>
1834<span class="special">);</span>
1835</pre>
1836<div class="tip"><table border="0" summary="Tip">
1837<tr>
1838<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
1839<th align="left">Tip</th>
1840</tr>
1841<tr><td align="left" valign="top"><p>
1842              An empty string can be specified as the <code class="computeroutput"><span class="identifier">incomplete_marker</span></code>
1843              parameter, in which case there will be no indication that the list
1844              was truncated.
1845            </p></td></tr>
1846</table></div>
1847</div>
1848<div class="section">
1849<div class="titlepage"><div><div><h5 class="title">
1850<a name="log.detailed.expressions.formatters.conditional"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.conditional" title="Conditional formatters">Conditional
1851          formatters</a>
1852</h5></div></div></div>
1853<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.if_hpp" title="Header &lt;boost/log/expressions/formatters/if.hpp&gt;">boost/log/expressions/formatters/if.hpp</a></code><span class="special">&gt;</span>
1854</pre>
1855<p>
1856            There are cases when one would want to check some condition about the
1857            log record and format it depending on that condition. One example of
1858            such a need is formatting an attribute value depending on its runtime
1859            type. The general syntax of the conditional formatter is as follows:
1860          </p>
1861<pre class="programlisting"><span class="identifier">expr</span><span class="special">::</span><span class="identifier">if_</span> <span class="special">(</span><span class="identifier">filter</span><span class="special">)</span>
1862<span class="special">[</span>
1863    <span class="identifier">true_formatter</span>
1864<span class="special">]</span>
1865<span class="special">.</span><span class="identifier">else_</span>
1866<span class="special">[</span>
1867    <span class="identifier">false_formatter</span>
1868<span class="special">]</span>
1869</pre>
1870<p>
1871            Those familiar with <a href="http://www.boost.org/doc/libs/release/libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
1872            lambda expressions will find this syntax quite familiar. The <code class="computeroutput"><span class="identifier">filter</span></code> argument is a filter that is
1873            applied to the record being formatted. If it returns <code class="computeroutput"><span class="keyword">true</span></code>,
1874            the <code class="computeroutput"><span class="identifier">true_formatter</span></code> is
1875            executed, otherwise <code class="computeroutput"><span class="identifier">false_formatter</span></code>
1876            is executed. The <code class="computeroutput"><span class="identifier">else_</span></code>
1877            section with <code class="computeroutput"><span class="identifier">false_formatter</span></code>
1878            is optional. If it is omitted and <code class="computeroutput"><span class="identifier">filter</span></code>
1879            yields <code class="computeroutput"><span class="keyword">false</span></code>, no formatter
1880            is executed. Here is an example:
1881          </p>
1882<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1883<span class="special">(</span>
1884    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1885        <span class="comment">// First, put the current time</span>
1886        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_date_time</span><span class="special">(</span><span class="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S.%f"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span>
1887        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">if_</span> <span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">has_attr</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"ID"</span><span class="special">))</span>
1888           <span class="special">[</span>
1889               <span class="comment">// if "ID" is present then put it to the record</span>
1890               <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"ID"</span><span class="special">)</span>
1891           <span class="special">]</span>
1892           <span class="special">.</span><span class="identifier">else_</span>
1893           <span class="special">[</span>
1894               <span class="comment">// otherwise put a missing marker</span>
1895               <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="string">"--"</span>
1896           <span class="special">]</span>
1897        <span class="comment">// and after that goes the log record text</span>
1898        <span class="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
1899<span class="special">);</span>
1900</pre>
1901</div>
1902<div class="section">
1903<div class="titlepage"><div><div><h5 class="title">
1904<a name="log.detailed.expressions.formatters.auto_newline"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.auto_newline" title="Automatic newline insertion">Automatic
1905          newline insertion</a>
1906</h5></div></div></div>
1907<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.auto_newline_hpp" title="Header &lt;boost/log/expressions/formatters/auto_newline.hpp&gt;">boost/log/expressions/formatters/auto_newline.hpp</a></code><span class="special">&gt;</span>
1908</pre>
1909<p>
1910            This is an adaptation of the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.auto_newline" title="Automatic newline insertion"><code class="computeroutput"><span class="identifier">auto_newline</span></code> manipulator</a> for
1911            formatter expressions. The <code class="computeroutput"><span class="identifier">auto_newline</span></code>
1912            formatter can be useful, for example, if log messages generated by one
1913            source are terminated with a newline character (and that behavior cannot
1914            be changed easily), and other messages are not. The formatter will ensure
1915            that all messages are reliably terminated with a newline and there are
1916            no duplicate newline characters. Like the manipulator, it will insert
1917            a newline unless the last character inserted into the stream before it
1918            was a newline. For example:
1919          </p>
1920<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1921<span class="special">(</span>
1922    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1923        <span class="comment">// Ensure that the sink outputs one message per line,</span>
1924        <span class="comment">// regardless whether the message itself ends with a newline or not</span>
1925        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">auto_newline</span>
1926<span class="special">);</span>
1927</pre>
1928</div>
1929<div class="section">
1930<div class="titlepage"><div><div><h5 class="title">
1931<a name="log.detailed.expressions.formatters.decorators"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators" title="Character decorators">Character
1932          decorators</a>
1933</h5></div></div></div>
1934<p>
1935            There are times when one would like to additionally post-process the
1936            composed string before passing it to the sink backend. For example, in
1937            order to store log into an XML file the formatted log record should be
1938            checked for special characters that have a special meaning in XML documents.
1939            This is where decorators step in.
1940          </p>
1941<div class="note"><table border="0" summary="Note">
1942<tr>
1943<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
1944<th align="left">Note</th>
1945</tr>
1946<tr><td align="left" valign="top"><p>
1947              Unlike most other formatters, decorators are dependent on the character
1948              type of the formatted output and this type cannot be deduced from the
1949              decorated formatter. By default, the character type is assumed to be
1950              <code class="computeroutput"><span class="keyword">char</span></code>. If the formatter
1951              is used to compose a wide-character string, prepend the decorator name
1952              with the <code class="computeroutput"><span class="identifier">w</span></code> letter (e.g.
1953              use <code class="computeroutput"><span class="identifier">wxml_decor</span></code> instead
1954              of <code class="computeroutput"><span class="identifier">xml_decor</span></code>). Also,
1955              for each decorator there is a generator function that accepts the character
1956              type as a template parameter; the function is named similarly to the
1957              decorator prepended with the <code class="computeroutput"><span class="identifier">make_</span></code>
1958              prefix (e.g. <code class="computeroutput"><span class="identifier">make_xml_decor</span></code>).
1959            </p></td></tr>
1960</table></div>
1961<div class="section">
1962<div class="titlepage"><div><div><h6 class="title">
1963<a name="log.detailed.expressions.formatters.decorators.xml"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.xml" title="XML character decorator">XML
1964            character decorator</a>
1965</h6></div></div></div>
1966<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.xml_decorator_hpp" title="Header &lt;boost/log/expressions/formatters/xml_decorator.hpp&gt;">boost/log/expressions/formatters/xml_decorator.hpp</a></code><span class="special">&gt;</span>
1967</pre>
1968<p>
1969              This decorator replaces XML special characters (&amp;, &lt;, &gt;,
1970              " and ') with the corresponding tokens (<code class="computeroutput"><span class="special">&amp;</span><span class="identifier">amp</span><span class="special">;</span></code>,
1971              <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">lt</span><span class="special">;</span></code>, <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">gt</span><span class="special">;</span></code>,
1972              <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">quot</span><span class="special">;</span></code> and <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">apos</span><span class="special">;</span></code>,
1973              correspondingly). The usage is as follows:
1974            </p>
1975<pre class="programlisting"><span class="identifier">xml_sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1976<span class="special">(</span>
1977    <span class="comment">// Apply the decoration to the whole formatted record</span>
1978    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">xml_decor</span>
1979    <span class="special">[</span>
1980        <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
1981    <span class="special">]</span>
1982<span class="special">);</span>
1983</pre>
1984<p>
1985              Since character decorators are yet another kind of formatters, it's
1986              fine to use them in other contexts where formatters are appropriate.
1987              For example, this is also a valid example:
1988            </p>
1989<pre class="programlisting"><span class="identifier">xml_sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1990<span class="special">(</span>
1991    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"&lt;message&gt;%1%: %2%&lt;/message&gt;"</span><span class="special">)</span>
1992        <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">)</span>
1993        <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">xml_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special">];</span> <span class="comment">// Only decorate the message text</span>
1994<span class="special">);</span>
1995</pre>
1996<p>
1997              There is an example of the library set up for logging into an XML file,
1998              see <a href="../../../../../../libs/log/example/doc/sinks_xml_file.cpp" target="_top">here</a>.
1999            </p>
2000</div>
2001<div class="section">
2002<div class="titlepage"><div><div><h6 class="title">
2003<a name="log.detailed.expressions.formatters.decorators.csv"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.csv" title="CSV character decorator">CSV
2004            character decorator</a>
2005</h6></div></div></div>
2006<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.csv_decorator_hpp" title="Header &lt;boost/log/expressions/formatters/csv_decorator.hpp&gt;">boost/log/expressions/formatters/csv_decorator.hpp</a></code><span class="special">&gt;</span>
2007</pre>
2008<p>
2009              This decorator allows to ensure that the resulting string conforms
2010              to the <a href="http://en.wikipedia.org/wiki/Comma-separated_values" target="_top">CSV</a>
2011              format requirements. In particular, it duplicates the quote characters
2012              in the formatted string.
2013            </p>
2014<pre class="programlisting"><span class="identifier">csv_sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
2015<span class="special">(</span>
2016    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
2017        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">","</span>
2018        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">csv_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Tag"</span><span class="special">)</span> <span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="string">","</span>
2019        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">csv_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special">]</span>
2020<span class="special">);</span>
2021</pre>
2022</div>
2023<div class="section">
2024<div class="titlepage"><div><div><h6 class="title">
2025<a name="log.detailed.expressions.formatters.decorators.c"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.c" title="C-style character decorators">C-style
2026            character decorators</a>
2027</h6></div></div></div>
2028<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.c_decorator_hpp" title="Header &lt;boost/log/expressions/formatters/c_decorator.hpp&gt;">boost/log/expressions/formatters/c_decorator.hpp</a></code><span class="special">&gt;</span>
2029</pre>
2030<p>
2031              The header defines two character decorators: <code class="computeroutput"><span class="identifier">c_decor</span></code>
2032              and <code class="computeroutput"><span class="identifier">c_ascii_decor</span></code>.
2033              The first one replaces the following characters with their escaped
2034              counterparts: \ (backslash, 0x5c), \a (bell character, 0x07), \b (backspace,
2035              0x08), \f (formfeed, 0x0c), \n (newline, 0x0a), \r (carriage return,
2036              0x0d), \t (horizontal tabulation, 0x09), \v (vertical tabulation, 0x0b),
2037              ' (apostroph, 0x27), " (quote, 0x22), ? (question mark, 0x3f).
2038              The <code class="computeroutput"><span class="identifier">c_ascii_decor</span></code> decorator
2039              does the same but also replaces all other non-printable and non-ASCII
2040              characters with escaped hexadecimal character codes in C notation (e.g.
2041              "\x8c"). The usage is similar to other character decorators:
2042            </p>
2043<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
2044<span class="special">(</span>
2045    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
2046        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">": ["</span>
2047        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">c_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Tag"</span><span class="special">)</span> <span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="string">"] "</span>
2048        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">c_ascii_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special">]</span>
2049<span class="special">);</span>
2050</pre>
2051</div>
2052<div class="section">
2053<div class="titlepage"><div><div><h6 class="title">
2054<a name="log.detailed.expressions.formatters.decorators.char"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.char" title="General character decorator">General
2055            character decorator</a>
2056</h6></div></div></div>
2057<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.char_decorator_hpp" title="Header &lt;boost/log/expressions/formatters/char_decorator.hpp&gt;">boost/log/expressions/formatters/char_decorator.hpp</a></code><span class="special">&gt;</span>
2058</pre>
2059<p>
2060              This decorator allows the user to define his own character replacement
2061              mapping in one of the two forms. The first form is a range of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code>s of strings (which can be C-style
2062              strings or ranges of characters, including <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>s).
2063              The strings in the <code class="computeroutput"><span class="identifier">first</span></code>
2064              elements of pairs will be replaced with the <code class="computeroutput"><span class="identifier">second</span></code>
2065              elements of the corresponding pair.
2066            </p>
2067<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="special">&gt;,</span> <span class="number">3</span> <span class="special">&gt;</span> <span class="identifier">shell_escapes</span> <span class="special">=</span>
2068<span class="special">{</span>
2069    <span class="special">{</span> <span class="string">"\""</span><span class="special">,</span> <span class="string">"\\\""</span> <span class="special">},</span>
2070    <span class="special">{</span> <span class="string">"'"</span><span class="special">,</span>  <span class="string">"\\'"</span> <span class="special">},</span>
2071    <span class="special">{</span> <span class="string">"$"</span><span class="special">,</span>  <span class="string">"\\$"</span> <span class="special">}</span>
2072<span class="special">};</span>
2073
2074<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
2075<span class="special">(</span>
2076    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">char_decor</span><span class="special">(</span><span class="identifier">shell_escapes</span><span class="special">)</span>
2077    <span class="special">[</span>
2078        <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2079    <span class="special">]</span>
2080<span class="special">);</span>
2081</pre>
2082<p>
2083              The second form is two same-sized sequences of strings; the first containing
2084              the search patterns and the second - the corresponding replacements.
2085            </p>
2086<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="number">3</span> <span class="special">&gt;</span> <span class="identifier">shell_patterns</span> <span class="special">=</span>
2087<span class="special">{</span>
2088    <span class="string">"\""</span><span class="special">,</span> <span class="string">"'"</span><span class="special">,</span> <span class="string">"$"</span>
2089<span class="special">};</span>
2090<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="number">3</span> <span class="special">&gt;</span> <span class="identifier">shell_replacements</span> <span class="special">=</span>
2091<span class="special">{</span>
2092    <span class="string">"\\\""</span><span class="special">,</span> <span class="string">"\\'"</span><span class="special">,</span> <span class="string">"\\$"</span>
2093<span class="special">};</span>
2094
2095<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
2096<span class="special">(</span>
2097    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">char_decor</span><span class="special">(</span><span class="identifier">shell_patterns</span><span class="special">,</span> <span class="identifier">shell_replacements</span><span class="special">)</span>
2098    <span class="special">[</span>
2099        <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2100    <span class="special">]</span>
2101<span class="special">);</span>
2102</pre>
2103<p>
2104              In both cases the patterns are not interpreted and are sought in the
2105              formatted characters in the original form.
2106            </p>
2107</div>
2108<div class="section">
2109<div class="titlepage"><div><div><h6 class="title">
2110<a name="log.detailed.expressions.formatters.decorators.max_size"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.max_size" title="String length limiting decorator">String
2111            length limiting decorator</a>
2112</h6></div></div></div>
2113<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.max_size_decorator_hpp" title="Header &lt;boost/log/expressions/formatters/max_size_decorator.hpp&gt;">boost/log/expressions/formatters/max_size_decorator.hpp</a></code><span class="special">&gt;</span>
2114</pre>
2115<p>
2116              Sometimes it can be useful to be able to limit the size of the output
2117              of a formatter or its part. For example, the limit might be imposed
2118              by the sink or the required output format. The <code class="computeroutput"><span class="identifier">max_size_decor</span></code>
2119              decorator allows to enforce such limit. Let's see a simple example:
2120            </p>
2121<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
2122<span class="special">(</span>
2123    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">max_size_decor</span><span class="special">&lt;</span> <span class="keyword">char</span> <span class="special">&gt;(</span><span class="number">20</span><span class="special">)</span>
2124    <span class="special">[</span>
2125        <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2126    <span class="special">]</span>
2127<span class="special">);</span>
2128</pre>
2129<div class="note"><table border="0" summary="Note">
2130<tr>
2131<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
2132<th align="left">Note</th>
2133</tr>
2134<tr><td align="left" valign="top"><p>
2135                The explicit template parameter for <code class="computeroutput"><span class="identifier">max_size_decor</span></code>
2136                specifies the character type that is used by formatter. In this example
2137                the string produced by the formatter contains characters of type
2138                <code class="computeroutput"><span class="keyword">char</span></code>, hence the template
2139                parameter.
2140              </p></td></tr>
2141</table></div>
2142<p>
2143              In this example the decorator limits the log message to no more than
2144              20 <a href="https://en.wikipedia.org/wiki/Character_encoding#Terminology" target="_top">code
2145              units</a> of type <code class="computeroutput"><span class="keyword">char</span></code>
2146              and removes the rest from the output. So if we had a log record like
2147              this:
2148            </p>
2149<pre class="programlisting"><span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"The quick brown fox jumps over the lazy dog"</span><span class="special">;</span>
2150</pre>
2151<p>
2152              the resulting output would look like this:
2153            </p>
2154<pre class="programlisting">The quick brown fox
2155</pre>
2156<p>
2157              However, looking at this output in a log file it is unclear whether
2158              the original output contained anything else. One might want to indicate
2159              the fact of message truncation, should one occur. For that purpose
2160              the decorator allows to specify an overflow marker that will be placed
2161              at the end of the truncated output, if the truncation took place. We
2162              can modify the above example like this:
2163            </p>
2164<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
2165<span class="special">(</span>
2166    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">max_size_decor</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="string">"&gt;&gt;&gt;"</span><span class="special">)</span>
2167    <span class="special">[</span>
2168        <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2169    <span class="special">]</span>
2170<span class="special">);</span>
2171</pre>
2172<div class="tip"><table border="0" summary="Tip">
2173<tr>
2174<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
2175<th align="left">Tip</th>
2176</tr>
2177<tr><td align="left" valign="top"><p>
2178                The formatter character type is deduced from the character type of
2179                the overflow marker, so it can be omitted.
2180              </p></td></tr>
2181</table></div>
2182<p>
2183              Now our log record will look like this in the output:
2184            </p>
2185<pre class="programlisting">The quick brown f&gt;&gt;&gt;
2186</pre>
2187<p>
2188              This output makes it more obvious that there was more to the original
2189              message. Note also that the length of the output is still 20 characters;
2190              the marker replaced the last characters of the truncated output.
2191            </p>
2192<div class="tip"><table border="0" summary="Tip">
2193<tr>
2194<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
2195<th align="left">Tip</th>
2196</tr>
2197<tr><td align="left" valign="top"><p>
2198                For the character truncation and marker positioning to work correctly
2199                in multibyte encodings, it is important that the locale used by the
2200                formatter is set up properly. In particular, the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">codecvt</span></code>
2201                facet in the locale must correctly recognize multibyte sequences
2202                corresponding to a single character in the output. One can use <a href="http://www.boost.org/doc/libs/release/libs/locale/doc/html/index.html" target="_top">Boost.Locale</a>
2203                to generate the locale and then install it in the sink frontend by
2204                calling <code class="computeroutput"><span class="identifier">imbue</span></code> (see
2205                <code class="computeroutput"><a class="link" href="../../boost/log/sinks/basic_fo_idm46079576891744.html" title="Class template basic_formatting_sink_frontend">basic_formatting_sink_frontend</a></code>
2206                for reference). If the output character type is <code class="computeroutput"><span class="keyword">wchar_t</span></code>,
2207                <code class="computeroutput"><span class="keyword">char16_t</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code> the library assumes that
2208                the output is encoded in UTF-16 or UTF-32, depending on the size
2209                of the character type. Because the truncation might occur in the
2210                middle of a multi-unit character, truncated output produced by the
2211                decorator can be slightly shorter than the specified limit sometimes.
2212              </p></td></tr>
2213</table></div>
2214<p>
2215              As with any other formatter, <code class="computeroutput"><span class="identifier">max_size_decor</span></code>
2216              can participate in more complex formatting expressions and limit length
2217              of only part of the message.
2218            </p>
2219<pre class="programlisting"><span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
2220<span class="special">(</span>
2221    <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
2222        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_date_time</span><span class="special">(</span><span class="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S.%f"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">" ["</span>
2223        <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">max_size_decor</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="string">"&gt;&gt;&gt;"</span><span class="special">)</span>
2224           <span class="special">[</span>
2225               <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2226           <span class="special">]</span>
2227        <span class="special">&lt;&lt;</span> <span class="string">"]"</span>
2228<span class="special">);</span>
2229</pre>
2230<p>
2231              The above formatter can produce output like this:
2232            </p>
2233<pre class="programlisting">2016-08-10 00:36:44.028473 [The quick brown f&gt;&gt;&gt;]
2234</pre>
2235</div>
2236</div>
2237</div>
2238</div>
2239<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
2240<td align="left"></td>
2241<td align="right"><div class="copyright-footer">Copyright © 2007-2019 Andrey Semashev<p>
2242        Distributed under the Boost Software License, Version 1.0. (See accompanying
2243        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>).
2244      </p>
2245</div></td>
2246</tr></table>
2247<hr>
2248<div class="spirit-nav">
2249<a accesskey="p" href="sink_backends.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../detailed.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="attributes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
2250</div>
2251</body>
2252</html>
2253