Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / log / doc / html / log / detailed / attributes.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Attributes</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&#160;1.&#160;Boost.Log v2">
8 <link rel="up" href="../detailed.html" title="Detailed features description">
9 <link rel="prev" href="expressions.html" title="Lambda expressions">
10 <link rel="next" href="utilities.html" title="Utilities">
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="expressions.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="utilities.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.attributes"></a><a class="link" href="attributes.html" title="Attributes">Attributes</a>
21 </h3></div></div></div>
22 <div class="toc"><dl class="toc">
23 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.constant">Constants</a></span></dt>
24 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.mutable_constant">Mutable constants</a></span></dt>
25 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.counter">Counters</a></span></dt>
26 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.clock">Wall clock</a></span></dt>
27 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.timer">Stop watch (timer)</a></span></dt>
28 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.named_scope">Named scopes</a></span></dt>
29 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.process_id">Current process
30         identifier</a></span></dt>
31 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.process_name">Current process
32         name</a></span></dt>
33 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.thread_id">Current thread identifier</a></span></dt>
34 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.function">Function objects
35         as attributes</a></span></dt>
36 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components">Other attribute-related
37         components</a></span></dt>
38 </dl></div>
39 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_hpp" title="Header &lt;boost/log/attributes/attribute.hpp&gt;">boost/log/attributes/attribute.hpp</a></code><span class="special">&gt;</span>
40 <span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_cast_hpp" title="Header &lt;boost/log/attributes/attribute_cast.hpp&gt;">boost/log/attributes/attribute_cast.hpp</a></code><span class="special">&gt;</span>
41 <span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_value_hpp" title="Header &lt;boost/log/attributes/attribute_value.hpp&gt;">boost/log/attributes/attribute_value.hpp</a></code><span class="special">&gt;</span>
42 </pre>
43 <p>
44         All attributes in the library are implemented using the <a href="http://c2.com/cgi/wiki?PimplIdiom" target="_top">pimpl
45         idiom</a>, or more specifically - shared pimpl idiom. Every attribute
46         provides an interface class which derives from the <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code>
47         class and an implementation class that derives from <code class="computeroutput"><a class="link" href="../../boost/log/attribute/impl.html" title="Struct impl">impl</a></code>.
48         The interface class only holds a reference counted pointer to the actual
49         implementation of the attribute; this pointer is a member of the <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> class, so derived interface
50         classes don't have any data members. When the interface class is default
51         constructed, it creates the corresponding implementation object and initializes
52         the <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> base class
53         with a pointer to the implementation. Therefore the pimpl nature of attributes
54         is transparent for users in a typical workflow.
55       </p>
56 <p>
57         The shared pimpl design comes significant in a few cases though. One such
58         case is copying the attribute. The copy operation is shallow, so multiple
59         interface objects may refer to a single implementation object. There is no
60         way to deep copy an attribute. Another case is default construction of <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> which creates an empty
61         object that does not refer to an implementation. Attributes in such empty
62         state should not be passed to the library but can be useful in some cases,
63         e.g. when a delayed variable initialization is needed.
64       </p>
65 <p>
66         It is possible to upcast the attribute interface from <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code>
67         to the actual interface class. To do this one has to apply <code class="computeroutput"><a class="link" href="../../boost/log/attribute_cast.html" title="Function template attribute_cast">attribute_cast</a></code>:
68       </p>
69 <pre class="programlisting"><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute</span> <span class="identifier">attr</span> <span class="special">=</span> <span class="special">...;</span>
70 <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">const_attr</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_cast</span><span class="special">&lt;</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="special">&gt;(</span><span class="identifier">attr</span><span class="special">);</span>
71 </pre>
72 <p>
73         In this example, the cast will succeed (i.e. the <code class="computeroutput"><span class="identifier">const_attr</span></code>
74         will be non-empty) if the attribute <code class="computeroutput"><span class="identifier">attr</span></code>
75         was originally created as <code class="computeroutput"><span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;</span></code>. Since all data is stored in the implementation
76         object, no data is lost in the casting process.
77       </p>
78 <p>
79         The main purpose of attributes is to generate attribute values. Values are
80         semantically distinct from the attributes. Such separation allows implementing
81         attributes that can return different values at different time points (like
82         clock-related attributes, for example) and, on the other hand, allows using
83         different values of the same attribute independently. The <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code>
84         interface has a method named <code class="computeroutput"><span class="identifier">get_value</span></code>
85         that returns the actual attribute value. Attribute values are also implemented
86         using the shared pimpl approach, the interface class is <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code>
87         and implementation classes derive from <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value/impl.html" title="Struct impl">impl</a></code>.
88       </p>
89 <p>
90         The attribute value object is mostly intended to store the actual attribute
91         value and implement type dispatching in order to be able to extract the stored
92         value. One should not confuse the attribute value object type and the stored
93         value type. The former is in most cases not needed by users and provides
94         type erasure, but the latter is needed to be able to extract the value. For
95         brevity we call the stored attribute value type simply the attribute value
96         type in this documentation.
97       </p>
98 <div class="section">
99 <div class="titlepage"><div><div><h4 class="title">
100 <a name="log.detailed.attributes.constant"></a><a class="link" href="attributes.html#log.detailed.attributes.constant" title="Constants">Constants</a>
101 </h4></div></div></div>
102 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.constant_hpp" title="Header &lt;boost/log/attributes/constant.hpp&gt;">boost/log/attributes/constant.hpp</a></code><span class="special">&gt;</span>
103 </pre>
104 <p>
105           The most simple and frequently used attribute type is a constant value
106           of some type. This kind of attribute is implemented with the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/constant.html" title="Class template constant">constant</a></code> class template.
107           The template is parametrized with the attribute value type. The constant
108           value should be passed to the attribute constructor. Here is an example:
109         </p>
110 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
111 <span class="special">{</span>
112     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span>
113
114     <span class="comment">// Register a constant attribute that always yields value -5</span>
115     <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(-</span><span class="number">5</span><span class="special">));</span>
116
117     <span class="comment">// Register another constant attribute. Make it a string this time.</span>
118     <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyString"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</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">"Hello world!"</span><span class="special">));</span>
119
120     <span class="comment">// There is also a convenience generator function. "MyInteger2" is constant&lt; int &gt; here.</span>
121     <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger2"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">make_constant</span><span class="special">(</span><span class="number">10</span><span class="special">));</span>
122 <span class="special">}</span>
123 </pre>
124 <p>
125           That's it, there's nothing much you can do with a constant attribute. Constants
126           are very useful when one wants to highlight some log records or just pass
127           some data to a sink backend (e.g. pass statistical parameters to the collector).
128         </p>
129 </div>
130 <div class="section">
131 <div class="titlepage"><div><div><h4 class="title">
132 <a name="log.detailed.attributes.mutable_constant"></a><a class="link" href="attributes.html#log.detailed.attributes.mutable_constant" title="Mutable constants">Mutable constants</a>
133 </h4></div></div></div>
134 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.mutable_constant_hpp" title="Header &lt;boost/log/attributes/mutable_constant.hpp&gt;">boost/log/attributes/mutable_constant.hpp</a></code><span class="special">&gt;</span>
135 </pre>
136 <p>
137           This kind of attribute is an extension for the <a class="link" href="attributes.html#log.detailed.attributes.constant" title="Constants">constant
138           attribute</a>. In addition to being able to store some value, the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/mutable_constant.html" title="Class template mutable_constant">mutable_constant</a></code>
139           class template has two distinctions:
140         </p>
141 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
142 <li class="listitem">
143               it allows modification of the stored value without re-registering the
144               attribute
145             </li>
146 <li class="listitem">
147               it allows synchronization of the stores and reads of the stored value
148             </li>
149 </ul></div>
150 <p>
151           In order to change the stored value of the attribute, one must call the
152           <code class="computeroutput"><span class="identifier">set</span></code> method:
153         </p>
154 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
155 <span class="special">{</span>
156     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span>
157
158     <span class="comment">// Register a mutable constant attribute that always yields value -5</span>
159     <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">mutable_constant</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">attr</span><span class="special">(-</span><span class="number">5</span><span class="special">);</span>
160     <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger"</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span>
161     <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">"This record has MyInteger == -5"</span><span class="special">;</span>
162
163     <span class="comment">// Change the attribute value</span>
164     <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="number">100</span><span class="special">);</span>
165     <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">"This record has MyInteger == 100"</span><span class="special">;</span>
166 <span class="special">}</span>
167 </pre>
168 <p>
169           In multithreaded applications the <code class="computeroutput"><span class="identifier">set</span></code>
170           method calls must be serialized with the <code class="computeroutput"><span class="identifier">get_value</span></code>
171           calls (which, generally speaking, happen on every log record being made).
172           By default <code class="computeroutput"><a class="link" href="../../boost/log/attributes/mutable_constant.html" title="Class template mutable_constant">mutable_constant</a></code>
173           does not serialize calls in any way, assuming that the user will do so
174           externally. However, the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/mutable_constant.html" title="Class template mutable_constant">mutable_constant</a></code>
175           template provides three additional template arguments: synchronization
176           primitive type, scoped exclusive lock type and scoped shareable lock type.
177           If a synchronization primitive type is specified, the scoped exclusive
178           lock type is a mandatory parameter. If the scoped shareable lock type is
179           not specified, the attribute will fall back to the exclusive lock instead
180           of shared locks. For example:
181         </p>
182 <pre class="programlisting"><span class="comment">// This mutable constant will always lock exclusively</span>
183 <span class="comment">// either for reading or storing the value</span>
184 <span class="keyword">typedef</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">mutable_constant</span><span class="special">&lt;</span>
185     <span class="keyword">int</span><span class="special">,</span>                                        <span class="comment">// attribute value type</span>
186     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">,</span>                               <span class="comment">// synchronization primitive</span>
187     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lock_guard</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span>           <span class="comment">// exclusive lock type</span>
188 <span class="special">&gt;</span> <span class="identifier">exclusive_mc</span><span class="special">;</span>
189 <span class="identifier">exclusive_mc</span> <span class="identifier">my_int1</span><span class="special">(</span><span class="number">10</span><span class="special">);</span>
190
191 <span class="comment">// This mutable constant will use shared clocking for reading the value</span>
192 <span class="comment">// and exclusive locking for storing</span>
193 <span class="keyword">typedef</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">mutable_constant</span><span class="special">&lt;</span>
194     <span class="keyword">int</span><span class="special">,</span>                                        <span class="comment">// attribute value type</span>
195     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_mutex</span><span class="special">,</span>                        <span class="comment">// synchronization primitive</span>
196     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_mutex</span> <span class="special">&gt;,</span>  <span class="comment">// exclusive lock type</span>
197     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_mutex</span> <span class="special">&gt;</span>   <span class="comment">// shared lock type</span>
198 <span class="special">&gt;</span> <span class="identifier">shared_mc</span><span class="special">;</span>
199 <span class="identifier">shared_mc</span> <span class="identifier">my_int2</span><span class="special">(</span><span class="number">20</span><span class="special">);</span>
200
201 <span class="identifier">BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span>
202 <span class="special">{</span>
203     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span> <span class="identifier">lg</span><span class="special">;</span>
204     <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger1"</span><span class="special">,</span> <span class="identifier">my_int1</span><span class="special">);</span>
205     <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger2"</span><span class="special">,</span> <span class="identifier">my_int2</span><span class="special">);</span>
206
207     <span class="keyword">return</span> <span class="identifier">lg</span><span class="special">;</span>
208 <span class="special">}</span>
209
210 <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
211 <span class="special">{</span>
212     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">&amp;</span> <span class="identifier">lg</span> <span class="special">=</span> <span class="identifier">get_my_logger</span><span class="special">();</span>
213
214     <span class="comment">// This is safe, even if executed in multiple threads</span>
215     <span class="identifier">my_int1</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="number">200</span><span class="special">);</span>
216     <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">"This record has MyInteger1 == 200"</span><span class="special">;</span>
217
218     <span class="identifier">my_int2</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="number">300</span><span class="special">);</span>
219     <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">"This record has MyInteger2 == 300"</span><span class="special">;</span>
220 <span class="special">}</span>
221 </pre>
222 <p>
223           Mutable constants are often used as auxiliary attributes inside loggers
224           to store attributes that may change on some events. As opposed to regular
225           constants, which would require re-registering in case of value modification,
226           mutable constants allow modifying the value in-place.
227         </p>
228 </div>
229 <div class="section">
230 <div class="titlepage"><div><div><h4 class="title">
231 <a name="log.detailed.attributes.counter"></a><a class="link" href="attributes.html#log.detailed.attributes.counter" title="Counters">Counters</a>
232 </h4></div></div></div>
233 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.counter_hpp" title="Header &lt;boost/log/attributes/counter.hpp&gt;">boost/log/attributes/counter.hpp</a></code><span class="special">&gt;</span>
234 </pre>
235 <p>
236           Counters are one of the simplest attributes that generate a new value each
237           time requested. Counters are often used to identify log records or to count
238           some events, e.g. accepted network connections. The class template <code class="computeroutput"><a class="link" href="../../boost/log/attributes/counter.html" title="Class template counter">counter</a></code> provides such
239           functionality. This template is parametrized with the counter value type,
240           which should support arithmetic operations, such as <code class="computeroutput"><span class="keyword">operator</span>
241           <span class="special">+</span></code> and <code class="computeroutput"><span class="keyword">operator</span>
242           <span class="special">-</span></code>. The counter attribute allows
243           specification of the initial value and step (which can be negative) on
244           construction.
245         </p>
246 <pre class="programlisting"><span class="identifier">BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span>
247 <span class="special">{</span>
248     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span> <span class="identifier">lg</span><span class="special">;</span>
249
250     <span class="comment">// This counter will count lines, starting from 0</span>
251     <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"LineCounter"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">counter</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;());</span>
252
253     <span class="comment">// This counter will count backwards, starting from 100 with step -5</span>
254     <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"CountDown"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">counter</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="number">100</span><span class="special">,</span> <span class="special">-</span><span class="number">5</span><span class="special">));</span>
255
256     <span class="keyword">return</span> <span class="identifier">lg</span><span class="special">;</span>
257 <span class="special">}</span>
258
259 <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
260 <span class="special">{</span>
261     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">&amp;</span> <span class="identifier">lg</span> <span class="special">=</span> <span class="identifier">get_my_logger</span><span class="special">();</span>
262     <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">"This record has LineCounter == 0, CountDown == 100"</span><span class="special">;</span>
263     <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">"This record has LineCounter == 1, CountDown == 95"</span><span class="special">;</span>
264     <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">"This record has LineCounter == 2, CountDown == 90"</span><span class="special">;</span>
265 <span class="special">}</span>
266 </pre>
267 <div class="note"><table border="0" summary="Note">
268 <tr>
269 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
270 <th align="left">Note</th>
271 </tr>
272 <tr><td align="left" valign="top"><p>
273             Don't expect that the log records with the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/counter.html" title="Class template counter">counter</a></code>
274             attribute will always have ascending or descending counter values in
275             the resulting log. In multithreaded applications counter values acquired
276             by different threads may come to a sink in any order. See <a class="link" href="../rationale/why_weak_record_ordering.html" title="Why log records are weakly ordered in a multithreaded application?">Rationale</a>
277             for a more detailed explanation on why it can happen. For this reason
278             it is more accurate to say that the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/counter.html" title="Class template counter">counter</a></code>
279             attribute generates an identifier in an ascending or descending order
280             rather than that it counts log records in either order.
281           </p></td></tr>
282 </table></div>
283 </div>
284 <div class="section">
285 <div class="titlepage"><div><div><h4 class="title">
286 <a name="log.detailed.attributes.clock"></a><a class="link" href="attributes.html#log.detailed.attributes.clock" title="Wall clock">Wall clock</a>
287 </h4></div></div></div>
288 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.clock_hpp" title="Header &lt;boost/log/attributes/clock.hpp&gt;">boost/log/attributes/clock.hpp</a></code><span class="special">&gt;</span>
289 </pre>
290 <p>
291           One of the "must-have" features of any logging library is support
292           for attaching a time stamp to every log record. The library provides two
293           attributes for this purpose: <code class="computeroutput"><span class="identifier">utc_clock</span></code>
294           and <code class="computeroutput"><span class="identifier">local_clock</span></code>. The former
295           returns the current UTC time and the latter returns the current local time.
296           In either case the returned time stamp is acquired with the maximum precision
297           for the target platform. The attribute value is <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>
298           (see <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>).
299           The usage is quite straightforward:
300         </p>
301 <pre class="programlisting"><span class="identifier">BOOST_LOG_DECLARE_GLOBAL_LOGGER</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span>
302
303 <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
304 <span class="special">{</span>
305     <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">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span>
306         <span class="string">"TimeStamp"</span><span class="special">,</span>
307         <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">local_clock</span><span class="special">());</span>
308
309     <span class="comment">// Now every log record ever made will have a time stamp attached</span>
310     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">&amp;</span> <span class="identifier">lg</span> <span class="special">=</span> <span class="identifier">get_my_logger</span><span class="special">();</span>
311     <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">"This record has a time stamp"</span><span class="special">;</span>
312 <span class="special">}</span>
313 </pre>
314 </div>
315 <div class="section">
316 <div class="titlepage"><div><div><h4 class="title">
317 <a name="log.detailed.attributes.timer"></a><a class="link" href="attributes.html#log.detailed.attributes.timer" title="Stop watch (timer)">Stop watch (timer)</a>
318 </h4></div></div></div>
319 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.timer_hpp" title="Header &lt;boost/log/attributes/timer.hpp&gt;">boost/log/attributes/timer.hpp</a></code><span class="special">&gt;</span>
320 </pre>
321 <p>
322           The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code> attribute
323           is very useful when there is a need to estimate the duration of some prolonged
324           process. The attribute returns the time elapsed since the attribute construction.
325           The attribute value type is <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><span class="special">::</span><span class="identifier">time_duration_type</span></code>
326           (see <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>).
327         </p>
328 <pre class="programlisting"><span class="comment">// The class represents a single peer-to-peer connection</span>
329 <span class="keyword">class</span> <span class="identifier">network_connection</span>
330 <span class="special">{</span>
331     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">m_logger</span><span class="special">;</span>
332
333 <span class="keyword">public</span><span class="special">:</span>
334     <span class="identifier">network_connection</span><span class="special">()</span>
335     <span class="special">{</span>
336         <span class="identifier">m_logger</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"Duration"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">());</span>
337         <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">m_logger</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"Connection established"</span><span class="special">;</span>
338     <span class="special">}</span>
339     <span class="special">~</span><span class="identifier">network_connection</span><span class="special">()</span>
340     <span class="special">{</span>
341         <span class="comment">// This log record will show the whole life time duration of the connection</span>
342         <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">m_logger</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"Connection closed"</span><span class="special">;</span>
343     <span class="special">}</span>
344 <span class="special">};</span>
345 </pre>
346 <p>
347           The attribute provides high resolution of the time estimation and can even
348           be used as a simple in-place performance profiling tool.
349         </p>
350 <div class="tip"><table border="0" summary="Tip">
351 <tr>
352 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
353 <th align="left">Tip</th>
354 </tr>
355 <tr><td align="left" valign="top"><p>
356             The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code>
357             attribute can even be used to profile the code in different modules without
358             recompiling them. The trick is to wrap an expensive call to a foreign
359             module with the thread-specific <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code>
360             <a class="link" href="attributes.html#log.detailed.attributes.related_components.scoped_attributes" title="Scoped attributes">scoped
361             attribute</a>, which will markup all log records made from within
362             the module with time readings.
363           </p></td></tr>
364 </table></div>
365 </div>
366 <div class="section">
367 <div class="titlepage"><div><div><h4 class="title">
368 <a name="log.detailed.attributes.named_scope"></a><a class="link" href="attributes.html#log.detailed.attributes.named_scope" title="Named scopes">Named scopes</a>
369 </h4></div></div></div>
370 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.named_scope_hpp" title="Header &lt;boost/log/attributes/named_scope.hpp&gt;">boost/log/attributes/named_scope.hpp</a></code><span class="special">&gt;</span>
371
372 <span class="comment">// Supporting headers</span>
373 <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.exception_hpp" title="Header &lt;boost/log/support/exception.hpp&gt;">boost/log/support/exception.hpp</a></code><span class="special">&gt;</span>
374 </pre>
375 <p>
376           The logging library supports maintaining scope stack tracking during the
377           application's execution. This stack may either be written to log or be
378           used for other needs (for example, to save the exact call sequence that
379           led to an exception when throwing one). Each stack element contains the
380           following information (see the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/named_scope_entry.html" title="Struct named_scope_entry">named_scope_entry</a></code>
381           structure template definition):
382         </p>
383 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
384 <li class="listitem">
385               Scope name. It can be defined by the user or generated by the compiler,
386               but in any case it <span class="underline">must be a constant string
387               literal</span> (see <a class="link" href="../rationale.html#log.rationale.why_str_lit" title="Why string literals as scope names?">Rationale</a>).
388             </li>
389 <li class="listitem">
390               Source file name, where the scope begins. It is usually a result of
391               the standard <code class="computeroutput"><span class="identifier">__FILE__</span></code>
392               macro expansion. Like the scope name, the file name <span class="underline">must
393               be a constant string literal</span>.
394             </li>
395 <li class="listitem">
396               Line number in the source file. Usually it is a result of the standard
397               <code class="computeroutput"><span class="identifier">__LINE__</span></code> macro expansion.
398             </li>
399 </ul></div>
400 <p>
401           The scope stack is implemented as a thread-specific global storage internally.
402           There is the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/named_scope.html" title="Class named_scope">named_scope</a></code>
403           attribute that allows hooking this stack into the logging pipeline. This
404           attribute generates value of the nested type <code class="computeroutput"><span class="identifier">named_scope</span><span class="special">::</span><span class="identifier">scope_stack</span></code>
405           which is the instance of the scope stack. The attribute can be registered
406           in the following way:
407         </p>
408 <pre class="programlisting"><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">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span><span class="string">"Scope"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">named_scope</span><span class="special">());</span>
409 </pre>
410 <p>
411           Note that it is perfectly valid to register the attribute globally because
412           the scope stack is thread-local anyway. This will also implicitly add scope
413           tracking to all threads of the application, which is often exactly what
414           is needed.
415         </p>
416 <p>
417           Now we can mark execution scopes with the macros <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>
418           and <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
419           (the latter accepts the scope name as its argument). These macros automatically
420           add source position information to each scope entry. An example follows:
421         </p>
422 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">n</span><span class="special">)</span>
423 <span class="special">{</span>
424     <span class="comment">// Mark the scope of the function foo</span>
425     <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span>
426
427     <span class="keyword">switch</span> <span class="special">(</span><span class="identifier">n</span><span class="special">)</span>
428     <span class="special">{</span>
429     <span class="keyword">case</span> <span class="number">0</span><span class="special">:</span>
430         <span class="special">{</span>
431             <span class="comment">// Mark the current scope</span>
432             <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"case 0"</span><span class="special">);</span>
433             <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">"Some log record"</span><span class="special">;</span>
434             <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span>
435         <span class="special">}</span>
436         <span class="keyword">break</span><span class="special">;</span>
437
438     <span class="keyword">case</span> <span class="number">1</span><span class="special">:</span>
439         <span class="special">{</span>
440             <span class="comment">// Mark the current scope</span>
441             <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"case 1"</span><span class="special">);</span>
442             <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">"Some log record"</span><span class="special">;</span>
443             <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span>
444         <span class="special">}</span>
445         <span class="keyword">break</span><span class="special">;</span>
446
447     <span class="keyword">default</span><span class="special">:</span>
448         <span class="special">{</span>
449             <span class="comment">// Mark the current scope</span>
450             <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"default"</span><span class="special">);</span>
451             <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">"Some log record"</span><span class="special">;</span>
452             <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span>
453         <span class="special">}</span>
454         <span class="keyword">break</span><span class="special">;</span>
455     <span class="special">}</span>
456 <span class="special">}</span>
457 </pre>
458 <p>
459           After executing <code class="computeroutput"><span class="identifier">foo</span></code> we
460           will be able to see in the log that the <code class="computeroutput"><span class="identifier">bar</span></code>
461           function was called from <code class="computeroutput"><span class="identifier">foo</span></code>
462           and, more precisely, from the case statement that corresponds to the value
463           of <code class="computeroutput"><span class="identifier">n</span></code>. This may be very
464           useful when tracking down subtle bugs that show up only when <code class="computeroutput"><span class="identifier">bar</span></code> is called from a specific location
465           (e.g. if <code class="computeroutput"><span class="identifier">bar</span></code> is being passed
466           invalid arguments in that particular location).
467         </p>
468 <div class="note"><table border="0" summary="Note">
469 <tr>
470 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
471 <th align="left">Note</th>
472 </tr>
473 <tr><td align="left" valign="top"><p>
474             The <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>
475             macro uses compiler-specific extensions to generate the scope name from
476             the enclosing function. C++11 defines a standard macro <code class="computeroutput"><span class="identifier">__func__</span></code> for this purpose, but it is
477             not universally supported. Additionally, format of the string is not
478             standardized and may vary from one compiler to another. For this reason
479             it is generally advised to use <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
480             instead of <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>
481             to ensure consistent and portable behavior.
482           </p></td></tr>
483 </table></div>
484 <p>
485           Another good use case is attaching the scope stack information to an exception.
486           With the help of <a href="http://www.boost.org/doc/libs/release/libs/exception/doc/boost-exception.html" target="_top">Boost.Exception</a>,
487           this is possible:
488         </p>
489 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span>
490 <span class="special">{</span>
491     <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span>
492
493     <span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">&lt;</span> <span class="number">0</span><span class="special">)</span>
494     <span class="special">{</span>
495         <span class="comment">// Attach a copy of the current scope stack to the exception</span>
496         <span class="keyword">throw</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_error_info</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">range_error</span><span class="special">(</span><span class="string">"x must not be negative"</span><span class="special">))</span>
497             <span class="special">&lt;&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">current_scope</span><span class="special">();</span>
498     <span class="special">}</span>
499 <span class="special">}</span>
500
501 <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
502 <span class="special">{</span>
503     <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span>
504
505     <span class="keyword">try</span>
506     <span class="special">{</span>
507         <span class="identifier">bar</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
508     <span class="special">}</span>
509     <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">range_error</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
510     <span class="special">{</span>
511         <span class="comment">// Acquire the scope stack from the exception object</span>
512         <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">"bar call failed: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">", scopes stack:\n"</span>
513             <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">get_error_info</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">current_scope_info</span> <span class="special">&gt;(</span><span class="identifier">e</span><span class="special">);</span>
514     <span class="special">}</span>
515 <span class="special">}</span>
516 </pre>
517 <div class="note"><table border="0" summary="Note">
518 <tr>
519 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
520 <th align="left">Note</th>
521 </tr>
522 <tr><td align="left" valign="top"><p>
523             In order this code to compile, the <a href="http://www.boost.org/doc/libs/release/libs/exception/doc/boost-exception.html" target="_top">Boost.Exception</a>
524             support header has to be included.
525           </p></td></tr>
526 </table></div>
527 <div class="note"><table border="0" summary="Note">
528 <tr>
529 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
530 <th align="left">Note</th>
531 </tr>
532 <tr><td align="left" valign="top"><p>
533             We do not inject the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/named_scope.html" title="Class named_scope">named_scope</a></code>
534             attribute into the exception. Since scope stacks are maintained globally,
535             throwing an exception will cause stack unwinding and, as a result, will
536             truncate the global stack. Instead we create a copy of the scope stack
537             by calling <code class="computeroutput"><a class="link" href="../../boost/log/current_scope.html" title="Function current_scope">current_scope</a></code> at the
538             throw site. This copy will be kept intact even if the global stack instance
539             changes during the stack unwinding.
540           </p></td></tr>
541 </table></div>
542 </div>
543 <div class="section">
544 <div class="titlepage"><div><div><h4 class="title">
545 <a name="log.detailed.attributes.process_id"></a><a class="link" href="attributes.html#log.detailed.attributes.process_id" title="Current process identifier">Current process
546         identifier</a>
547 </h4></div></div></div>
548 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.current_process_id_hpp" title="Header &lt;boost/log/attributes/current_process_id.hpp&gt;">boost/log/attributes/current_process_id.hpp</a></code><span class="special">&gt;</span>
549 </pre>
550 <p>
551           It is often useful to know the process identifier that produces the log,
552           especially if the log can eventually combine the output of different processes.
553           The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/current_process_id.html" title="Class current_process_id">current_process_id</a></code>
554           attribute is a constant that formats into the current process identifier.
555           The value type of the attribute can be determined by the <code class="computeroutput"><span class="identifier">current_process_id</span><span class="special">::</span><span class="identifier">value_type</span></code> typedef.
556         </p>
557 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
558 <span class="special">{</span>
559     <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">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span>
560         <span class="string">"ProcessID"</span><span class="special">,</span>
561         <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_id</span><span class="special">());</span>
562 <span class="special">}</span>
563 </pre>
564 </div>
565 <div class="section">
566 <div class="titlepage"><div><div><h4 class="title">
567 <a name="log.detailed.attributes.process_name"></a><a class="link" href="attributes.html#log.detailed.attributes.process_name" title="Current process name">Current process
568         name</a>
569 </h4></div></div></div>
570 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.current_process_name_hpp" title="Header &lt;boost/log/attributes/current_process_name.hpp&gt;">boost/log/attributes/current_process_name.hpp</a></code><span class="special">&gt;</span>
571 </pre>
572 <p>
573           The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/current_process_name.html" title="Class current_process_name">current_process_name</a></code>
574           produces <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> values with the executable name
575           of the current process.
576         </p>
577 <div class="note"><table border="0" summary="Note">
578 <tr>
579 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
580 <th align="left">Note</th>
581 </tr>
582 <tr><td align="left" valign="top"><p>
583             This attribute is not universally portable, although Windows, Linux and
584             OS X are supported. The attribute may work on other POSIX systems as
585             well, but it was not tested. If the process name cannot be obtained the
586             attribute will generate a string with the process id.
587           </p></td></tr>
588 </table></div>
589 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
590 <span class="special">{</span>
591     <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">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span>
592         <span class="string">"Process"</span><span class="special">,</span>
593         <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_name</span><span class="special">());</span>
594 <span class="special">}</span>
595 </pre>
596 </div>
597 <div class="section">
598 <div class="titlepage"><div><div><h4 class="title">
599 <a name="log.detailed.attributes.thread_id"></a><a class="link" href="attributes.html#log.detailed.attributes.thread_id" title="Current thread identifier">Current thread identifier</a>
600 </h4></div></div></div>
601 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.current_thread_id_hpp" title="Header &lt;boost/log/attributes/current_thread_id.hpp&gt;">boost/log/attributes/current_thread_id.hpp</a></code><span class="special">&gt;</span>
602 </pre>
603 <p>
604           Multithreaded builds of the library also support the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/current_thread_id.html" title="Class current_thread_id">current_thread_id</a></code>
605           attribute with value type <code class="computeroutput"><span class="identifier">current_thread_id</span><span class="special">::</span><span class="identifier">value_type</span></code>.
606           The attribute will generate values specific to the calling thread. The
607           usage is similar to the process id.
608         </p>
609 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
610 <span class="special">{</span>
611     <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">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span>
612         <span class="string">"ThreadID"</span><span class="special">,</span>
613         <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_thread_id</span><span class="special">());</span>
614 <span class="special">}</span>
615 </pre>
616 <div class="tip"><table border="0" summary="Tip">
617 <tr>
618 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
619 <th align="left">Tip</th>
620 </tr>
621 <tr><td align="left" valign="top"><p>
622             You may have noticed that the attribute is registered globally. This
623             will not result in all threads having the same ThreadID in log records
624             as the attribute will always return a thread-specific value. The additional
625             benefit is that you don't have to do a thing in the thread initialization
626             routines to have the thread-specific attribute value in log records.
627           </p></td></tr>
628 </table></div>
629 </div>
630 <div class="section">
631 <div class="titlepage"><div><div><h4 class="title">
632 <a name="log.detailed.attributes.function"></a><a class="link" href="attributes.html#log.detailed.attributes.function" title="Function objects as attributes">Function objects
633         as attributes</a>
634 </h4></div></div></div>
635 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.function_hpp" title="Header &lt;boost/log/attributes/function.hpp&gt;">boost/log/attributes/function.hpp</a></code><span class="special">&gt;</span>
636 </pre>
637 <p>
638           This attribute is a simple wrapper around a user-defined function object.
639           Each attempt to acquire the attribute value results in the function object
640           call. The result of the call is returned as the attribute value (this implies
641           that the function must not return <code class="computeroutput"><span class="keyword">void</span></code>).
642           The function object attribute can be constructed with the <code class="computeroutput"><span class="identifier">make_function</span></code> helper function, like this:
643         </p>
644 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
645 <span class="special">{</span>
646     <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">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span><span class="string">"MyRandomAttr"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">make_function</span><span class="special">(&amp;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">rand</span><span class="special">));</span>
647 <span class="special">}</span>
648 </pre>
649 <p>
650           Auto-generated function objects, like the ones defined in <a href="http://www.boost.org/doc/libs/release/libs/bind/bind.html" target="_top">Boost.Bind</a>
651           or STL, are also supported.
652         </p>
653 <div class="note"><table border="0" summary="Note">
654 <tr>
655 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
656 <th align="left">Note</th>
657 </tr>
658 <tr><td align="left" valign="top"><p>
659             Some deficient compilers may not support <code class="computeroutput"><span class="identifier">result_of</span></code>
660             construct properly. This metafunction is used in the <code class="computeroutput"><span class="identifier">make_function</span></code>
661             function to automatically detect the return type of the function object.
662             If <code class="computeroutput"><span class="identifier">result_of</span></code> breaks or
663             detects incorrect type, one can try to explicitly specify the return
664             type of the function object as a template argument to the <code class="computeroutput"><span class="identifier">make_function</span></code> function.
665           </p></td></tr>
666 </table></div>
667 </div>
668 <div class="section">
669 <div class="titlepage"><div><div><h4 class="title">
670 <a name="log.detailed.attributes.related_components"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components" title="Other attribute-related components">Other attribute-related
671         components</a>
672 </h4></div></div></div>
673 <div class="toc"><dl class="toc">
674 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_name">Attribute
675           names</a></span></dt>
676 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_set">Attribute
677           set</a></span></dt>
678 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_value_set">Attribute
679           value set</a></span></dt>
680 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.value_processing">Attribute
681           value extraction and visitation</a></span></dt>
682 <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.scoped_attributes">Scoped
683           attributes</a></span></dt>
684 </dl></div>
685 <div class="section">
686 <div class="titlepage"><div><div><h5 class="title">
687 <a name="log.detailed.attributes.related_components.attribute_name"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">Attribute
688           names</a>
689 </h5></div></div></div>
690 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_name_hpp" title="Header &lt;boost/log/attributes/attribute_name.hpp&gt;">boost/log/attributes/attribute_name.hpp</a></code><span class="special">&gt;</span>
691 </pre>
692 <p>
693             Attribute names are represented with <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code>
694             objects which are used as keys in associative containers of attributes
695             used by the library. The <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code>
696             object can be created from a string, so most of the time its use is transparent.
697           </p>
698 <p>
699             The name is not stored as a string within the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code>
700             object. Instead, a process-wide unique identifier is generated and associated
701             with the particular name. This association is preserved until the process
702             termination, so every time the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code>
703             object is created for the same name it obtains the same identifier. The
704             association is not stable across the different runs of the application
705             though.
706           </p>
707 <div class="warning"><table border="0" summary="Warning">
708 <tr>
709 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
710 <th align="left">Warning</th>
711 </tr>
712 <tr><td align="left" valign="top"><p>
713               Since the association between string names and identifiers involves
714               some state allocation, it is not advised to use externally provided
715               or known to be changing strings for attribute names. Even if the name
716               is not used in any log records, the association is preserved anyway.
717               Continuously constructing <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code>
718               objects with unique string names may manifest itself as a memory leak.
719             </p></td></tr>
720 </table></div>
721 <p>
722             Working with identifiers is much more efficient than with strings. For
723             example, copying does not involve dynamic memory allocation and comparison
724             operators are very lightweight. On the other hand, it is easy to get
725             a human-readable attribute name for presentation, if needed.
726           </p>
727 <p>
728             The <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code>
729             class supports an empty (uninitialized) state when default constructed.
730             In this state the name object is not equal to any other initialized name
731             object. Uninitialized attribute names should not be passed to the library
732             but can be useful in some contexts (e.g. when a delayed initialization
733             is desired).
734           </p>
735 </div>
736 <div class="section">
737 <div class="titlepage"><div><div><h5 class="title">
738 <a name="log.detailed.attributes.related_components.attribute_set"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_set" title="Attribute set">Attribute
739           set</a>
740 </h5></div></div></div>
741 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_set_hpp" title="Header &lt;boost/log/attributes/attribute_set.hpp&gt;">boost/log/attributes/attribute_set.hpp</a></code><span class="special">&gt;</span>
742 </pre>
743 <p>
744             Attribute set is an unordered associative container that maps <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">attribute
745             names</a> to <a class="link" href="attributes.html" title="Attributes">attributes</a>.
746             It is used in <a class="link" href="sources.html" title="Logging sources">loggers</a> and
747             the <a class="link" href="../detailed.html#log.detailed.core.core" title="Logging core">logging core</a> to store
748             source-specific, thread-specific and global attributes. The interface
749             is very similar to STL associative containers and is described in the
750             <code class="computeroutput"><a class="link" href="../../boost/log/attribute_set.html" title="Class attribute_set">attribute_set</a></code>
751             class reference.
752           </p>
753 </div>
754 <div class="section">
755 <div class="titlepage"><div><div><h5 class="title">
756 <a name="log.detailed.attributes.related_components.attribute_value_set"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">Attribute
757           value set</a>
758 </h5></div></div></div>
759 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_value_set_hpp" title="Header &lt;boost/log/attributes/attribute_value_set.hpp&gt;">boost/log/attributes/attribute_value_set.hpp</a></code><span class="special">&gt;</span>
760 </pre>
761 <p>
762             Attribute value set is an unordered associative container that maps
763             <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">attribute
764             names</a> to <a class="link" href="attributes.html" title="Attributes">attribute values</a>.
765             This container is used in log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">records</a>
766             to represent attribute values. Unlike conventional containers, <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value_set.html" title="Class attribute_value_set">attribute_value_set</a></code>
767             does not support removing or modifying elements after being inserted.
768             This warrants that the attribute values that participated filtering will
769             not disappear from the log record in the middle of the processing.
770           </p>
771 <p>
772             Additionally, the set can be constructed from three <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_set" title="Attribute set">attribute
773             sets</a>, which are interpreted as the sets of source-specific, thread-specific
774             and global attributes. The constructor adopts attribute values from the
775             three attribute sets into a single set of attribute values. After construction,
776             <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value_set.html" title="Class attribute_value_set">attribute_value_set</a></code>
777             is considered to be in an unfrozen state. This means that the container
778             may keep references to the elements of the attribute sets used as the
779             source for the value set construction. While in this state, neither the
780             attribute sets nor the value set must not be modified in any way as this
781             may make the value set corrupted. The value set can be used for reading
782             in this state, its lookup operations will perform as usual. The value
783             set can be frozen by calling the <code class="computeroutput"><span class="identifier">freeze</span></code>
784             method; the set will no longer be attached to the original attribute
785             sets and will be available for further insertions after this call. The
786             library will ensure that the value set is always frozen when a log record
787             is returned from the logging core; the set is <span class="underline">not</span>
788             frozen during filtering though.
789           </p>
790 <div class="tip"><table border="0" summary="Tip">
791 <tr>
792 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
793 <th align="left">Tip</th>
794 </tr>
795 <tr><td align="left" valign="top"><p>
796               In the unfrozen state the value set may not have all attribute values
797               acquired from the attributes. It will only acquire the values as requested
798               by filters. After freezing the container has all attribute values.
799               This transition allows to optimize the library so that attribute values
800               are only acquired when needed.
801             </p></td></tr>
802 </table></div>
803 <p>
804             For further details on the container interface please consult the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value_set.html" title="Class attribute_value_set">attribute_value_set</a></code>
805             reference.
806           </p>
807 </div>
808 <div class="section">
809 <div class="titlepage"><div><div><h5 class="title">
810 <a name="log.detailed.attributes.related_components.value_processing"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.value_processing" title="Attribute value extraction and visitation">Attribute
811           value extraction and visitation</a>
812 </h5></div></div></div>
813 <p>
814             Since attribute values do not expose the stored value in the interface,
815             an API is needed to acquire the stored value. The library provides two
816             APIs for this purpose: value visitation and extraction.
817           </p>
818 <div class="section">
819 <div class="titlepage"><div><div><h6 class="title">
820 <a name="log.detailed.attributes.related_components.value_processing.visitation"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.value_processing.visitation" title="Value visitation">Value
821             visitation</a>
822 </h6></div></div></div>
823 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.value_visitation_fwd_hpp" title="Header &lt;boost/log/attributes/value_visitation_fwd.hpp&gt;">boost/log/attributes/value_visitation_fwd.hpp</a></code><span class="special">&gt;</span>
824 <span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.value_visitation_hpp" title="Header &lt;boost/log/attributes/value_visitation.hpp&gt;">boost/log/attributes/value_visitation.hpp</a></code><span class="special">&gt;</span>
825 </pre>
826 <p>
827               Attribute value visitation implements the visitor design pattern, hence
828               the naming. The user has to provide a unary function object (a visitor)
829               which will be invoked on the stored attribute value. The caller also
830               has to provide the expected type or set of possible types of the stored
831               value. Obviously, the visitor must be capable of receiving an argument
832               of the expected type. Visitation will only succeed if the stored type
833               matches the expectation.
834             </p>
835 <p>
836               In order to apply the visitor, one should call the <code class="computeroutput"><a class="link" href="../../boost/log/visit_idm45711348203152.html" title="Function template visit">visit</a></code> function on
837               the attribute value. Let's see an example:
838             </p>
839 <p>
840 </p>
841 <pre class="programlisting"><span class="comment">// Our attribute value visitor</span>
842 <span class="keyword">struct</span> <span class="identifier">print_visitor</span>
843 <span class="special">{</span>
844     <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span>
845
846     <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span>
847     <span class="special">{</span>
848         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Visited value is int: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">val</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>
849     <span class="special">}</span>
850
851     <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</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">val</span><span class="special">)</span> <span class="keyword">const</span>
852     <span class="special">{</span>
853         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Visited value is string: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">val</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>
854     <span class="special">}</span>
855 <span class="special">};</span>
856
857 <span class="keyword">void</span> <span class="identifier">print_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">)</span>
858 <span class="special">{</span>
859     <span class="comment">// Define the set of expected types of the stored value</span>
860     <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">int</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">types</span><span class="special">;</span>
861
862     <span class="comment">// Apply our visitor</span>
863     <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visitation_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visit</span><span class="special">&lt;</span> <span class="identifier">types</span> <span class="special">&gt;(</span><span class="identifier">attr</span><span class="special">,</span> <span class="identifier">print_visitor</span><span class="special">());</span>
864
865     <span class="comment">// Check the result</span>
866     <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span>
867         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Visitation succeeded"</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>
868     <span class="keyword">else</span>
869         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Visitation failed"</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>
870 <span class="special">}</span>
871 </pre>
872 <p>
873             </p>
874 <p>
875               <a href="../../../../../../libs/log/example/doc/attr_value_visitation.cpp" target="_top">See
876               the complete code</a>.
877             </p>
878 <p>
879               In this example we print the stored attribute value in our <code class="computeroutput"><span class="identifier">print_visitor</span></code>. We expect the attribute
880               value to have either <code class="computeroutput"><span class="keyword">int</span></code>
881               or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> stored type; only in this
882               case the visitor will be invoked and the visitation result will be
883               positive. In case of failure the <code class="computeroutput"><a class="link" href="../../boost/log/visitation_result.html" title="Class visitation_result">visitation_result</a></code>
884               class provides additional information on the failure reason. The class
885               has the method named <code class="computeroutput"><span class="identifier">code</span></code>
886               which returns visitation error code. The following error codes are
887               possible:
888             </p>
889 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
890 <li class="listitem">
891                   <code class="computeroutput"><span class="identifier">ok</span></code> - visitation
892                   succeeded, the visitor has been invoked; visitation result is positive
893                   when this code is used
894                 </li>
895 <li class="listitem">
896                   <code class="computeroutput"><span class="identifier">value_not_found</span></code>
897                   - visitation failed because the requested value was not found;
898                   this code is used when visitation is applied to a log record or
899                   a set of attribute values rather than a single value
900                 </li>
901 <li class="listitem">
902                   <code class="computeroutput"><span class="identifier">value_has_invalid_type</span></code>
903                   - visitation failed because the value has type differing from any
904                   of the expected types
905                 </li>
906 </ul></div>
907 <p>
908               By default the visitor function result is ignored but it is possible
909               to obtain it. To do this one should use a special <code class="computeroutput"><a class="link" href="../../boost/log/save_result.html" title="Function template save_result">save_result</a></code> wrapper
910               for the visitor; the wrapper will save the visitor resulting value
911               into an external variable captured by reference. The visitor result
912               is initialized when the returned <code class="computeroutput"><a class="link" href="../../boost/log/visitation_result.html" title="Class visitation_result">visitation_result</a></code>
913               is positive. See the following example where we compute the hash value
914               on the stored value.
915             </p>
916 <p>
917 </p>
918 <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hash_visitor</span>
919 <span class="special">{</span>
920     <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">result_type</span><span class="special">;</span>
921
922     <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span>
923     <span class="special">{</span>
924         <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">val</span><span class="special">;</span>
925         <span class="identifier">h</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&lt;&lt;</span> <span class="number">15</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span>
926         <span class="identifier">h</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&gt;&gt;</span> <span class="number">6</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&lt;&lt;</span> <span class="number">7</span><span class="special">);</span>
927         <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
928     <span class="special">}</span>
929
930     <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</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">val</span><span class="special">)</span> <span class="keyword">const</span>
931     <span class="special">{</span>
932         <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
933         <span class="keyword">for</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="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">val</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">val</span><span class="special">.</span><span class="identifier">end</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>
934             <span class="identifier">h</span> <span class="special">+=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span>
935
936         <span class="identifier">h</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&lt;&lt;</span> <span class="number">15</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span>
937         <span class="identifier">h</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&gt;&gt;</span> <span class="number">6</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&lt;&lt;</span> <span class="number">7</span><span class="special">);</span>
938         <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
939     <span class="special">}</span>
940 <span class="special">};</span>
941
942 <span class="keyword">void</span> <span class="identifier">hash_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">)</span>
943 <span class="special">{</span>
944     <span class="comment">// Define the set of expected types of the stored value</span>
945     <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">int</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">types</span><span class="special">;</span>
946
947     <span class="comment">// Apply our visitor</span>
948     <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
949     <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visitation_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visit</span><span class="special">&lt;</span> <span class="identifier">types</span> <span class="special">&gt;(</span><span class="identifier">attr</span><span class="special">,</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">save_result</span><span class="special">(</span><span class="identifier">hash_visitor</span><span class="special">(),</span> <span class="identifier">h</span><span class="special">));</span>
950
951     <span class="comment">// Check the result</span>
952     <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span>
953         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Visitation succeeded, hash value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">h</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>
954     <span class="keyword">else</span>
955         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Visitation failed"</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>
956 <span class="special">}</span>
957 </pre>
958 <p>
959             </p>
960 <p>
961               <a href="../../../../../../libs/log/example/doc/attr_value_visitation.cpp" target="_top">See
962               the complete code</a>.
963             </p>
964 <div class="tip"><table border="0" summary="Tip">
965 <tr>
966 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
967 <th align="left">Tip</th>
968 </tr>
969 <tr><td align="left" valign="top"><p>
970                 When there is no default state for the visitor result it is convenient
971                 to use <a href="http://www.boost.org/doc/libs/release/libs/optional/index.html" target="_top">Boost.Optional</a>
972                 to wrap the returned value. The <code class="computeroutput"><span class="identifier">optional</span></code>
973                 will be initialized with the visitor result if visitation succeeded.
974                 In case if visitor is polymorphic (i.e. it has different result types
975                 depending on its argument type) <a href="http://www.boost.org/doc/libs/release/doc/html/variant.html" target="_top">Boost.Variant</a>
976                 can be used to receive the resulting value. It is also worthwhile
977                 to use an empty type, such as <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">blank</span></code>,
978                 to indicate the uninitialized state of the <code class="computeroutput"><span class="identifier">variant</span></code>.
979               </p></td></tr>
980 </table></div>
981 <p>
982               As it has been mentioned, visitation can also be applied to log records
983               and attribute value sets. The syntax is the same, except that the attribute
984               name also has to be specified. The <code class="computeroutput"><a class="link" href="../../boost/log/visit_idm45711348203152.html" title="Function template visit">visit</a></code> algorithm will
985               try to find the attribute value by name and then apply the visitor
986               to the found element.
987             </p>
988 <p>
989 </p>
990 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">hash_value</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> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_name</span> <span class="identifier">name</span><span class="special">)</span>
991 <span class="special">{</span>
992     <span class="comment">// Define the set of expected types of the stored value</span>
993     <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">int</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">types</span><span class="special">;</span>
994
995     <span class="comment">// Apply our visitor</span>
996     <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
997     <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visitation_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visit</span><span class="special">&lt;</span> <span class="identifier">types</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">logging</span><span class="special">::</span><span class="identifier">save_result</span><span class="special">(</span><span class="identifier">hash_visitor</span><span class="special">(),</span> <span class="identifier">h</span><span class="special">));</span>
998
999     <span class="comment">// Check the result</span>
1000     <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span>
1001         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Visitation succeeded, hash value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">h</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>
1002     <span class="keyword">else</span>
1003         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Visitation failed"</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>
1004 <span class="special">}</span>
1005 </pre>
1006 <p>
1007             </p>
1008 <p>
1009               Also, for convenience <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code>
1010               has the method named <code class="computeroutput"><span class="identifier">visit</span></code>
1011               with the same meaning as the free function applied to the attribute
1012               value.
1013             </p>
1014 </div>
1015 <div class="section">
1016 <div class="titlepage"><div><div><h6 class="title">
1017 <a name="log.detailed.attributes.related_components.value_processing.extraction"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.value_processing.extraction" title="Value extraction">Value
1018             extraction</a>
1019 </h6></div></div></div>
1020 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.value_extraction_fwd_hpp" title="Header &lt;boost/log/attributes/value_extraction_fwd.hpp&gt;">boost/log/attributes/value_extraction_fwd.hpp</a></code><span class="special">&gt;</span>
1021 <span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.value_extraction_hpp" title="Header &lt;boost/log/attributes/value_extraction.hpp&gt;">boost/log/attributes/value_extraction.hpp</a></code><span class="special">&gt;</span>
1022 </pre>
1023 <p>
1024               Attribute value extraction API allows to acquire a reference to the
1025               stored value. It does not require a visitor function object, but the
1026               user still has to provide the expected type or a set of types the stored
1027               value may have.
1028             </p>
1029 <p>
1030 </p>
1031 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">print_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">)</span>
1032 <span class="special">{</span>
1033     <span class="comment">// Extract a reference to the stored value</span>
1034     <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">&gt;</span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="identifier">attr</span><span class="special">);</span>
1035
1036     <span class="comment">// Check the result</span>
1037     <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span>
1038         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Extraction succeeded: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</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>
1039     <span class="keyword">else</span>
1040         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Extraction failed"</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>
1041 <span class="special">}</span>
1042 </pre>
1043 <p>
1044             </p>
1045 <p>
1046               <a href="../../../../../../libs/log/example/doc/attr_value_extraction.cpp" target="_top">See
1047               the complete code</a>.
1048             </p>
1049 <p>
1050               In this example we expect the attribute value to have the stored type
1051               <code class="computeroutput"><span class="keyword">int</span></code>. The <code class="computeroutput"><a class="link" href="../../boost/log/extract_idm45711348442880.html" title="Function template extract">extract</a></code>
1052               function attempts to extract a reference to the stored value and returns
1053               the filled <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> object if succeeded.
1054             </p>
1055 <p>
1056               Value extraction can also be used with a set of expected stored types.
1057               The following code snippet demonstrates this:
1058             </p>
1059 <p>
1060 </p>
1061 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">print_value_multiple_types</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">)</span>
1062 <span class="special">{</span>
1063     <span class="comment">// Define the set of expected types of the stored value</span>
1064     <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">int</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">types</span><span class="special">;</span>
1065
1066     <span class="comment">// Extract a reference to the stored value</span>
1067     <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">types</span> <span class="special">&gt;</span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="identifier">types</span> <span class="special">&gt;(</span><span class="identifier">attr</span><span class="special">);</span>
1068
1069     <span class="comment">// Check the result</span>
1070     <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span>
1071     <span class="special">{</span>
1072         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Extraction succeeded"</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>
1073         <span class="keyword">switch</span> <span class="special">(</span><span class="identifier">val</span><span class="special">.</span><span class="identifier">which</span><span class="special">())</span>
1074         <span class="special">{</span>
1075         <span class="keyword">case</span> <span class="number">0</span><span class="special">:</span>
1076             <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"int: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">get</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;()</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>
1077             <span class="keyword">break</span><span class="special">;</span>
1078
1079         <span class="keyword">case</span> <span class="number">1</span><span class="special">:</span>
1080             <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"string: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">get</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="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
1081             <span class="keyword">break</span><span class="special">;</span>
1082         <span class="special">}</span>
1083     <span class="special">}</span>
1084     <span class="keyword">else</span>
1085         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Extraction failed"</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>
1086 <span class="special">}</span>
1087 </pre>
1088 <p>
1089             </p>
1090 <p>
1091               Notice that we used <code class="computeroutput"><span class="identifier">which</span></code>
1092               method of the returned reference to dispatch between possible types.
1093               The method returns the index of the type in the <code class="computeroutput"><span class="identifier">types</span></code>
1094               sequence. Also note that the <code class="computeroutput"><span class="identifier">get</span></code>
1095               method now accepts an explicit template parameter to select the reference
1096               type to acquire; naturally, this type must correspond to the actual
1097               referred type, which is warranted by the switch/case statement in our
1098               case.
1099             </p>
1100 <p>
1101               Value visitation is also supported by 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> object. Here is
1102               how we compute a hash value from the extracted value:
1103             </p>
1104 <p>
1105 </p>
1106 <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hash_visitor</span>
1107 <span class="special">{</span>
1108     <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">result_type</span><span class="special">;</span>
1109
1110     <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span>
1111     <span class="special">{</span>
1112         <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">val</span><span class="special">;</span>
1113         <span class="identifier">h</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&lt;&lt;</span> <span class="number">15</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span>
1114         <span class="identifier">h</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&gt;&gt;</span> <span class="number">6</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&lt;&lt;</span> <span class="number">7</span><span class="special">);</span>
1115         <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
1116     <span class="special">}</span>
1117
1118     <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</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">val</span><span class="special">)</span> <span class="keyword">const</span>
1119     <span class="special">{</span>
1120         <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
1121         <span class="keyword">for</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="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">val</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">val</span><span class="special">.</span><span class="identifier">end</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>
1122             <span class="identifier">h</span> <span class="special">+=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span>
1123
1124         <span class="identifier">h</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&lt;&lt;</span> <span class="number">15</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span>
1125         <span class="identifier">h</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&gt;&gt;</span> <span class="number">6</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">&lt;&lt;</span> <span class="number">7</span><span class="special">);</span>
1126         <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
1127     <span class="special">}</span>
1128 <span class="special">};</span>
1129
1130 <span class="keyword">void</span> <span class="identifier">hash_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">)</span>
1131 <span class="special">{</span>
1132     <span class="comment">// Define the set of expected types of the stored value</span>
1133     <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">int</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">types</span><span class="special">;</span>
1134
1135     <span class="comment">// Extract the stored value</span>
1136     <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">types</span> <span class="special">&gt;</span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="identifier">types</span> <span class="special">&gt;(</span><span class="identifier">attr</span><span class="special">);</span>
1137
1138     <span class="comment">// Check the result</span>
1139     <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span>
1140         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Extraction succeeded, hash value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">apply_visitor</span><span class="special">(</span><span class="identifier">hash_visitor</span><span class="special">())</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>
1141     <span class="keyword">else</span>
1142         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Extraction failed"</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>
1143 <span class="special">}</span>
1144 </pre>
1145 <p>
1146             </p>
1147 <p>
1148               Lastly, like with value visitation, value extraction can also be applied
1149               to log records and attribute value sets.
1150             </p>
1151 <p>
1152 </p>
1153 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">hash_value</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> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_name</span> <span class="identifier">name</span><span class="special">)</span>
1154 <span class="special">{</span>
1155     <span class="comment">// Define the set of expected types of the stored value</span>
1156     <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">int</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">types</span><span class="special">;</span>
1157
1158     <span class="comment">// Extract the stored value</span>
1159     <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">types</span> <span class="special">&gt;</span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="identifier">types</span> <span class="special">&gt;(</span><span class="identifier">name</span><span class="special">,</span> <span class="identifier">rec</span><span class="special">);</span>
1160
1161     <span class="comment">// Check the result</span>
1162     <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span>
1163         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Extraction succeeded, hash value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">apply_visitor</span><span class="special">(</span><span class="identifier">hash_visitor</span><span class="special">())</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>
1164     <span class="keyword">else</span>
1165         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Extraction failed"</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>
1166 <span class="special">}</span>
1167 </pre>
1168 <p>
1169             </p>
1170 <p>
1171               In addition the library provides two special variants of the <code class="computeroutput"><a class="link" href="../../boost/log/extract_idm45711348442880.html" title="Function template extract">extract</a></code>
1172               function: <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm45711348414320.html" title="Function template extract_or_throw">extract_or_throw</a></code> and
1173               <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm45711348382816.html" title="Function template extract_or_default">extract_or_default</a></code>.
1174               As the naming implies, the functions provide different behavior in
1175               case if the attribute value cannot be extracted. The former one throws
1176               an exception if the value cannot be extracted and the latter one returns
1177               the default value.
1178             </p>
1179 <div class="warning"><table border="0" summary="Warning">
1180 <tr>
1181 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
1182 <th align="left">Warning</th>
1183 </tr>
1184 <tr><td align="left" valign="top"><p>
1185                 Care must be taken with the <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm45711348382816.html" title="Function template extract_or_default">extract_or_default</a></code>
1186                 function. The function accepts the default value is accepted by constant
1187                 reference, and this reference can eventually be returned from <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm45711348382816.html" title="Function template extract_or_default">extract_or_default</a></code>.
1188                 If a temporary object as used for the default value, user must ensure
1189                 that the result of <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm45711348382816.html" title="Function template extract_or_default">extract_or_default</a></code>
1190                 is saved by value and not by reference. Otherwise the saved reference
1191                 may become dangling when the temporary is destroyed.
1192               </p></td></tr>
1193 </table></div>
1194 <p>
1195               Similarly to <code class="computeroutput"><span class="identifier">visit</span></code>,
1196               the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code>
1197               class has methods named <code class="computeroutput"><span class="identifier">extract</span></code>,
1198               <code class="computeroutput"><span class="identifier">extract_or_throw</span></code> and
1199               <code class="computeroutput"><span class="identifier">extract_or_default</span></code>
1200               with the same meaning as the corresponding free functions applied to
1201               the attribute value.
1202             </p>
1203 </div>
1204 </div>
1205 <div class="section">
1206 <div class="titlepage"><div><div><h5 class="title">
1207 <a name="log.detailed.attributes.related_components.scoped_attributes"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.scoped_attributes" title="Scoped attributes">Scoped
1208           attributes</a>
1209 </h5></div></div></div>
1210 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.scoped_attribute_hpp" title="Header &lt;boost/log/attributes/scoped_attribute.hpp&gt;">boost/log/attributes/scoped_attribute.hpp</a></code><span class="special">&gt;</span>
1211 </pre>
1212 <p>
1213             Scoped attributes are a powerful mechanism of tagging log records that
1214             can be used for different purposes. As the naming implies, scoped attributes
1215             are registered in the beginning of a scope and unregistered on the end
1216             of the scope. The mechanism includes the following macros:
1217           </p>
1218 <pre class="programlisting"><code class="computeroutput"><a class="link" href="../../BOOST_LO_idm45711348486016.html" title="Macro BOOST_LOG_SCOPED_LOGGER_ATTR">BOOST_LOG_SCOPED_LOGGER_ATTR</a></code><span class="special">(</span><span class="identifier">logger</span><span class="special">,</span> <span class="identifier">attr_name</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span>
1219 <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm45711348481248.html" title="Macro BOOST_LOG_SCOPED_THREAD_ATTR">BOOST_LOG_SCOPED_THREAD_ATTR</a></code><span class="special">(</span><span class="identifier">attr_name</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span>
1220 </pre>
1221 <p>
1222             The first macro registers a source-specific attribute in the <code class="computeroutput"><span class="identifier">logger</span></code> logger object. The attribute
1223             name and the attribute itself are given in the <code class="computeroutput"><span class="identifier">attr_name</span></code>
1224             and <code class="computeroutput"><span class="identifier">attr</span></code> arguments. The
1225             second macro does exactly the same but the attribute is registered for
1226             the current thread in the logging core (which does not require a logger).
1227           </p>
1228 <div class="note"><table border="0" summary="Note">
1229 <tr>
1230 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
1231 <th align="left">Note</th>
1232 </tr>
1233 <tr><td align="left" valign="top"><p>
1234               If an attribute with the same name is already registered in the logger/logging
1235               core, the macros won't override the existing attribute and will eventually
1236               have no effect. See <a class="link" href="../rationale/why_weak_scoped_attributes.html" title="Why scoped attributes don't override existing attributes?">Rationale</a>
1237               for a more detailed explanation of the reasons for such behavior.
1238             </p></td></tr>
1239 </table></div>
1240 <p>
1241             Usage example follows:
1242           </p>
1243 <pre class="programlisting"><span class="identifier">BOOST_LOG_DECLARE_GLOBAL_LOGGER</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span>
1244
1245 <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
1246 <span class="special">{</span>
1247     <span class="comment">// This log record will also be marked with the "Tag" attribute,</span>
1248     <span class="comment">// whenever it is called from the A::bar function.</span>
1249     <span class="comment">// It will not be marked when called from other places.</span>
1250     <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">get_my_logger</span><span class="special">())</span> <span class="special">&lt;&lt;</span> <span class="string">"A log message from foo"</span><span class="special">;</span>
1251 <span class="special">}</span>
1252
1253 <span class="keyword">struct</span> <span class="identifier">A</span>
1254 <span class="special">{</span>
1255     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">m_Logger</span><span class="special">;</span>
1256
1257     <span class="keyword">void</span> <span class="identifier">bar</span><span class="special">()</span>
1258     <span class="special">{</span>
1259         <span class="comment">// Set a thread-wide markup tag.</span>
1260         <span class="comment">// Note the additional parentheses to form a Boost.PP sequence.</span>
1261         <span class="identifier">BOOST_LOG_SCOPED_THREAD_ATTR</span><span class="special">(</span><span class="string">"Tag"</span><span class="special">,</span>
1262             <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</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">"Called from A::bar"</span><span class="special">));</span>
1263
1264         <span class="comment">// This log record will be marked</span>
1265         <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">m_Logger</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"A log message from A::bar"</span><span class="special">;</span>
1266
1267         <span class="identifier">foo</span><span class="special">();</span>
1268     <span class="special">}</span>
1269 <span class="special">};</span>
1270
1271 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">*[])</span>
1272 <span class="special">{</span>
1273     <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span>
1274
1275     <span class="comment">// Let's measure our application run time</span>
1276     <span class="identifier">BOOST_LOG_SCOPED_LOGGER_ATTR</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"RunTime"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">());</span>
1277
1278     <span class="comment">// Mark application start.</span>
1279     <span class="comment">// The "RunTime" attribute should be nearly 0 at this point.</span>
1280     <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">"Application started"</span><span class="special">;</span>
1281
1282     <span class="comment">// Note that no other log records are affected by the "RunTime" attribute.</span>
1283     <span class="identifier">foo</span><span class="special">();</span>
1284
1285     <span class="identifier">A</span> <span class="identifier">a</span><span class="special">;</span>
1286     <span class="identifier">a</span><span class="special">.</span><span class="identifier">bar</span><span class="special">();</span>
1287
1288     <span class="comment">// Mark application ending.</span>
1289     <span class="comment">// The "RunTime" attribute will show the execution time elapsed.</span>
1290     <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">"Application ended"</span><span class="special">;</span>
1291
1292     <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
1293 <span class="special">}</span>
1294 </pre>
1295 <p>
1296             It is quite often convenient to mark a group of log records with a constant
1297             value in order to be able to filter the records later. The library provides
1298             two convenience macros just for this purpose:
1299           </p>
1300 <pre class="programlisting"><code class="computeroutput"><a class="link" href="../../BOOST_LO_idm45711348483632.html" title="Macro BOOST_LOG_SCOPED_LOGGER_TAG">BOOST_LOG_SCOPED_LOGGER_TAG</a></code><span class="special">(</span><span class="identifier">logger</span><span class="special">,</span> <span class="identifier">tag_name</span><span class="special">,</span> <span class="identifier">tag_value</span><span class="special">);</span>
1301 <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm45711348479264.html" title="Macro BOOST_LOG_SCOPED_THREAD_TAG">BOOST_LOG_SCOPED_THREAD_TAG</a></code><span class="special">(</span><span class="identifier">tag_name</span><span class="special">,</span> <span class="identifier">tag_value</span><span class="special">);</span>
1302 </pre>
1303 <p>
1304             The macros are effectively wrappers around <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm45711348486016.html" title="Macro BOOST_LOG_SCOPED_LOGGER_ATTR">BOOST_LOG_SCOPED_LOGGER_ATTR</a></code>
1305             and <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm45711348481248.html" title="Macro BOOST_LOG_SCOPED_THREAD_ATTR">BOOST_LOG_SCOPED_THREAD_ATTR</a></code>,
1306             respectively. For example, the "Tag" scoped attribute from
1307             the example above can be registered like this:
1308           </p>
1309 <pre class="programlisting"><span class="identifier">BOOST_LOG_SCOPED_THREAD_TAG</span><span class="special">(</span><span class="string">"Tag"</span><span class="special">,</span> <span class="string">"Called from A::bar"</span><span class="special">);</span>
1310 </pre>
1311 <div class="warning"><table border="0" summary="Warning">
1312 <tr>
1313 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
1314 <th align="left">Warning</th>
1315 </tr>
1316 <tr><td align="left" valign="top"><p>
1317               When using scoped attributes, make sure that the scoped attribute is
1318               not altered in the attribute set in which it was registered. For example,
1319               one should not clear or reinstall the attribute set of the logger if
1320               there are logger-specific scoped attributes registered in it. Otherwise
1321               the program will likely crash. This issue is especially critical in
1322               multithreaded application, when one thread may not know whether there
1323               are scoped attributes in the logger or there are not. Future releases
1324               may solve this limitation but currently the scoped attribute must remain
1325               intact until unregistered on leaving the scope.
1326             </p></td></tr>
1327 </table></div>
1328 <p>
1329             Although the described macros are intended to be the primary interface
1330             for the functionality, there is also a C++ interface available. It may
1331             be useful if the user decides to develop his own macros that cannot be
1332             based on the existing ones.
1333           </p>
1334 <p>
1335             Any scoped attribute is attached to a generic sentry object of type
1336             <code class="computeroutput"><span class="identifier">scoped_attribute</span></code>. As
1337             long as the sentry exists, the attribute is registered. There are several
1338             functions that create sentries for source or thread-specific attributes:
1339           </p>
1340 <pre class="programlisting"><span class="comment">// Source-specific scoped attribute registration</span>
1341 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">LoggerT</span> <span class="special">&gt;</span>
1342 <span class="special">[</span><span class="identifier">unspecified</span><span class="special">]</span> <span class="identifier">add_scoped_logger_attribute</span><span class="special">(</span>
1343     <span class="identifier">LoggerT</span><span class="special">&amp;</span> <span class="identifier">l</span><span class="special">,</span>
1344     <span class="identifier">attribute_name</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">name</span><span class="special">,</span>
1345     <span class="identifier">attribute</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">);</span>
1346
1347 <span class="comment">// Thread-specific scoped attribute registration</span>
1348 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">CharT</span> <span class="special">&gt;</span>
1349 <span class="special">[</span><span class="identifier">unspecified</span><span class="special">]</span> <span class="identifier">add_scoped_thread_attribute</span><span class="special">(</span>
1350     <span class="identifier">attribute_name</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">name</span><span class="special">,</span>
1351     <span class="identifier">attribute</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">);</span>
1352 </pre>
1353 <p>
1354             An object of the <code class="computeroutput"><span class="identifier">scoped_attribute</span></code>
1355             type is able to attach results of each of these functions on its construction.
1356             For example, <code class="computeroutput"><span class="identifier">BOOST_LOG_SCOPED_LOGGER_ATTR</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"RunTime"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">())</span></code> can roughly be expanded to this:
1357           </p>
1358 <pre class="programlisting"><span class="identifier">attrs</span><span class="special">::</span><span class="identifier">scoped_attribute</span> <span class="identifier">sentry</span> <span class="special">=</span>
1359     <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">add_scoped_logger_attribute</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"RunTime"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">());</span>
1360 </pre>
1361 </div>
1362 </div>
1363 </div>
1364 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
1365 <td align="left"></td>
1366 <td align="right"><div class="copyright-footer">Copyright &#169; 2007-2016 Andrey Semashev<p>
1367         Distributed under the Boost Software License, Version 1.0. (See accompanying
1368         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>).
1369       </p>
1370 </div></td>
1371 </tr></table>
1372 <hr>
1373 <div class="spirit-nav">
1374 <a accesskey="p" href="expressions.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="utilities.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
1375 </div>
1376 </body>
1377 </html>