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 - Examples
</title>
7 <link rel=
"stylesheet" href=
"style.css" type=
"text/css">
8 <link rel=
"start" href=
"index.html">
9 <link rel=
"prev" href=
"performance.html">
10 <link rel=
"up" href=
"index.html">
11 <link rel=
"next" href=
"tests.html">
15 <h1><img src=
"../../../boost.png" alt=
"Boost logo" align=
16 "middle" width=
"277" height=
"86">Boost.Flyweight Examples
</h1>
18 <div class=
"prev_link"><a href=
"performance.html"><img src=
"prev.gif" alt=
"performance" border=
"0"><br>
21 <div class=
"up_link"><a href=
"index.html"><img src=
"up.gif" alt=
"index" border=
"0"><br>
24 <div class=
"next_link"><a href=
"tests.html"><img src=
"next.gif" alt=
"tests" border=
"0"><br>
26 </a></div><br clear=
"all" style=
"clear: all;">
27 <br clear=
"all" style=
"clear: all;">
34 <li><a href=
"#example1">Example
1: basic usage
</a></li>
35 <li><a href=
"#example2">Example
2: key-value flyweights
</a></li>
36 <li><a href=
"#example3">Example
3: flyweights and the composite pattern
</a></li>
37 <li><a href=
"#example4">Example
4: formatted text processing
</a></li>
38 <li><a href=
"#example5">Example
5: flyweight-based memoization
</a></li>
39 <li><a href=
"#example6">Example
6: serialization
</a></li>
40 <li><a href=
"#example7">Example
7: performance comparison
</a></li>
41 <li><a href=
"#example8">Example
8: custom factory
</a></li>
44 <h2><a name=
"example1">Example
1: basic usage
</a></h2>
47 See
<a href=
"../example/basic.cpp">source code
</a>.
51 Dummy program showing the basic capabilities of
<code>flyweight
</code>
52 explained at the
<a href=
"tutorial/basics.html">tutorial
</a>.
55 <h2><a name=
"example2">Example
2: key-value flyweights
</a></h2>
58 See
<a href=
"../example/key_value.cpp">source code
</a>.
62 The program simulates the scenario described at the tutorial section on
63 <a href=
"tutorial/key_value.html">key-value flyweights
</a>: The class
64 <code>texture
</code> manages some texture rendering data stored in
65 a file whose location is given at construction time. The program
66 handles large quantities of objects of this class by encapsulating
67 them into key-value flyweights keyed by filename. Observe how the
68 execution of the program results in no extra constructions or copies
69 of objects of type
<code>texture
</code> except those absolutely
73 <h2><a name=
"example3">Example
3: flyweights and the composite pattern
</a></h2>
76 See
<a href=
"../example/composite.cpp">source code
</a>.
80 The
<a href=
"http://c2.com/cgi/wiki?CompositePattern"><i>composite
81 design pattern
</i></a> revolves about the idea that a tree data structure
82 can be easily constructed and manipulated by defining the tree node type
83 polymorphically so that either is a leaf node or else contains a list of
84 pointers to their child nodes.
85 This way, a tree is the exact same entity as its root node, which allows
86 for very simple recursive tree-handling algorithms. Large composite trees
87 having a high degree of duplication of nodes and subtrees (as for instance
88 those generated when parsing a computer program) are a natural fit for the
89 flyweight idiom: simply turning the node type into a flyweight
90 automatically deals with duplication at the node and subtree level.
94 The example program parses Lisp-like lists of the form
95 <code>(a
<sub>1</sub> ... a
<sub><i>n
</i></sub>)
</code> where each
96 <code>a
<sub>i
</sub></code> is a terminal string or a list. The parsed
97 data structure is a composite type defined using Boost.Flyweight in conjunction
98 with the recursive facilities of
99 <a href=
"../../variant/index.html">Boost.Variant
</a>. So, given the list
103 (= (tan (+ x y))(/ (+ (tan x)(tan y))(-
1 (* (tan x)(tan y)))))
107 the resulting data structure implicitly detects the duplicated
108 occurrences of
<code>+
</code>,
<code>x
</code>,
<code>y
</code>,
109 <code>tan
</code>,
<code>(tan x)
</code> and
<code>(tan y)
</code>.
112 <h2><a name=
"example4">Example
4: formatted text processing
</a></h2>
115 See
<a href=
"../example/html.cpp">source code
</a>.
119 A classic example of application of the flyweight pattern is that of a
120 text processor which handles characters with rich formatting information,
121 like font type, size, color and special options (boldness, italics, etc.)
122 Coding the formatting information of each character takes considerable
123 space, but, given the high degree of repetition typical in a document,
124 maintaining formatted characters as flyweight objects drastically reduces
129 The example program parses, manipulates and stores HTML documents following
130 flyweight-based representation techniques. Given the hierarchical nature
131 of HTML markup, a crude approximation to the formatting options of a given
132 character is just to equate them with the stack of tag contexts to which
133 the character belongs, as the figure shows.
138 alt=
"formatting contexts of characters in an HTML document"
139 width=
"320" height=
"275"><br>
140 <b>Fig.
1: Formatting contexts of characters in an HTML document.
</b>
144 HTML documents are then parsed as arrays of (character, format)
145 pairs, where the format is the tag context as described above. The very high
146 degree of redundancy in formatting information is taken care of by the
147 use of Boost.Flyweight. This character-based representation makes it
148 easy to manipulate the document: transposition and elimination of
149 portions of text are trivial operations. As an example, the program
150 reverses the text occupying the central portion of the document.
151 Saving the result in HTML reduces to traversing the array of formatted
152 characters and emitting opening/closing HTML tags as the context of adjacent
157 For the sake of brevity, the HTML parsing capabilities of this program
158 are coarse: for instance, elements without end-tag (like
<BR
>), character
159 encoding and HTML entities (e.g.
"&copy;" for
©) are not properly
160 handled. Improving the parsing code is left as an exercise to the reader.
163 <h2><a name=
"example5">Example
5: flyweight-based memoization
</a></h2>
166 See
<a href=
"../example/fibonacci.cpp">source code
</a>.
170 <a href=
"http://en.wikipedia.org/wiki/Memoization">Memoization
</a>
171 is an optimization technique consisting in caching
172 the results of a computation for later reuse; this can dramatically
173 improve performance when calculating recursive numerical functions,
174 for instance.
<a href=
"tutorial/key_value.html">Key-value flyweights
</a>
175 can be used to implement memoization for a numerical function
<i>f
</i>
176 by modeling a memoized invocation of the function as a value of
177 type
<code>flyweight
<key_value
<int,compute_f
> ></code>, where
178 <code>compute_f
</code> is a type that does the computation of
179 <i>f
</i>(
<i>n
</i>) at its
<code>compute_f::compute_f(int)
</code> constructor.
180 For instance, the
<a href=
"http://mathworld.wolfram.com/FibonacciNumber.html">Fibonacci
181 numbers
</a> can be computed with memoization like this:
185 <span class=keyword
>typedef
</span> <span class=identifier
>flyweight
</span><span class=special
><</span><span class=identifier
>key_value
</span><span class=special
><</span><span class=keyword
>int
</span><span class=special
>,
</span><span class=identifier
>compute_fibonacci
</span><span class=special
>>,
</span><span class=identifier
>no_tracking
</span><span class=special
>></span> <span class=identifier
>fibonacci
</span><span class=special
>;
</span>
187 <span class=keyword
>struct
</span> <span class=identifier
>compute_fibonacci
</span>
188 <span class=special
>{
</span>
189 <span class=identifier
>compute_fibonacci
</span><span class=special
>(
</span><span class=keyword
>int
</span> <span class=identifier
>n
</span><span class=special
>):
</span>
190 <span class=identifier
>result
</span><span class=special
>(
</span><span class=identifier
>n
</span><span class=special
>==
</span><span class=number
>0</span><span class=special
>?
</span><span class=number
>0</span><span class=special
>:
</span><span class=identifier
>n
</span><span class=special
>==
</span><span class=number
>1</span><span class=special
>?
</span><span class=number
>1</span><span class=special
>:
</span><span class=identifier
>fibonacci
</span><span class=special
>(
</span><span class=identifier
>n
</span><span class=special
>-
</span><span class=number
>2</span><span class=special
>).
</span><span class=identifier
>get
</span><span class=special
>()+
</span><span class=identifier
>fibonacci
</span><span class=special
>(
</span><span class=identifier
>n
</span><span class=special
>-
</span><span class=number
>1</span><span class=special
>).
</span><span class=identifier
>get
</span><span class=special
>())
</span>
191 <span class=special
>{}
</span>
193 <span class=keyword
>operator
</span> <span class=keyword
>int
</span><span class=special
>()
</span><span class=keyword
>const
</span><span class=special
>{
</span><span class=keyword
>return
</span> <span class=identifier
>result
</span><span class=special
>;}
</span>
194 <span class=keyword
>int
</span> <span class=identifier
>result
</span><span class=special
>;
</span>
195 <span class=special
>};
</span>
199 The
<a href=
"tutorial/configuration.html#no_tracking"><code>no_tracking
</code></a>
200 policy is used so that the memoized computations persist for future
201 use throughout the program. The provided program develops this example in full.
204 <h2><a name=
"example6">Example
6: serialization
</a></h2>
207 See
<a href=
"../example/serialization.cpp">source code
</a>.
211 If
<code>T
</code> is serializable (using
212 <a href=
"../../serialization/index.html">Boost.Serialization
</a>),
213 <code>flyweight
<T
></code> is automatically
214 serializable as well. The example program performs the following two
215 complementary procedures:
217 <li>Read a text file as a
<code>std::vector
<flyweight
<std::string
> ></code>
218 and save the structure to a serialization file.
220 <li>Load a
<code>std::vector
<flyweight
<std::string
> ></code> from a
221 serialization file and write it as a text file.
224 If you visually inspect the contents of any of the generated serialization files
225 you can notice that no word appears twice; Boost.Flyweight implements some internal
226 machinery that avoids duplicating output information when saving equal
227 <code>flyweight
</code> objects.
230 <h2><a name=
"example7">Example
7: performance comparison
</a></h2>
233 See
<a href=
"../example/perf.cpp">source code
</a>.
237 This program measures the time and space performances of a simple
238 string type against several differently configured
<code>flyweight
</code>
239 instantations as used in a conventional task involving parsing a file and
240 doing some manipulations on the parsed text.
241 Memory consumption is computed by instrumenting the relevant
242 components (the string type itself, flyweight factories, etc.) with custom
243 allocators that keep track of the allocations and deallocations requested.
244 The program has been used to produce the experimental results given
245 at the
<a href=
"performance.html#results">performance section
</a>.
248 <h2><a name=
"example8">Example
8: custom factory
</a></h2>
251 See
<a href=
"../example/custom_factory.cpp">source code
</a>.
255 The example shows how to write and use a custom factory class. This
256 "verbose" factory outputs messages tracing the invocations of its public interface
257 by Boost.Flyweight, so helping the user visualize factory usage patterns.
262 <div class=
"prev_link"><a href=
"performance.html"><img src=
"prev.gif" alt=
"performance" border=
"0"><br>
265 <div class=
"up_link"><a href=
"index.html"><img src=
"up.gif" alt=
"index" border=
"0"><br>
268 <div class=
"next_link"><a href=
"tests.html"><img src=
"next.gif" alt=
"tests" border=
"0"><br>
270 </a></div><br clear=
"all" style=
"clear: all;">
271 <br clear=
"all" style=
"clear: all;">
275 <p>Revised October
14th
2014</p>
277 <p>© Copyright
2006-
2014 Joaqu
ín M L
ópez Mu
ñoz.
278 Distributed under the Boost Software
279 License, Version
1.0. (See accompanying file
<a href=
"../../../LICENSE_1_0.txt">
280 LICENSE_1_0.txt
</a> or copy at
<a href=
"http://www.boost.org/LICENSE_1_0.txt">
281 http://www.boost.org/LICENSE_1_0.txt
</a>)