summaryrefslogtreecommitdiff
path: root/libs/log/doc/html/log/detailed/attributes.html
blob: 719a1c9a74eda9586cdd4b93e80e1d7258675431 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Attributes</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Boost.Log v2">
<link rel="up" href="../detailed.html" title="Detailed features description">
<link rel="prev" href="expressions.html" title="Lambda expressions">
<link rel="next" href="utilities.html" title="Utilities">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<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>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="log.detailed.attributes"></a><a class="link" href="attributes.html" title="Attributes">Attributes</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.constant">Constants</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.mutable_constant">Mutable constants</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.counter">Counters</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.clock">Wall clock</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.timer">Stop watch (timer)</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.named_scope">Named scopes</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.process_id">Current process
        identifier</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.process_name">Current process
        name</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.thread_id">Current thread identifier</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.function">Function objects
        as attributes</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components">Other attribute-related
        components</a></span></dt>
</dl></div>
<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>
<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>
<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>
</pre>
<p>
        All attributes in the library are implemented using the <a href="http://c2.com/cgi/wiki?PimplIdiom" target="_top">pimpl
        idiom</a>, or more specifically - shared pimpl idiom. Every attribute
        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>
        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>.
        The interface class only holds a reference counted pointer to the actual
        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
        classes don't have any data members. When the interface class is default
        constructed, it creates the corresponding implementation object and initializes
        the <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> base class
        with a pointer to the implementation. Therefore the pimpl nature of attributes
        is transparent for users in a typical workflow.
      </p>
<p>
        The shared pimpl design comes significant in a few cases though. One such
        case is copying the attribute. The copy operation is shallow, so multiple
        interface objects may refer to a single implementation object. There is no
        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
        object that does not refer to an implementation. Attributes in such empty
        state should not be passed to the library but can be useful in some cases,
        e.g. when a delayed variable initialization is needed.
      </p>
<p>
        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>
        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>:
      </p>
<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>
<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>
</pre>
<p>
        In this example, the cast will succeed (i.e. the <code class="computeroutput"><span class="identifier">const_attr</span></code>
        will be non-empty) if the attribute <code class="computeroutput"><span class="identifier">attr</span></code>
        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
        object, no data is lost in the casting process.
      </p>
<p>
        The main purpose of attributes is to generate attribute values. Values are
        semantically distinct from the attributes. Such separation allows implementing
        attributes that can return different values at different time points (like
        clock-related attributes, for example) and, on the other hand, allows using
        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>
        interface has a method named <code class="computeroutput"><span class="identifier">get_value</span></code>
        that returns the actual attribute value. Attribute values are also implemented
        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>
        and implementation classes derive from <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value/impl.html" title="Struct impl">impl</a></code>.
      </p>
<p>
        The attribute value object is mostly intended to store the actual attribute
        value and implement type dispatching in order to be able to extract the stored
        value. One should not confuse the attribute value object type and the stored
        value type. The former is in most cases not needed by users and provides
        type erasure, but the latter is needed to be able to extract the value. For
        brevity we call the stored attribute value type simply the attribute value
        type in this documentation.
      </p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="log.detailed.attributes.constant"></a><a class="link" href="attributes.html#log.detailed.attributes.constant" title="Constants">Constants</a>
</h4></div></div></div>
<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>
</pre>
<p>
          The most simple and frequently used attribute type is a constant value
          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.
          The template is parametrized with the attribute value type. The constant
          value should be passed to the attribute constructor. Here is an example:
        </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span>

    <span class="comment">// Register a constant attribute that always yields value -5</span>
    <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>

    <span class="comment">// Register another constant attribute. Make it a string this time.</span>
    <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>

    <span class="comment">// There is also a convenience generator function. "MyInteger2" is constant&lt; int &gt; here.</span>
    <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>
<span class="special">}</span>
</pre>
<p>
          That's it, there's nothing much you can do with a constant attribute. Constants
          are very useful when one wants to highlight some log records or just pass
          some data to a sink backend (e.g. pass statistical parameters to the collector).
        </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<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>
</h4></div></div></div>
<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>
</pre>
<p>
          This kind of attribute is an extension for the <a class="link" href="attributes.html#log.detailed.attributes.constant" title="Constants">constant
          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>
          class template has two distinctions:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
              it allows modification of the stored value without re-registering the
              attribute
            </li>
<li class="listitem">
              it allows synchronization of the stores and reads of the stored value
            </li>
</ul></div>
<p>
          In order to change the stored value of the attribute, one must call the
          <code class="computeroutput"><span class="identifier">set</span></code> method:
        </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span>

    <span class="comment">// Register a mutable constant attribute that always yields value -5</span>
    <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>
    <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>
    <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>

    <span class="comment">// Change the attribute value</span>
    <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>
    <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>
<span class="special">}</span>
</pre>
<p>
          In multithreaded applications the <code class="computeroutput"><span class="identifier">set</span></code>
          method calls must be serialized with the <code class="computeroutput"><span class="identifier">get_value</span></code>
          calls (which, generally speaking, happen on every log record being made).
          By default <code class="computeroutput"><a class="link" href="../../boost/log/attributes/mutable_constant.html" title="Class template mutable_constant">mutable_constant</a></code>
          does not serialize calls in any way, assuming that the user will do so
          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>
          template provides three additional template arguments: synchronization
          primitive type, scoped exclusive lock type and scoped shareable lock type.
          If a synchronization primitive type is specified, the scoped exclusive
          lock type is a mandatory parameter. If the scoped shareable lock type is
          not specified, the attribute will fall back to the exclusive lock instead
          of shared locks. For example:
        </p>
<pre class="programlisting"><span class="comment">// This mutable constant will always lock exclusively</span>
<span class="comment">// either for reading or storing the value</span>
<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>
    <span class="keyword">int</span><span class="special">,</span>                                        <span class="comment">// attribute value type</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">,</span>                               <span class="comment">// synchronization primitive</span>
    <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>
<span class="special">&gt;</span> <span class="identifier">exclusive_mc</span><span class="special">;</span>
<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>

<span class="comment">// This mutable constant will use shared clocking for reading the value</span>
<span class="comment">// and exclusive locking for storing</span>
<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>
    <span class="keyword">int</span><span class="special">,</span>                                        <span class="comment">// attribute value type</span>
    <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>
    <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>
    <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>
<span class="special">&gt;</span> <span class="identifier">shared_mc</span><span class="special">;</span>
<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>

<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>
<span class="special">{</span>
    <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span> <span class="identifier">lg</span><span class="special">;</span>
    <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>
    <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>

    <span class="keyword">return</span> <span class="identifier">lg</span><span class="special">;</span>
<span class="special">}</span>

<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <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>

    <span class="comment">// This is safe, even if executed in multiple threads</span>
    <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>
    <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>

    <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>
    <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>
<span class="special">}</span>
</pre>
<p>
          Mutable constants are often used as auxiliary attributes inside loggers
          to store attributes that may change on some events. As opposed to regular
          constants, which would require re-registering in case of value modification,
          mutable constants allow modifying the value in-place.
        </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="log.detailed.attributes.counter"></a><a class="link" href="attributes.html#log.detailed.attributes.counter" title="Counters">Counters</a>
</h4></div></div></div>
<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>
</pre>
<p>
          Counters are one of the simplest attributes that generate a new value each
          time requested. Counters are often used to identify log records or to count
          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
          functionality. This template is parametrized with the counter value type,
          which should support arithmetic operations, such as <code class="computeroutput"><span class="keyword">operator</span>
          <span class="special">+</span></code> and <code class="computeroutput"><span class="keyword">operator</span>
          <span class="special">-</span></code>. The counter attribute allows
          specification of the initial value and step (which can be negative) on
          construction.
        </p>
<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>
<span class="special">{</span>
    <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span> <span class="identifier">lg</span><span class="special">;</span>

    <span class="comment">// This counter will count lines, starting from 0</span>
    <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>

    <span class="comment">// This counter will count backwards, starting from 100 with step -5</span>
    <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>

    <span class="keyword">return</span> <span class="identifier">lg</span><span class="special">;</span>
<span class="special">}</span>

<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <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>
    <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>
    <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>
    <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>
<span class="special">}</span>
</pre>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            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>
            attribute will always have ascending or descending counter values in
            the resulting log. In multithreaded applications counter values acquired
            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>
            for a more detailed explanation on why it can happen. For this reason
            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>
            attribute generates an identifier in an ascending or descending order
            rather than that it counts log records in either order.
          </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="log.detailed.attributes.clock"></a><a class="link" href="attributes.html#log.detailed.attributes.clock" title="Wall clock">Wall clock</a>
</h4></div></div></div>
<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>
</pre>
<p>
          One of the "must-have" features of any logging library is support
          for attaching a time stamp to every log record. The library provides two
          attributes for this purpose: <code class="computeroutput"><span class="identifier">utc_clock</span></code>
          and <code class="computeroutput"><span class="identifier">local_clock</span></code>. The former
          returns the current UTC time and the latter returns the current local time.
          In either case the returned time stamp is acquired with the maximum precision
          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>
          (see <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>).
          The usage is quite straightforward:
        </p>
<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>

<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span>
        <span class="string">"TimeStamp"</span><span class="special">,</span>
        <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">local_clock</span><span class="special">());</span>

    <span class="comment">// Now every log record ever made will have a time stamp attached</span>
    <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>
    <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>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<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>
</h4></div></div></div>
<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>
</pre>
<p>
          The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code> attribute
          is very useful when there is a need to estimate the duration of some prolonged
          process. The attribute returns the time elapsed since the attribute construction.
          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>
          (see <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>).
        </p>
<pre class="programlisting"><span class="comment">// The class represents a single peer-to-peer connection</span>
<span class="keyword">class</span> <span class="identifier">network_connection</span>
<span class="special">{</span>
    <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">m_logger</span><span class="special">;</span>

<span class="keyword">public</span><span class="special">:</span>
    <span class="identifier">network_connection</span><span class="special">()</span>
    <span class="special">{</span>
        <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>
        <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>
    <span class="special">}</span>
    <span class="special">~</span><span class="identifier">network_connection</span><span class="special">()</span>
    <span class="special">{</span>
        <span class="comment">// This log record will show the whole life time duration of the connection</span>
        <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>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
          The attribute provides high resolution of the time estimation and can even
          be used as a simple in-place performance profiling tool.
        </p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
            The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code>
            attribute can even be used to profile the code in different modules without
            recompiling them. The trick is to wrap an expensive call to a foreign
            module with the thread-specific <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code>
            <a class="link" href="attributes.html#log.detailed.attributes.related_components.scoped_attributes" title="Scoped attributes">scoped
            attribute</a>, which will markup all log records made from within
            the module with time readings.
          </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<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>
</h4></div></div></div>
<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>

<span class="comment">// Supporting headers</span>
<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>
</pre>
<p>
          The logging library supports maintaining scope stack tracking during the
          application's execution. This stack may either be written to log or be
          used for other needs (for example, to save the exact call sequence that
          led to an exception when throwing one). Each stack element contains the
          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>
          structure template definition):
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
              Scope name. It can be defined by the user or generated by the compiler,
              but in any case it <span class="underline">must be a constant string
              literal</span> (see <a class="link" href="../rationale.html#log.rationale.why_str_lit" title="Why string literals as scope names?">Rationale</a>).
            </li>
<li class="listitem">
              Source file name, where the scope begins. It is usually a result of
              the standard <code class="computeroutput"><span class="identifier">__FILE__</span></code>
              macro expansion. Like the scope name, the file name <span class="underline">must
              be a constant string literal</span>.
            </li>
<li class="listitem">
              Line number in the source file. Usually it is a result of the standard
              <code class="computeroutput"><span class="identifier">__LINE__</span></code> macro expansion.
            </li>
</ul></div>
<p>
          The scope stack is implemented as a thread-specific global storage internally.
          There is the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/named_scope.html" title="Class named_scope">named_scope</a></code>
          attribute that allows hooking this stack into the logging pipeline. This
          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>
          which is the instance of the scope stack. The attribute can be registered
          in the following way:
        </p>
<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>
</pre>
<p>
          Note that it is perfectly valid to register the attribute globally because
          the scope stack is thread-local anyway. This will also implicitly add scope
          tracking to all threads of the application, which is often exactly what
          is needed.
        </p>
<p>
          Now we can mark execution scopes with the macros <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>
          and <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
          (the latter accepts the scope name as its argument). These macros automatically
          add source position information to each scope entry. An example follows:
        </p>
<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>
<span class="special">{</span>
    <span class="comment">// Mark the scope of the function foo</span>
    <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span>

    <span class="keyword">switch</span> <span class="special">(</span><span class="identifier">n</span><span class="special">)</span>
    <span class="special">{</span>
    <span class="keyword">case</span> <span class="number">0</span><span class="special">:</span>
        <span class="special">{</span>
            <span class="comment">// Mark the current scope</span>
            <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"case 0"</span><span class="special">);</span>
            <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>
            <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span>
        <span class="special">}</span>
        <span class="keyword">break</span><span class="special">;</span>

    <span class="keyword">case</span> <span class="number">1</span><span class="special">:</span>
        <span class="special">{</span>
            <span class="comment">// Mark the current scope</span>
            <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"case 1"</span><span class="special">);</span>
            <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>
            <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span>
        <span class="special">}</span>
        <span class="keyword">break</span><span class="special">;</span>

    <span class="keyword">default</span><span class="special">:</span>
        <span class="special">{</span>
            <span class="comment">// Mark the current scope</span>
            <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"default"</span><span class="special">);</span>
            <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>
            <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span>
        <span class="special">}</span>
        <span class="keyword">break</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
          After executing <code class="computeroutput"><span class="identifier">foo</span></code> we
          will be able to see in the log that the <code class="computeroutput"><span class="identifier">bar</span></code>
          function was called from <code class="computeroutput"><span class="identifier">foo</span></code>
          and, more precisely, from the case statement that corresponds to the value
          of <code class="computeroutput"><span class="identifier">n</span></code>. This may be very
          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
          (e.g. if <code class="computeroutput"><span class="identifier">bar</span></code> is being passed
          invalid arguments in that particular location).
        </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            The <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>
            macro uses compiler-specific extensions to generate the scope name from
            the enclosing function. C++11 defines a standard macro <code class="computeroutput"><span class="identifier">__func__</span></code> for this purpose, but it is
            not universally supported. Additionally, format of the string is not
            standardized and may vary from one compiler to another. For this reason
            it is generally advised to use <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
            instead of <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>
            to ensure consistent and portable behavior.
          </p></td></tr>
</table></div>
<p>
          Another good use case is attaching the scope stack information to an exception.
          With the help of <a href="http://www.boost.org/doc/libs/release/libs/exception/doc/boost-exception.html" target="_top">Boost.Exception</a>,
          this is possible:
        </p>
<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>
<span class="special">{</span>
    <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span>

    <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>
    <span class="special">{</span>
        <span class="comment">// Attach a copy of the current scope stack to the exception</span>
        <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>
            <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>
    <span class="special">}</span>
<span class="special">}</span>

<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span>

    <span class="keyword">try</span>
    <span class="special">{</span>
        <span class="identifier">bar</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
    <span class="special">}</span>
    <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>
    <span class="special">{</span>
        <span class="comment">// Acquire the scope stack from the exception object</span>
        <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>
            <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>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            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>
            support header has to be included.
          </p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            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>
            attribute into the exception. Since scope stacks are maintained globally,
            throwing an exception will cause stack unwinding and, as a result, will
            truncate the global stack. Instead we create a copy of the scope stack
            by calling <code class="computeroutput"><a class="link" href="../../boost/log/current_scope.html" title="Function current_scope">current_scope</a></code> at the
            throw site. This copy will be kept intact even if the global stack instance
            changes during the stack unwinding.
          </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<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
        identifier</a>
</h4></div></div></div>
<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>
</pre>
<p>
          It is often useful to know the process identifier that produces the log,
          especially if the log can eventually combine the output of different processes.
          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>
          attribute is a constant that formats into the current process identifier.
          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.
        </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span>
        <span class="string">"ProcessID"</span><span class="special">,</span>
        <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_id</span><span class="special">());</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<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
        name</a>
</h4></div></div></div>
<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>
</pre>
<p>
          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>
          produces <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> values with the executable name
          of the current process.
        </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            This attribute is not universally portable, although Windows, Linux and
            OS X are supported. The attribute may work on other POSIX systems as
            well, but it was not tested. If the process name cannot be obtained the
            attribute will generate a string with the process id.
          </p></td></tr>
</table></div>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span>
        <span class="string">"Process"</span><span class="special">,</span>
        <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_name</span><span class="special">());</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<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>
</h4></div></div></div>
<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>
</pre>
<p>
          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>
          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>.
          The attribute will generate values specific to the calling thread. The
          usage is similar to the process id.
        </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span>
        <span class="string">"ThreadID"</span><span class="special">,</span>
        <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_thread_id</span><span class="special">());</span>
<span class="special">}</span>
</pre>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
            You may have noticed that the attribute is registered globally. This
            will not result in all threads having the same ThreadID in log records
            as the attribute will always return a thread-specific value. The additional
            benefit is that you don't have to do a thing in the thread initialization
            routines to have the thread-specific attribute value in log records.
          </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="log.detailed.attributes.function"></a><a class="link" href="attributes.html#log.detailed.attributes.function" title="Function objects as attributes">Function objects
        as attributes</a>
</h4></div></div></div>
<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>
</pre>
<p>
          This attribute is a simple wrapper around a user-defined function object.
          Each attempt to acquire the attribute value results in the function object
          call. The result of the call is returned as the attribute value (this implies
          that the function must not return <code class="computeroutput"><span class="keyword">void</span></code>).
          The function object attribute can be constructed with the <code class="computeroutput"><span class="identifier">make_function</span></code> helper function, like this:
        </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&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>
<span class="special">}</span>
</pre>
<p>
          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>
          or STL, are also supported.
        </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            Some deficient compilers may not support <code class="computeroutput"><span class="identifier">result_of</span></code>
            construct properly. This metafunction is used in the <code class="computeroutput"><span class="identifier">make_function</span></code>
            function to automatically detect the return type of the function object.
            If <code class="computeroutput"><span class="identifier">result_of</span></code> breaks or
            detects incorrect type, one can try to explicitly specify the return
            type of the function object as a template argument to the <code class="computeroutput"><span class="identifier">make_function</span></code> function.
          </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<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
        components</a>
</h4></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_name">Attribute
          names</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_set">Attribute
          set</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_value_set">Attribute
          value set</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.value_processing">Attribute
          value extraction and visitation</a></span></dt>
<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.scoped_attributes">Scoped
          attributes</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<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
          names</a>
</h5></div></div></div>
<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>
</pre>
<p>
            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>
            objects which are used as keys in associative containers of attributes
            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>
            object can be created from a string, so most of the time its use is transparent.
          </p>
<p>
            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>
            object. Instead, a process-wide unique identifier is generated and associated
            with the particular name. This association is preserved until the process
            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>
            object is created for the same name it obtains the same identifier. The
            association is not stable across the different runs of the application
            though.
          </p>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
              Since the association between string names and identifiers involves
              some state allocation, it is not advised to use externally provided
              or known to be changing strings for attribute names. Even if the name
              is not used in any log records, the association is preserved anyway.
              Continuously constructing <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code>
              objects with unique string names may manifest itself as a memory leak.
            </p></td></tr>
</table></div>
<p>
            Working with identifiers is much more efficient than with strings. For
            example, copying does not involve dynamic memory allocation and comparison
            operators are very lightweight. On the other hand, it is easy to get
            a human-readable attribute name for presentation, if needed.
          </p>
<p>
            The <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code>
            class supports an empty (uninitialized) state when default constructed.
            In this state the name object is not equal to any other initialized name
            object. Uninitialized attribute names should not be passed to the library
            but can be useful in some contexts (e.g. when a delayed initialization
            is desired).
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<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
          set</a>
</h5></div></div></div>
<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>
</pre>
<p>
            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
            names</a> to <a class="link" href="attributes.html" title="Attributes">attributes</a>.
            It is used in <a class="link" href="sources.html" title="Logging sources">loggers</a> and
            the <a class="link" href="../detailed.html#log.detailed.core.core" title="Logging core">logging core</a> to store
            source-specific, thread-specific and global attributes. The interface
            is very similar to STL associative containers and is described in the
            <code class="computeroutput"><a class="link" href="../../boost/log/attribute_set.html" title="Class attribute_set">attribute_set</a></code>
            class reference.
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<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
          value set</a>
</h5></div></div></div>
<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>
</pre>
<p>
            Attribute value 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
            names</a> to <a class="link" href="attributes.html" title="Attributes">attribute values</a>.
            This container is used in log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">records</a>
            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>
            does not support removing or modifying elements after being inserted.
            This warrants that the attribute values that participated filtering will
            not disappear from the log record in the middle of the processing.
          </p>
<p>
            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
            sets</a>, which are interpreted as the sets of source-specific, thread-specific
            and global attributes. The constructor adopts attribute values from the
            three attribute sets into a single set of attribute values. After construction,
            <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value_set.html" title="Class attribute_value_set">attribute_value_set</a></code>
            is considered to be in an unfrozen state. This means that the container
            may keep references to the elements of the attribute sets used as the
            source for the value set construction. While in this state, neither the
            attribute sets nor the value set must not be modified in any way as this
            may make the value set corrupted. The value set can be used for reading
            in this state, its lookup operations will perform as usual. The value
            set can be frozen by calling the <code class="computeroutput"><span class="identifier">freeze</span></code>
            method; the set will no longer be attached to the original attribute
            sets and will be available for further insertions after this call. The
            library will ensure that the value set is always frozen when a log record
            is returned from the logging core; the set is <span class="underline">not</span>
            frozen during filtering though.
          </p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
              In the unfrozen state the value set may not have all attribute values
              acquired from the attributes. It will only acquire the values as requested
              by filters. After freezing the container has all attribute values.
              This transition allows to optimize the library so that attribute values
              are only acquired when needed.
            </p></td></tr>
</table></div>
<p>
            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>
            reference.
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<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
          value extraction and visitation</a>
</h5></div></div></div>
<p>
            Since attribute values do not expose the stored value in the interface,
            an API is needed to acquire the stored value. The library provides two
            APIs for this purpose: value visitation and extraction.
          </p>
<div class="section">
<div class="titlepage"><div><div><h6 class="title">
<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
            visitation</a>
</h6></div></div></div>
<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>
<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>
</pre>
<p>
              Attribute value visitation implements the visitor design pattern, hence
              the naming. The user has to provide a unary function object (a visitor)
              which will be invoked on the stored attribute value. The caller also
              has to provide the expected type or set of possible types of the stored
              value. Obviously, the visitor must be capable of receiving an argument
              of the expected type. Visitation will only succeed if the stored type
              matches the expectation.
            </p>
<p>
              In order to apply the visitor, one should call the <code class="computeroutput"><a class="link" href="../../boost/log/visit_idp42540128.html" title="Function template visit">visit</a></code> function on
              the attribute value. Let's see an example:
            </p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Our attribute value visitor</span>
<span class="keyword">struct</span> <span class="identifier">print_visitor</span>
<span class="special">{</span>
    <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span>

    <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>
    <span class="special">{</span>
        <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>
    <span class="special">}</span>

    <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>
    <span class="special">{</span>
        <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>
    <span class="special">}</span>
<span class="special">};</span>

<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>
<span class="special">{</span>
    <span class="comment">// Define the set of expected types of the stored value</span>
    <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>

    <span class="comment">// Apply our visitor</span>
    <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>

    <span class="comment">// Check the result</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span>
        <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>
    <span class="keyword">else</span>
        <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>
<span class="special">}</span>
</pre>
<p>
            </p>
<p>
              <a href="../../../../../../libs/log/example/doc/attr_value_visitation.cpp" target="_top">See
              the complete code</a>.
            </p>
<p>
              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
              value to have either <code class="computeroutput"><span class="keyword">int</span></code>
              or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> stored type; only in this
              case the visitor will be invoked and the visitation result will be
              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>
              class provides additional information on the failure reason. The class
              has the method named <code class="computeroutput"><span class="identifier">code</span></code>
              which returns visitation error code. The following error codes are
              possible:
            </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
                  <code class="computeroutput"><span class="identifier">ok</span></code> - visitation
                  succeeded, the visitor has been invoked; visitation result is positive
                  when this code is used
                </li>
<li class="listitem">
                  <code class="computeroutput"><span class="identifier">value_not_found</span></code>
                  - visitation failed because the requested value was not found;
                  this code is used when visitation is applied to a log record or
                  a set of attribute values rather than a single value
                </li>
<li class="listitem">
                  <code class="computeroutput"><span class="identifier">value_has_invalid_type</span></code>
                  - visitation failed because the value has type differing from any
                  of the expected types
                </li>
</ul></div>
<p>
              By default the visitor function result is ignored but it is possible
              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
              for the visitor; the wrapper will save the visitor resulting value
              into an external variable captured by reference. The visitor result
              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>
              is positive. See the following example where we compute the hash value
              on the stored value.
            </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hash_visitor</span>
<span class="special">{</span>
    <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>

    <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>
    <span class="special">{</span>
        <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>
        <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>
        <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>
        <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
    <span class="special">}</span>

    <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>
    <span class="special">{</span>
        <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>
        <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>
            <span class="identifier">h</span> <span class="special">+=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span>

        <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>
        <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>
        <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>

<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>
<span class="special">{</span>
    <span class="comment">// Define the set of expected types of the stored value</span>
    <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>

    <span class="comment">// Apply our visitor</span>
    <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>
    <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>

    <span class="comment">// Check the result</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span>
        <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>
    <span class="keyword">else</span>
        <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>
<span class="special">}</span>
</pre>
<p>
            </p>
<p>
              <a href="../../../../../../libs/log/example/doc/attr_value_visitation.cpp" target="_top">See
              the complete code</a>.
            </p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
                When there is no default state for the visitor result it is convenient
                to use <a href="http://www.boost.org/doc/libs/release/libs/optional/index.html" target="_top">Boost.Optional</a>
                to wrap the returned value. The <code class="computeroutput"><span class="identifier">optional</span></code>
                will be initialized with the visitor result if visitation succeeded.
                In case if visitor is polymorphic (i.e. it has different result types
                depending on its argument type) <a href="http://www.boost.org/doc/libs/release/doc/html/variant.html" target="_top">Boost.Variant</a>
                can be used to receive the resulting value. It is also worthwhile
                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>,
                to indicate the uninitialized state of the <code class="computeroutput"><span class="identifier">variant</span></code>.
              </p></td></tr>
</table></div>
<p>
              As it has been mentioned, visitation can also be applied to log records
              and attribute value sets. The syntax is the same, except that the attribute
              name also has to be specified. The <code class="computeroutput"><a class="link" href="../../boost/log/visit_idp42540128.html" title="Function template visit">visit</a></code> algorithm will
              try to find the attribute value by name and then apply the visitor
              to the found element.
            </p>
<p>
</p>
<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>
<span class="special">{</span>
    <span class="comment">// Define the set of expected types of the stored value</span>
    <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>

    <span class="comment">// Apply our visitor</span>
    <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>
    <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>

    <span class="comment">// Check the result</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span>
        <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>
    <span class="keyword">else</span>
        <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>
<span class="special">}</span>
</pre>
<p>
            </p>
<p>
              Also, for convenience <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code>
              has the method named <code class="computeroutput"><span class="identifier">visit</span></code>
              with the same meaning as the free function applied to the attribute
              value.
            </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h6 class="title">
<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
            extraction</a>
</h6></div></div></div>
<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>
<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>
</pre>
<p>
              Attribute value extraction API allows to acquire a reference to the
              stored value. It does not require a visitor function object, but the
              user still has to provide the expected type or a set of types the stored
              value may have.
            </p>
<p>
</p>
<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>
<span class="special">{</span>
    <span class="comment">// Extract a reference to the stored value</span>
    <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>

    <span class="comment">// Check the result</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span>
        <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>
    <span class="keyword">else</span>
        <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>
<span class="special">}</span>
</pre>
<p>
            </p>
<p>
              <a href="../../../../../../libs/log/example/doc/attr_value_extraction.cpp" target="_top">See
              the complete code</a>.
            </p>
<p>
              In this example we expect the attribute value to have the stored type
              <code class="computeroutput"><span class="keyword">int</span></code>. The <code class="computeroutput"><a class="link" href="../../boost/log/extract_idp42351392.html" title="Function template extract">extract</a></code>
              function attempts to extract a reference to the stored value and returns
              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.
            </p>
<p>
              Value extraction can also be used with a set of expected stored types.
              The following code snippet demonstrates this:
            </p>
<p>
</p>
<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>
<span class="special">{</span>
    <span class="comment">// Define the set of expected types of the stored value</span>
    <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>

    <span class="comment">// Extract a reference to the stored value</span>
    <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>

    <span class="comment">// Check the result</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span>
    <span class="special">{</span>
        <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>
        <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>
        <span class="special">{</span>
        <span class="keyword">case</span> <span class="number">0</span><span class="special">:</span>
            <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>
            <span class="keyword">break</span><span class="special">;</span>

        <span class="keyword">case</span> <span class="number">1</span><span class="special">:</span>
            <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>
            <span class="keyword">break</span><span class="special">;</span>
        <span class="special">}</span>
    <span class="special">}</span>
    <span class="keyword">else</span>
        <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>
<span class="special">}</span>
</pre>
<p>
            </p>
<p>
              Notice that we used <code class="computeroutput"><span class="identifier">which</span></code>
              method of the returned reference to dispatch between possible types.
              The method returns the index of the type in the <code class="computeroutput"><span class="identifier">types</span></code>
              sequence. Also note that the <code class="computeroutput"><span class="identifier">get</span></code>
              method now accepts an explicit template parameter to select the reference
              type to acquire; naturally, this type must correspond to the actual
              referred type, which is warranted by the switch/case statement in our
              case.
            </p>
<p>
              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
              how we compute a hash value from the extracted value:
            </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hash_visitor</span>
<span class="special">{</span>
    <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>

    <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>
    <span class="special">{</span>
        <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>
        <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>
        <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>
        <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
    <span class="special">}</span>

    <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>
    <span class="special">{</span>
        <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>
        <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>
            <span class="identifier">h</span> <span class="special">+=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span>

        <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>
        <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>
        <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>

<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>
<span class="special">{</span>
    <span class="comment">// Define the set of expected types of the stored value</span>
    <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>

    <span class="comment">// Extract the stored value</span>
    <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>

    <span class="comment">// Check the result</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span>
        <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>
    <span class="keyword">else</span>
        <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>
<span class="special">}</span>
</pre>
<p>
            </p>
<p>
              Lastly, like with value visitation, value extraction can also be applied
              to log records and attribute value sets.
            </p>
<p>
</p>
<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>
<span class="special">{</span>
    <span class="comment">// Define the set of expected types of the stored value</span>
    <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>

    <span class="comment">// Extract the stored value</span>
    <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>

    <span class="comment">// Check the result</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span>
        <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>
    <span class="keyword">else</span>
        <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>
<span class="special">}</span>
</pre>
<p>
            </p>
<p>
              In addition the library provides two special variants of the <code class="computeroutput"><a class="link" href="../../boost/log/extract_idp42351392.html" title="Function template extract">extract</a></code>
              function: <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_thr_idp42379312.html" title="Function template extract_or_throw">extract_or_throw</a></code> and
              <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_def_idp42410176.html" title="Function template extract_or_default">extract_or_default</a></code>.
              As the naming implies, the functions provide different behavior in
              case if the attribute value cannot be extracted. The former one throws
              an exception if the value cannot be extracted and the latter one returns
              the default value.
            </p>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
                Care must be taken with the <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_def_idp42410176.html" title="Function template extract_or_default">extract_or_default</a></code>
                function. The function accepts the default value is accepted by constant
                reference, and this reference can eventually be returned from <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_def_idp42410176.html" title="Function template extract_or_default">extract_or_default</a></code>.
                If a temporary object as used for the default value, user must ensure
                that the result of <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_def_idp42410176.html" title="Function template extract_or_default">extract_or_default</a></code>
                is saved by value and not by reference. Otherwise the saved reference
                may become dangling when the temporary is destroyed.
              </p></td></tr>
</table></div>
<p>
              Similarly to <code class="computeroutput"><span class="identifier">visit</span></code>,
              the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code>
              class has methods named <code class="computeroutput"><span class="identifier">extract</span></code>,
              <code class="computeroutput"><span class="identifier">extract_or_throw</span></code> and
              <code class="computeroutput"><span class="identifier">extract_or_default</span></code>
              with the same meaning as the corresponding free functions applied to
              the attribute value.
            </p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<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
          attributes</a>
</h5></div></div></div>
<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>
</pre>
<p>
            Scoped attributes are a powerful mechanism of tagging log records that
            can be used for different purposes. As the naming implies, scoped attributes
            are registered in the beginning of a scope and unregistered on the end
            of the scope. The mechanism includes the following macros:
          </p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_LOGGER_ATTR.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>
<code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_THREAD_ATTR.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>
</pre>
<p>
            The first macro registers a source-specific attribute in the <code class="computeroutput"><span class="identifier">logger</span></code> logger object. The attribute
            name and the attribute itself are given in the <code class="computeroutput"><span class="identifier">attr_name</span></code>
            and <code class="computeroutput"><span class="identifier">attr</span></code> arguments. The
            second macro does exactly the same but the attribute is registered for
            the current thread in the logging core (which does not require a logger).
          </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
              If an attribute with the same name is already registered in the logger/logging
              core, the macros won't override the existing attribute and will eventually
              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>
              for a more detailed explanation of the reasons for such behavior.
            </p></td></tr>
</table></div>
<p>
            Usage example follows:
          </p>
<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>

<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="comment">// This log record will also be marked with the "Tag" attribute,</span>
    <span class="comment">// whenever it is called from the A::bar function.</span>
    <span class="comment">// It will not be marked when called from other places.</span>
    <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>
<span class="special">}</span>

<span class="keyword">struct</span> <span class="identifier">A</span>
<span class="special">{</span>
    <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">m_Logger</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">bar</span><span class="special">()</span>
    <span class="special">{</span>
        <span class="comment">// Set a thread-wide markup tag.</span>
        <span class="comment">// Note the additional parentheses to form a Boost.PP sequence.</span>
        <span class="identifier">BOOST_LOG_SCOPED_THREAD_ATTR</span><span class="special">(</span><span class="string">"Tag"</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">"Called from A::bar"</span><span class="special">));</span>

        <span class="comment">// This log record will be marked</span>
        <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>

        <span class="identifier">foo</span><span class="special">();</span>
    <span class="special">}</span>
<span class="special">};</span>

<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>
<span class="special">{</span>
    <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span>

    <span class="comment">// Let's measure our application run time</span>
    <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>

    <span class="comment">// Mark application start.</span>
    <span class="comment">// The "RunTime" attribute should be nearly 0 at this point.</span>
    <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>

    <span class="comment">// Note that no other log records are affected by the "RunTime" attribute.</span>
    <span class="identifier">foo</span><span class="special">();</span>

    <span class="identifier">A</span> <span class="identifier">a</span><span class="special">;</span>
    <span class="identifier">a</span><span class="special">.</span><span class="identifier">bar</span><span class="special">();</span>

    <span class="comment">// Mark application ending.</span>
    <span class="comment">// The "RunTime" attribute will show the execution time elapsed.</span>
    <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>

    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
            It is quite often convenient to mark a group of log records with a constant
            value in order to be able to filter the records later. The library provides
            two convenience macros just for this purpose:
          </p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_LOGGER_TAG.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>
<code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_THREAD_TAG.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>
</pre>
<p>
            The macros are effectively wrappers around <code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_LOGGER_ATTR.html" title="Macro BOOST_LOG_SCOPED_LOGGER_ATTR">BOOST_LOG_SCOPED_LOGGER_ATTR</a></code>
            and <code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_THREAD_ATTR.html" title="Macro BOOST_LOG_SCOPED_THREAD_ATTR">BOOST_LOG_SCOPED_THREAD_ATTR</a></code>,
            respectively. For example, the "Tag" scoped attribute from
            the example above can be registered like this:
          </p>
<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>
</pre>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
              When using scoped attributes, make sure that the scoped attribute is
              not altered in the attribute set in which it was registered. For example,
              one should not clear or reinstall the attribute set of the logger if
              there are logger-specific scoped attributes registered in it. Otherwise
              the program will likely crash. This issue is especially critical in
              multithreaded application, when one thread may not know whether there
              are scoped attributes in the logger or there are not. Future releases
              may solve this limitation but currently the scoped attribute must remain
              intact until unregistered on leaving the scope.
            </p></td></tr>
</table></div>
<p>
            Although the described macros are intended to be the primary interface
            for the functionality, there is also a C++ interface available. It may
            be useful if the user decides to develop his own macros that cannot be
            based on the existing ones.
          </p>
<p>
            Any scoped attribute is attached to a generic sentry object of type
            <code class="computeroutput"><span class="identifier">scoped_attribute</span></code>. As
            long as the sentry exists, the attribute is registered. There are several
            functions that create sentries for source or thread-specific attributes:
          </p>
<pre class="programlisting"><span class="comment">// Source-specific scoped attribute registration</span>
<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>
<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>
    <span class="identifier">LoggerT</span><span class="special">&amp;</span> <span class="identifier">l</span><span class="special">,</span>
    <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>
    <span class="identifier">attribute</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">);</span>

<span class="comment">// Thread-specific scoped attribute registration</span>
<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>
<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>
    <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>
    <span class="identifier">attribute</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">);</span>
</pre>
<p>
            An object of the <code class="computeroutput"><span class="identifier">scoped_attribute</span></code>
            type is able to attach results of each of these functions on its construction.
            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:
          </p>
<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>
    <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>
</pre>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2007-2015 Andrey
      Semashev<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        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>).
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<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>
</div>
</body>
</html>