1 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.0.1 Transitional//EN">
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">
15 <h1><img src=
"../../../../boost.png" alt=
"Boost logo" align=
16 "middle" width=
"277" height=
"86">Boost.Flyweight Tutorial: Configuring Boost.Flyweight
</h1>
18 <div class=
"prev_link"><a href=
"key_value.html"><img src=
"../prev.gif" alt=
"key-value flyweights" border=
"0"><br>
21 <div class=
"up_link"><a href=
"index.html"><img src=
"../up.gif" alt=
"Boost.Flyweight tutorial" border=
"0"><br>
22 Boost.Flyweight tutorial
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;">
33 <li><a href=
"#intro">Configurable aspects of Boost.Flyweight
</a>
35 <li><a href=
"#free_order_template">Free-order template parameter interface
</a></li>
36 <li><a href=
"#header_inclusion">Header inclusion
</a></li>
39 <li><a href=
"#tagging">Tagging
</a></li>
40 <li><a href=
"#factories">Factory specification
</a>
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>
48 <li><a href=
"#holders">Holder specification
</a>
50 <li><a href=
"#static_holder"><code>static_holder
</code></a></li>
51 <li><a href=
"#intermodule_holder"><code>intermodule_holder
</code></a></li>
54 <li><a href=
"#locking">Locking policies
</a>
56 <li><a href=
"#simple_locking"><code>simple_locking
</code></a></li>
57 <li><a href=
"#no_locking"><code>no_locking
</code></a></li>
60 <li><a href=
"#tracking">Tracking policies
</a>
62 <li><a href=
"#refcounted"><code>refcounted
</code></a></li>
63 <li><a href=
"#no_tracking"><code>no_tracking
</code></a></li>
68 <h2><a name=
"intro">Configurable aspects of Boost.Flyweight
</a></h2>
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:
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.
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
91 <h3><a name=
"free_order_template">Free-order template parameter interface
</a></h3>
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:
102 <span class=identifier
>flyweight
</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
>tag
</span><span class=special
><</span><span class=identifier
>label_t
</span><span class=special
>>,
</span> <span class=identifier
>set_factory
</span><span class=special
><>,
</span> <span class=identifier
>no_tracking
</span> <span class=special
>></span>
110 <span class=identifier
>flyweight
</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
>no_tracking
</span><span class=special
>,
</span> <span class=identifier
>tag
</span><span class=special
><</span><span class=identifier
>label_t
</span><span class=special
>>,
</span> <span class=identifier
>set_factory
</span><span class=special
><></span> <span class=special
>></span>
114 or in any other order; only
<code>std::string
</code> is required to occupy
115 the first place in the specification.
118 <h3><a name=
"header_inclusion">Header inclusion
</a></h3>
121 The example code shown at the
<a href=
"basics.html#intro">introductory section
</a>
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:
129 <span class=preprocessor
>#include
</span> <span class=special
><</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
>></span> <span class=comment
>// class template flyweight
</span>
130 <span class=preprocessor
>#include
</span> <span class=special
><</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
>></span> <span class=comment
>// hashed flyweight factory
</span>
131 <span class=preprocessor
>#include
</span> <span class=special
><</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
>></span> <span class=comment
>// regular factory instantiation
</span>
132 <span class=preprocessor
>#include
</span> <span class=special
><</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
>></span> <span class=comment
>// simple locking policy
</span>
133 <span class=preprocessor
>#include
</span> <span class=special
><</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
>></span> <span class=comment
>// refcounting tracking policy
</span>
137 When using components other than these, their specific headers must be
141 <h2><a name=
"tagging">Tagging
</a></h2>
144 Consider the following two types:
148 <span class=keyword
>typedef
</span> <span class=identifier
>flyweight
</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
>name_t
</span><span class=special
>;
</span>
149 <span class=keyword
>typedef
</span> <span class=identifier
>flyweight
</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
>ip_address_t
</span><span class=special
>;
</span>
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:
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
><</span><span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>string
</span><span class=special
>,
</span><span class=identifier
>tag
</span><span class=special
><</span><span class=identifier
>name_tag
</span><span class=special
>></span> <span class=special
>></span> <span class=identifier
>name_t
</span><span class=special
>;
</span>
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
><</span><span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>string
</span><span class=special
>,
</span><span class=identifier
>tag
</span><span class=special
><</span><span class=identifier
>ip_address_tag
</span><span class=special
>></span> <span class=special
>></span> <span class=identifier
>ip_address_t
</span><span class=special
>;
</span>
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
179 <h2><a name=
"factories">Factory specification
</a></h2>
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
<T
></code> is
186 actually equivalent to
190 <span class=identifier
>flyweight
</span><span class=special
><</span><span class=identifier
>T
</span><span class=special
>,
</span><span class=identifier
>hashed_factory
</span><span class=special
><></span> <span class=special
>></span>
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.
200 <h3><a name=
"factory_types">Types involved in the configuration of factories
</a></h3>
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
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
&</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.
222 <h3><a name=
"hashed_factory"><code>hashed_factory
</code></a></h3>
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
<[Hash[,Pred[,Allocator]]]
></code>
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>,
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
245 <span class=identifier
>flyweight
</span><span class=special
><</span><span class=identifier
>T
</span><span class=special
>,
</span><span class=identifier
>hashed_factory
</span><span class=special
><></span> <span class=special
>></span>
253 <span class=identifier
>flyweight
</span><span class=special
><</span>
254 <span class=identifier
>T
</span><span class=special
>,
</span>
255 <span class=identifier
>hashed_factory
</span><span class=special
><</span>
256 <span class=identifier
>boost
</span><span class=special
>::
</span><span class=identifier
>hash
</span><span class=special
><</span><span class=identifier
>key_value
</span><span class=special
>>,
</span>
257 <span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>equal_to
</span><span class=special
><</span><span class=identifier
>key_value
</span><span class=special
>>,
</span>
258 <span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>allocator
</span><span class=special
><</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
>></span>
259 <span class=special
>></span>
260 <span class=special
>></span>
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:
274 <span class=identifier
>flyweight
</span><span class=special
><</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
><</span>
277 <span class=identifier
>special_hash
</span><span class=special
><</span><span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>string
</span><span class=special
>>,
</span>
278 <span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>equal_to
</span><span class=special
><</span><span class=identifier
>key_value
</span><span class=special
>>,
</span>
279 <span class=identifier
>custom_allocator
</span><span class=special
><</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
>></span>
280 <span class=special
>></span>
281 <span class=special
>></span>
284 <h3><a name=
"set_factory"><code>set_factory
</code></a></h3>
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
<[Compare[,Allocator]]
></code>
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
305 <span class=identifier
>flyweight
</span><span class=special
><</span><span class=identifier
>T
</span><span class=special
>,
</span><span class=identifier
>set_factory
</span><span class=special
><></span> <span class=special
>></span>
313 <span class=identifier
>flyweight
</span><span class=special
><</span>
314 <span class=identifier
>T
</span><span class=special
>,
</span>
315 <span class=identifier
>set_factory
</span><span class=special
><</span><span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>less
</span><span class=special
><</span><span class=identifier
>key_type
</span><span class=special
>>,
</span><span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>allocator
</span><span class=special
><</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
>></span> <span class=special
>></span>
316 <span class=special
>></span>
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
328 <h3><a name=
"assoc_container_factory"><code>assoc_container_factory
</code></a></h3>
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
<ContainerSpecifier
></code>
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
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
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.
365 Let us see what a container specifier looks like with an example.
366 Suppose we have our own ordered container like the following:
370 <span class=keyword
>template
</span><span class=special
><</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
><</span><span class=identifier
>Elem
</span><span class=special
>>,
</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
><</span><span class=identifier
>Elem
</span><span class=special
>></span>
374 <span class=special
>></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>
382 Then
<code>ultrafast_set
</code> can be plugged into
383 <code>assoc_container_factory
</code> like this:
387 <span class=keyword
>typedef
</span> <span class=identifier
>flyweight
</span><span class=special
><</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
><</span>
390 <span class=comment
>// MPL lambda expression follows
</span>
391 <b><span class=identifier
>ultrafast_set
</span><span class=special
><</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
><</span><span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>string
</span><span class=special
>></span> <span class=special
>></span></b>
392 <span class=special
>></span>
393 <span class=special
>></span> <span class=identifier
>flyweight_string
</span><span class=special
>;
</span>
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
&</code>
406 (here
<code>const std::string
&</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:
414 <span class=keyword
>typedef
</span> <span class=identifier
>flyweight
</span><span class=special
><</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
><</span>
417 <b><span class=identifier
>ultrafast_set
</span><span class=special
><</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
><</span><span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>string
</span><span class=special
>>,
</span>
420 <span class=identifier
>std
</span><span class=special
>::
</span><span class=identifier
>allocator
</span><span class=special
><</span><span class=identifier
>mpl
</span><span class=special
>::
</span><span class=identifier
>_1
</span><span class=special
>></span>
421 <span class=special
>></span>
422 <span class=special
>></span></b>
423 <span class=special
>></span> <span class=identifier
>flyweight_string
</span><span class=special
>;
</span>
426 <h2><a name=
"holders">Holder specification
</a></h2>
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.
440 <h3><a name=
"static_holder"><code>static_holder
</code></a></h3>
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>
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
453 <h3><a name=
"intermodule_holder"><code>intermodule_holder
</code></a></h3>
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>
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:
471 <span class=comment
>// module
1</span>
473 <span class=keyword
>typedef
</span> <span class=identifier
>flyweight
</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
>flyweight_string
</span><span class=special
>;
</span>
475 <span class=comment
>// produce_string is exported so that it can be dynamically
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
>"boost
"</span><span class=special
>);
</span>
481 <span class=special
>}
</span>
485 <span class=comment
>// main program
</span>
487 <span class=keyword
>typedef
</span> <span class=identifier
>flyweight
</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
>flyweight_string
</span><span class=special
>;
</span>
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>
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
>"boost
"</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>
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.
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:
519 <span class=keyword
>typedef
</span> <span class=identifier
>flyweight
</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
><b>intermodule_holder
</b></span><span class=special
>></span> <span class=identifier
>flyweight_string
</span><span class=special
>;
</span>
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.
530 <h2><a name=
"locking">Locking policies
</a></h2>
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.
539 <h3><a name=
"simple_locking"><code>simple_locking
</code></a></h3>
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>
547 This is the default locking policy. It specifies the simplest native
548 synchronization primitives provided by the operating system, whenever
552 <h3><a name=
"no_locking"><code>no_locking
</code></a></h3>
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>
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.
570 <h2><a name=
"tracking">Tracking policies
</a></h2>
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.
581 <h3><a name=
"refcounted"><code>refcounted
</code></a></h3>
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>
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
595 <h3><a name=
"no_tracking"><code>no_tracking
</code></a></h3>
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>
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:
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>
612 whereas potential drawbacks of using
<code>no_tracking
</code> include:
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"
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>
625 <div class=
"prev_link"><a href=
"key_value.html"><img src=
"../prev.gif" alt=
"key-value flyweights" border=
"0"><br>
628 <div class=
"up_link"><a href=
"index.html"><img src=
"../up.gif" alt=
"Boost.Flyweight tutorial" border=
"0"><br>
629 Boost.Flyweight tutorial
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;">
637 <p>Revised November
8th
2008</p>
639 <p>© Copyright
2006-
2008 Joaqu
ín M L
ópez Mu
ñ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>)