]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/flyweight/doc/tutorial/configuration.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / flyweight / doc / tutorial / configuration.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
2
3 <html>
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
6 <title>Boost.Flyweight Documentation - Tutorial - Configuring Boost.Flyweight</title>
7 <link rel="stylesheet" href="../style.css" type="text/css">
8 <link rel="start" href="../index.html">
9 <link rel="prev" href="key_value.html">
10 <link rel="up" href="index.html">
11 <link rel="next" href="extension.html">
12 </head>
13
14 <body>
15 <h1><img src="../../../../boost.png" alt="Boost logo" align=
16 "middle" width="277" height="86">Boost.Flyweight Tutorial: Configuring Boost.Flyweight</h1>
17
18 <div class="prev_link"><a href="key_value.html"><img src="../prev.gif" alt="key-value flyweights" border="0"><br>
19 Key-value flyweights
20 </a></div>
21 <div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight tutorial" border="0"><br>
22 Boost.Flyweight tutorial
23 </a></div>
24 <div class="next_link"><a href="extension.html"><img src="../next.gif" alt="extending Boost.Flyweight" border="0"><br>
25 Extending Boost.Flyweight
26 </a></div><br clear="all" style="clear: all;">
27
28 <hr>
29
30 <h2>Contents</h2>
31
32 <ul>
33 <li><a href="#intro">Configurable aspects of Boost.Flyweight</a>
34 <ul>
35 <li><a href="#free_order_template">Free-order template parameter interface</a></li>
36 <li><a href="#header_inclusion">Header inclusion</a></li>
37 </ul>
38 </li>
39 <li><a href="#tagging">Tagging</a></li>
40 <li><a href="#factories">Factory specification</a>
41 <ul>
42 <li><a href="#factory_types">Types involved in the configuration of factories</a></li>
43 <li><a href="#hashed_factory"><code>hashed_factory</code></a></li>
44 <li><a href="#set_factory"><code>set_factory</code></a></li>
45 <li><a href="#assoc_container_factory"><code>assoc_container_factory</code></a></li>
46 </ul>
47 </li>
48 <li><a href="#holders">Holder specification</a>
49 <ul>
50 <li><a href="#static_holder"><code>static_holder</code></a></li>
51 <li><a href="#intermodule_holder"><code>intermodule_holder</code></a></li>
52 </ul>
53 </li>
54 <li><a href="#locking">Locking policies</a>
55 <ul>
56 <li><a href="#simple_locking"><code>simple_locking</code></a></li>
57 <li><a href="#no_locking"><code>no_locking</code></a></li>
58 </ul>
59 </li>
60 <li><a href="#tracking">Tracking policies</a>
61 <ul>
62 <li><a href="#refcounted"><code>refcounted</code></a></li>
63 <li><a href="#no_tracking"><code>no_tracking</code></a></li>
64 </ul>
65 </li>
66 </ul>
67
68 <h2><a name="intro">Configurable aspects of Boost.Flyweight</a></h2>
69
70 <p>
71 Most of the time, <code>flyweight</code> default configuration is just good
72 enough and the user need not care about further tuning of her <code>flyweight</code>
73 instantiations; however, when the necessity for more control over Boost.Flyweight
74 behavior arises, comprehensive mechanisms are provided to select, configure and
75 even extend the following implementation aspects:
76 <ul>
77 <li><a href="#tagging">Type tagging</a>.</li>
78 <li><a href="#factories">Factory</a> used to store the shared values
79 <code>flyweight</code> objects refer to.
80 </li>
81 <li><a href="#holders">Mechanism of instantiation</a> of the flyweight factory.</li>
82 <li>Internal <a href="#locking">synchronization mechanism</a> for access to
83 the internal factory in multithreaded environments.</li>
84 <li><a href="#tracking">Tracking policy</a> controlling how a value stored in the
85 factory is handled when all the flyweight objects associated to it are
86 destroyed.
87 </li>
88 </ul>
89 </p>
90
91 <h3><a name="free_order_template">Free-order template parameter interface</a></h3>
92
93 <p>
94 The <code>flyweight</code> class template features a "smart" specification
95 interface by which the configuration aspects can be provided as optional template arguments
96 in whatever order the user pleases. For instance, a tagged <code>flyweight</code>
97 of <code>std::string</code>s with a <a href="#set_factory">set-based factory</a> and
98 <a href="#no_tracking">no tracking</a> can be specified like this:
99 </p>
100
101 <blockquote><pre>
102 <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span> <span class=identifier>tag</span><span class=special>&lt;</span><span class=identifier>label_t</span><span class=special>&gt;,</span> <span class=identifier>set_factory</span><span class=special>&lt;&gt;,</span> <span class=identifier>no_tracking</span> <span class=special>&gt;</span>
103 </pre></blockquote>
104
105 <p>
106 or like this:
107 </p>
108
109 <blockquote><pre>
110 <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span> <span class=identifier>no_tracking</span><span class=special>,</span> <span class=identifier>tag</span><span class=special>&lt;</span><span class=identifier>label_t</span><span class=special>&gt;,</span> <span class=identifier>set_factory</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
111 </pre></blockquote>
112
113 <p>
114 or in any other order; only <code>std::string</code> is required to occupy
115 the first place in the specification.
116 </p>
117
118 <h3><a name="header_inclusion">Header inclusion</a></h3>
119
120 <p>
121 The example code shown at the <a href="basics.html#intro">introductory section</a>
122 uses the
123 <a href="../reference/index.html#flyweight_synopsis"><code>"boost/flyweight.hpp"</code></a>
124 convenience header, which simply includes the headers for the class template
125 <code>flyweight</code> and its default configuration components:
126 </p>
127
128 <blockquote><pre>
129 <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// class template flyweight</span>
130 <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>hashed_factory</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// hashed flyweight factory</span>
131 <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>static_holder</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// regular factory instantiation</span>
132 <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>simple_locking</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// simple locking policy</span>
133 <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>/</span><span class=identifier>refcounted</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span> <span class=comment>// refcounting tracking policy</span>
134 </pre></blockquote>
135
136 <p>
137 When using components other than these, their specific headers must be
138 explicitly included.
139 </p>
140
141 <h2><a name="tagging">Tagging</a></h2>
142
143 <p>
144 Consider the following two types:
145 </p>
146
147 <blockquote><pre>
148 <span class=keyword>typedef</span> <span class=identifier>flyweight</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=identifier>name_t</span><span class=special>;</span>
149 <span class=keyword>typedef</span> <span class=identifier>flyweight</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=identifier>ip_address_t</span><span class=special>;</span>
150 </pre></blockquote>
151
152 <p>
153 Although technically both types are identical, this is so by virtue of
154 coincidence, as there is no sensible relation between names and IP addresses.
155 Internally, the fact that <code>name_t</code> and <code>ip_address_t</code>
156 are the same flyweight type causes values of both classes to be stored together
157 in the same flyweight factory, although their respective ranges
158 are not expected to overlap. <i>Tagging</i> can be used to turn these
159 into really different types:
160 </p>
161
162 <blockquote><pre>
163 <span class=keyword>struct</span> <span class=identifier>name_tag</span><span class=special>{};</span>
164 <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier>tag</span><span class=special>&lt;</span><span class=identifier>name_tag</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>name_t</span><span class=special>;</span>
165
166 <span class=keyword>struct</span> <span class=identifier>ip_address_tag</span><span class=special>{};</span>
167 <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier>tag</span><span class=special>&lt;</span><span class=identifier>ip_address_tag</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>ip_address_t</span><span class=special>;</span>
168 </pre></blockquote>
169
170 <p>
171 Now, <code>name_t</code> and <code>ip_address_t</code> are different
172 flyweight classes having separate factories each. Tags are a purely syntactic
173 device: any type can be used for tagging inside the <code>tag</code>
174 construct, though good style recommends using tag classes with
175 descriptive names which are local to the context where the flyweight type
176 is being defined.
177 </p>
178
179 <h2><a name="factories">Factory specification</a></h2>
180
181 <p>
182 <code>flyweight</code> uses a type of internal component called
183 <i>factory</i> whose purpose is to store and retrieve the different values
184 flyweight objects refer to at a given time. By default, a factory based on
185 a hashed container is used, so that <code>flyweight&lt;T&gt;</code> is
186 actually equivalent to
187 </p>
188
189 <blockquote><pre>
190 <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>hashed_factory</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
191 </pre></blockquote>
192
193 <p>
194 where <code>hashed_factory</code> is a so-called <i>factory specifier</i>.
195 Boost.Flyweight provides several predefined factory specifiers, which not
196 only let the user select the specific type of factory used, but also
197 accept their own template arguments to customize each factory.
198 </p>
199
200 <h3><a name="factory_types">Types involved in the configuration of factories</a></h3>
201
202 <p>
203 A given <code>flyweight</code> instantiation has associated
204 <code>flyweight::key_type</code>
205 and <code>flyweight::value_type</code> types (which are equal in the case
206 of regular flyweights or different if <a href="key_value.html">key-value
207 flyweights</a>
208 are used). Also, there is an internal <code>Entry</code> type which
209 corresponds to the type of the objects actually stored in the factory:
210 <code>Entry</code> contains the shared <code>value_type</code> objects
211 of <code>flyweight</code> as well a some internal bookkeeping information;
212 also, <code>Entry</code> is implicitly convertible to
213 <code>const key_type&amp;</code>, so that factories can rely on
214 <code>key_type</code> to look up <code>Entrie</code>s. Since
215 <code>Entry</code> is internal to the implementation of <code>flyweight</code>,
216 it cannot be directly referred to by the user in the configuration of
217 factories. Instead, the proxy
218 <a href="../../../mpl/doc/refmanual/placeholders.html"><i>placeholder</i></a>
219 type <code>boost::mpl::_1</code> can be used.
220 </p>
221
222 <h3><a name="hashed_factory"><code>hashed_factory</code></a></h3>
223
224 <blockquote>
225 <b>Header:</b> <a href="../reference/factories.html#hashed_factory_synopsis"><code>"boost/flyweight/hashed_factory.hpp"</code></a><br>
226 <b>Syntax:</b> <code>hashed_factory&lt;[Hash[,Pred[,Allocator]]]&gt;</code>
227 </blockquote>
228
229 <p>
230 This specifier, which Boost.Flyweight takes by default, controls the usage of a
231 factory internally based in a hash container. Values are determined to be
232 equivalent by means of the
233 <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html"><code>Binary
234 Predicate</code></a> <code>Pred</code>, and indexed into the factory container
235 using <code>Hash</code>, which is assumed to be a <i>hash function</i>,
236 i.e. a
237 <a href="http://www.sgi.com/tech/stl/UnaryFunction.html"><code>Unary
238 Function</code></a> assigning to each value a hash identifier of
239 type <code>std::size_t</code>. The <code>Allocator</code> parameter is
240 used by the factory container for its memory allocation needs. The default
241 types for these parameters are such that the expression
242 </p>
243
244 <blockquote><pre>
245 <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>hashed_factory</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
246 </pre></blockquote>
247
248 <p>
249 is equivalent to
250 </p>
251
252 <blockquote><pre>
253 <span class=identifier>flyweight</span><span class=special>&lt;</span>
254 <span class=identifier>T</span><span class=special>,</span>
255 <span class=identifier>hashed_factory</span><span class=special>&lt;</span>
256 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&gt;,</span>
257 <span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&gt;,</span>
258 <span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>&gt;</span>
259 <span class=special>&gt;</span>
260 <span class=special>&gt;</span>
261 </pre></blockquote>
262
263 <p>
264 where <code>key_type</code> is the key type of the flyweight and
265 <code>boost::mpl::_1</code>, as explained above, stands for the
266 internal <code>Entry</code> type of the elements stored in the factory.
267 Suppose we would like to configure <code>hashed_factory</code> for
268 a <code>std::string</code> flyweight with
269 a special hash predicate <code>special_hash</code> and a custom allocator
270 <code>custom_allocator</code>; this would be specified as follows:
271 </p>
272
273 <blockquote><pre>
274 <span class=identifier>flyweight</span><span class=special>&lt;</span>
275 <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
276 <span class=identifier>hashed_factory</span><span class=special>&lt;</span>
277 <span class=identifier>special_hash</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>
278 <span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special>&lt;</span><span class=identifier>key_value</span><span class=special>&gt;,</span>
279 <span class=identifier>custom_allocator</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>&gt;</span>
280 <span class=special>&gt;</span>
281 <span class=special>&gt;</span>
282 </pre></blockquote>
283
284 <h3><a name="set_factory"><code>set_factory</code></a></h3>
285
286 <blockquote>
287 <b>Header:</b> <a href="../reference/factories.html#set_factory_synopsis"><code>"boost/flyweight/set_factory.hpp"</code></a><br>
288 <b>Syntax:</b> <code>set_factory&lt;[Compare[,Allocator]]&gt;</code>
289 </blockquote>
290
291 <p>
292 <code>set_factory</code> resorts to an <code>std::set</code>-like ordered
293 container for the implementation of the flyweight factory.
294 <code>Compare</code> must be a
295 <a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"><code>Strict
296 Weak Ordering</code></a> on the value type <code>flyweight</code> is
297 acting upon; as is customary with STL ordered containers, two values
298 are considered equivalent if none is less than the other according to <code>Pred</code>.
299 <code>Allocator</code> is an allocator type passed along to the factory
300 internal container for its memory-related tasks. When default parameters are
301 used, the expression
302 </p>
303
304 <blockquote><pre>
305 <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>set_factory</span><span class=special>&lt;&gt;</span> <span class=special>&gt;</span>
306 </pre></blockquote>
307
308 <p>
309 is equivalent to
310 </p>
311
312 <blockquote><pre>
313 <span class=identifier>flyweight</span><span class=special>&lt;</span>
314 <span class=identifier>T</span><span class=special>,</span>
315 <span class=identifier>set_factory</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>key_type</span><span class=special>&gt;,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>&gt;</span> <span class=special>&gt;</span>
316 <span class=special>&gt;</span>
317 </pre></blockquote>
318
319 <p>
320 Usual tradeoffs arising in the comparison of ordered and hashed containers
321 also apply when choosing between <code>set_factory</code> and
322 <code>hashed_factory</code>:
323 so, set-based lookup and insertion of values are generally slower than those based on hashing,
324 but the latter can be affected by pathological worst-case scenarios with very
325 poor performance.
326 </p>
327
328 <h3><a name="assoc_container_factory"><code>assoc_container_factory</code></a></h3>
329
330 <blockquote>
331 <b>Header:</b> <a href="../reference/factories.html#assoc_container_factory_synopsis"><code>"boost/flyweight/assoc_container_factory.hpp"</code></a><br>
332 <b>Syntax:</b> <code>assoc_container_factory&lt;ContainerSpecifier&gt;</code>
333 </blockquote>
334
335 <p>
336 This specifier can be seen as a generalization of
337 <code>hashed_factory</code> and <code>set_factory</code> where the user
338 supplies the exact type of container on which the factory is based.
339 The way in which the container is specified might seem at first a little
340 daunting to those unfamiliar with the
341 <a href="../../../mpl/doc/index.html">Boost MPL Library</a>:
342 <code>ContainerSpecifier</code> must be an
343 <a href="lambda_expressions.html"><code>MPL Lambda
344 Expression</code></a> such that, when invoked with the
345 types <code>Entry</code> and <code>key_type</code>
346 explained <a href="#factory_types">above</a>, it produces the type of
347 a container of <code>Entry</code> elements satisfying the following
348 requirements:
349 <ol>
350 <li>The container type must be a model of
351 <a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html"><code>Unique
352 Associative Container</code></a> where equivalence of <code>Entry</code>s
353 is determined by the <code>key_type</code> values the entries are convertible
354 to .
355 </li>
356 <li>The container must be <i>stable</i>, i.e. its iterators must remain valid
357 after insert and erase operations. Note that this condition is not met by
358 many existing implementations of hashed containers that invalidate iterators
359 upon a rehashing operation.
360 </li>
361 </ol>
362 </p>
363
364 <p>
365 Let us see what a container specifier looks like with an example.
366 Suppose we have our own ordered container like the following:
367 </p>
368
369 <blockquote><pre>
370 <span class=keyword>template</span><span class=special>&lt;</span>
371 <span class=keyword>typename</span> <span class=identifier>Elem</span><span class=special>,</span>
372 <span class=keyword>typename</span> <span class=identifier>Compare</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>Elem</span><span class=special>&gt;,</span>
373 <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>=</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>Elem</span><span class=special>&gt;</span>
374 <span class=special>&gt;</span>
375 <span class=keyword>class</span> <span class=identifier>ultrafast_set</span>
376 <span class=special>{</span>
377 <span class=special>...</span>
378 <span class=special>};</span>
379 </pre></blockquote>
380
381 <p>
382 Then <code>ultrafast_set</code> can be plugged into
383 <code>assoc_container_factory</code> like this:
384 </p>
385
386 <blockquote><pre>
387 <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span>
388 <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
389 <span class=identifier>assoc_container_factory</span><span class=special>&lt;</span>
390 <span class=comment>// MPL lambda expression follows</span>
391 <b><span class=identifier>ultrafast_set</span><span class=special>&lt;</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>less</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>&gt;</span></b>
392 <span class=special>&gt;</span>
393 <span class=special>&gt;</span> <span class=identifier>flyweight_string</span><span class=special>;</span>
394 </pre></blockquote>
395
396 <p>
397 As has been explained, <code>mpl::_1</code> is a so-called MPL
398 placeholder standing as a "slot" to be replaced with
399 <code>Entry</code> by the internal machinery of Boost.Flyweight.
400 Note that we have not
401 relied on the default argument of <code>ultrafast_set</code> for
402 <code>Compare</code> and instead we have provided a fixed
403 instantiation for <code>std::string</code>: this is so because
404 requirements state that the type with which <code>ContainerSpecifier</code>
405 will be filled in internally is convertible to <code>const key_type&amp;</code>
406 (here <code>const std::string&amp;</code>), and it is based on
407 <code>key_type</code> that lookup and equivalence of entries
408 should be determined. On the other hand,
409 the default argument for the <code>Allocator</code> parameter works
410 just fine, as is more apparent if we write it down explicitly:
411 </p>
412
413 <blockquote><pre>
414 <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span>
415 <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span>
416 <span class=identifier>assoc_container_factory</span><span class=special>&lt;</span>
417 <b><span class=identifier>ultrafast_set</span><span class=special>&lt;</span>
418 <span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>,</span>
419 <span class=identifier>std</span><span class=special>::</span><span class=identifier>less</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>
420 <span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>_1</span><span class=special>&gt;</span>
421 <span class=special>&gt;</span>
422 <span class=special>&gt;</span></b>
423 <span class=special>&gt;</span> <span class=identifier>flyweight_string</span><span class=special>;</span>
424 </pre></blockquote>
425
426 <h2><a name="holders">Holder specification</a></h2>
427
428 <p>
429 Each flyweight type, that is, each distinct instantiation of the class
430 template <code>flyweight</code>, is associated with exactly one factory
431 object. In most cases, how this factory object is created is of little
432 importance to the user of Boost.Flyweight, but there are special
433 circumstances where control of this aspect is necessary. An internal
434 component called <i>holder</i> is in charge of instantiating the
435 factory class and some other internal information; this component is
436 stipulated by means of a <i>holder specifier</i>, <code>static_holder</code>
437 being the default one.
438 </p>
439
440 <h3><a name="static_holder"><code>static_holder</code></a></h3>
441
442 <blockquote>
443 <b>Header:</b> <a href="../reference/holders.html#static_holder_synopsis"><code>"boost/flyweight/static_holder.hpp"</code></a><br>
444 <b>Syntax:</b> <code>static_holder</code>
445 </blockquote>
446
447 <p>
448 This the default holder specifier of Boost.Flyweight, and produces
449 holders where the unique factory lives as a local static variable of the
450 program.
451 </p>
452
453 <h3><a name="intermodule_holder"><code>intermodule_holder</code></a></h3>
454
455 <blockquote>
456 <b>Header:</b> <a href="../reference/holders.html#intermodule_holder_synopsis"><code>"boost/flyweight/intermodule_holder.hpp"</code></a><br>
457 <b>Syntax:</b> <code>intermodule_holder</code>
458 </blockquote>
459
460 <p>
461 In most C++ environments, static variables do not mix well with
462 dynamically loaded modules in the sense that instances of the same
463 static variable can be duplicated across different modules, even
464 though by definition the variable should be unique. In many
465 cases, this duplication goes unnoticed if the modules do not communicate
466 between each other using the affected types, but consider this
467 case where such communication does happen:
468 </p>
469
470 <blockquote><pre>
471 <span class=comment>// module 1</span>
472
473 <span class=keyword>typedef</span> <span class=identifier>flyweight</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=identifier>flyweight_string</span><span class=special>;</span>
474
475 <span class=comment>// produce_string is exported so that it can be dynamically
476 // linked</span>
477
478 <span class=identifier>flyweight_string</span> <span class=identifier>produce_string</span><span class=special>()</span>
479 <span class=special>{</span>
480 <span class=keyword>return</span> <span class=identifier>flyweight_string</span><span class=special>(</span><span class=string>&quot;boost&quot;</span><span class=special>);</span>
481 <span class=special>}</span>
482 </pre></blockquote>
483
484 <blockquote><pre>
485 <span class=comment>// main program</span>
486
487 <span class=keyword>typedef</span> <span class=identifier>flyweight</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=identifier>flyweight_string</span><span class=special>;</span>
488
489 <span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
490 <span class=special>{</span>
491 <span class=special>...</span> <span class=comment>// import module 1</span>
492
493 <span class=identifier>flyweight_string</span> <span class=identifier>str1</span><span class=special>=</span><span class=identifier>produce_string</span><span class=special>();</span>
494 <span class=identifier>flyweight_string</span> <span class=identifier>str2</span><span class=special>(</span><span class=string>&quot;boost&quot;</span><span class=special>);</span>
495 <span class=identifier>assert</span><span class=special>(</span><span class=identifier>str1</span><span class=special>==</span><span class=identifier>str2</span><span class=special>);</span>
496 <span class=special>}</span>
497 </pre></blockquote>
498
499 <p>
500 In many environments, this program results in an assertion
501 failure because the flyweight factory object used
502 by <code>flyweight_string</code> as seen within module 1 is
503 not the same factory object as seen within the main program: hence
504 the value representations internally pointed to by <code>str1</code>
505 and <code>str2</code> will differ and will be mistakenly
506 considered as not equal. Many other problems might arise
507 due to factory duplication, including undefined behavior.
508 </p>
509
510 <p>
511 <code>intermodule_holder</code> specifies a factory holder which
512 is capable of avoiding the duplication problem and ensuring that
513 all modules of a program are using the same factory instance.
514 To fix the example above, it suffices to redefine
515 <code>flyweight_string</code> in both modules as:
516 </p>
517
518 <blockquote><pre>
519 <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,</span><span class=identifier><b>intermodule_holder</b></span><span class=special>&gt;</span> <span class=identifier>flyweight_string</span><span class=special>;</span>
520 </pre></blockquote>
521
522 <p>
523 <code>intermodule_holder</code> is considerably more onerous than
524 <code>static_holder</code> in terms of compilation times and
525 introduces a non-negligible overhead at program start-up, so its use
526 should be reserved to the situations where it is really necessary.
527 </p>
528
529
530 <h2><a name="locking">Locking policies</a></h2>
531
532 <p>
533 The internal factory associated to each <code>flyweight</code>
534 type is a shared resource and as such access to it must be properly
535 synchronized in multithreaded environments. A <i>locking policy</i>
536 specifies the synchronization mechanisms to be used for this purpose.
537 </p>
538
539 <h3><a name="simple_locking"><code>simple_locking</code></a></h3>
540
541 <blockquote>
542 <b>Header:</b> <a href="../reference/locking.html#simple_locking_synopsis"><code>"boost/flyweight/simple_locking.hpp"</code></a><br>
543 <b>Syntax:</b> <code>simple_locking</code>
544 </blockquote>
545
546 <p>
547 This is the default locking policy. It specifies the simplest native
548 synchronization primitives provided by the operating system, whenever
549 available.
550 </p>
551
552 <h3><a name="no_locking"><code>no_locking</code></a></h3>
553
554 <blockquote>
555 <b>Header:</b> <a href="../reference/locking.html#no_locking_synopsis"><code>"boost/flyweight/no_locking.hpp"</code></a><br>
556 <b>Syntax:</b> <code>no_locking</code>
557 </blockquote>
558
559 <p>
560 No synchronization is enforced so that irrestricted internal access
561 to the implementation shared resources is allowed.
562 Selecting <code>no_locking</code> results in somewhat faster execution than
563 the default <code>simple_locking</code>, but it renders the type
564 thread-unsafe, which can have catastrophic consequences.
565 This policy should not be used except in single-threaded environments or
566 when there is an absolute guarantee that the particular <code>flyweight</code>
567 type will not be used in a concurrent scenario.
568 </p>
569
570 <h2><a name="tracking">Tracking policies</a></h2>
571
572 <p>
573 A <i>tracking policy</i> controls the lifetimes of the <code>flyweight</code>
574 objects and can act based on this information. For instance, a suitable
575 tracking mechanism can determine when a given value stored in the factory
576 can be safely erased because it is no longer referenced by any
577 <code>flyweight</code>; this is precisely what the default tracking policy,
578 <code>refcounted</code>, does.
579 </p>
580
581 <h3><a name="refcounted"><code>refcounted</code></a></h3>
582
583 <blockquote>
584 <b>Header:</b> <a href="../reference/tracking.html#refcounted_synopsis"><code>"boost/flyweight/refcounted.hpp"</code></a><br>
585 <b>Syntax:</b> <code>refcounted</code>
586 </blockquote>
587
588 <p>
589 This tracking policy determines that values stored in the factory be
590 equipped with reference counting mechanisms so that a factory entry is
591 erased when the last <code>flyweight</code> object associated to it
592 is destroyed.
593 </p>
594
595 <h3><a name="no_tracking"><code>no_tracking</code></a></h3>
596
597 <blockquote>
598 <b>Header:</b> <a href="../reference/tracking.html#no_tracking_synopsis"><code>"boost/flyweight/no_tracking.hpp"</code></a><br>
599 <b>Syntax:</b> <code>no_tracking</code>
600 </blockquote>
601
602 <p>
603 No flyweight tracking is done when this policy is selected, which implies
604 that the values stored in the factory remain in it until program termination.
605 As compared with <code>refcounted</code>, <code>no_tracking</code> presents
606 advantages and drawbacks. The benefits are:
607 <ul>
608 <li>Non-tracked flyweight objects are faster to pass around than refcounted ones.</li>
609 <li>There is some reduction in memory usage due to the
610 absence of reference counters.</li>
611 </ul>
612 whereas potential drawbacks of using <code>no_tracking</code> include:
613 <ul>
614 <li>The number of unused entries stored in the factory can keep growing
615 during the program lifetime, which can become a problem for certain
616 patterns of flyweight creation where the set of active values "drifts"
617 over time.</li>
618 <li>There can be a potential delay during program termination, since
619 it is then when all the factory entries get destroyed at once.</li>
620 </ul>
621 </p>
622
623 <hr>
624
625 <div class="prev_link"><a href="key_value.html"><img src="../prev.gif" alt="key-value flyweights" border="0"><br>
626 Key-value flyweights
627 </a></div>
628 <div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight tutorial" border="0"><br>
629 Boost.Flyweight tutorial
630 </a></div>
631 <div class="next_link"><a href="extension.html"><img src="../next.gif" alt="extending Boost.Flyweight" border="0"><br>
632 Extending Boost.Flyweight
633 </a></div><br clear="all" style="clear: all;">
634
635 <br>
636
637 <p>Revised November 8th 2008</p>
638
639 <p>&copy; Copyright 2006-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
640 Distributed under the Boost Software
641 License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
642 LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
643 http://www.boost.org/LICENSE_1_0.txt</a>)
644 </p>
645
646 </body>
647 </html>