Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/signals/doc/design.xml @ 35

Last change on this file since 35 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 8.7 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!--
3   Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
4 
5   Distributed under the Boost Software License, Version 1.0.
6   (See accompanying file LICENSE_1_0.txt or copy at
7   http://www.boost.org/LICENSE_1_0.txt)
8  -->
9<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
10  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
11<section last-revision="$Date: 2006/11/03 19:45:40 $">
12  <title>Design Overview</title>
13
14  <using-namespace name="boost"/>
15  <using-namespace name="boost::signals"/>
16
17  <section>
18    <title>Type Erasure</title>
19
20    <para>"Type erasure", where static type information is eliminated
21    by the use of dynamically dispatched interfaces, is used
22    extensively within the Boost.Signals library to reduce the amount
23    of code generated by template instantiation. Each signal must
24    manage a list of slots and their associated connections, along
25    with a <code>std::map</code> to map from group identifiers to
26    their associated connections. However, instantiating this map for
27    every token type, and perhaps within each translation unit (for
28    some popular template instantiation strategies) increase compile
29    time overhead and space overhead.</para>
30
31    <para> To combat this so-called "template bloat", we use
32    Boost.Function and Boost.Any to store unknown types and
33    operations. Then, all of the code for handling the list of slots
34    and the mapping from slot identifiers to connections is factored
35    into the class <code><classname>signal_base</classname></code>
36    that deals exclusively with the <code>any</code> and
37    <code><classname>function</classname></code> objects, hiding the
38    actual implementations using the well-known pimpl idiom. The
39    actual <code><classname>signalN</classname></code> class templates
40    deal only with code that will change depending on the number of
41    arguments or which is inherently template-dependent (such as
42    connection).</para>
43  </section>
44
45  <section>
46    <title><code>connection</code> class</title>
47
48    <para> The <code><classname>connection</classname></code> class is
49    central to the behavior of the Boost.Signals library. It is the
50    only entity within the Boost.Signals system that has knowledge of
51    all objects that are associated by a given connection. To be
52    specific, the <code><classname>connection</classname></code> class
53    itself is merely a thin wrapper over a
54    <code><classname>shared_ptr</classname></code> to a
55    <code>basic_connection</code> object.</para>
56
57    <para> <code><classname>connection</classname></code> objects are
58    stored by all participants in the Signals system: each
59    <code><classname>trackable</classname></code> object contains a
60    list of <code><classname>connection</classname></code> objects
61    describing all connections it is a part of; similarly, all signals
62    contain a set of pairs that define a slot. The pairs consist of a
63    slot function object (generally a Boost.Function object) and a
64    <code><classname>connection</classname></code> object (that will
65    disconnect on destruction). Finally, the mapping from slot groups
66    to slots is based on the key value in a
67    <code><classname>std::multimap</classname></code> (the stored data
68    in the <code><classname>std::multimap</classname></code> is the
69    slot pair).</para>
70  </section>
71
72  <section>
73    <title>Slot Call Iterator</title>
74
75    <para> The slot call iterator is conceptually a stack of iterator
76    adaptors that modify the behavior of the underlying iterator
77    through the list of slots. The following table describes the type
78    and behavior of each iterator adaptor required. Note that this is
79    only a conceptual model: the implementation collapses all these
80    layers into a single iterator adaptor because several popular
81    compilers failed to compile the implementation of the conceptual
82    model.</para>
83
84    <informaltable>
85      <tgroup cols="2" align="left">
86        <thead>
87          <row>
88            <entry>Iterator Adaptor</entry>
89            <entry>Purpose</entry>
90          </row>
91        </thead>
92        <tbody>
93          <row>
94            <entry><para>Slot List Iterator</para></entry>
95            <entry><para>An iterator through the list of slots
96            connected to a signal. The <code>value_type</code> of this
97            iterator will be
98            <code><classname>std::pair</classname>&lt;any,
99            connection&gt;</code>, where the
100            <code><classname>any</classname></code> contains an
101            instance of the slot function type.</para></entry>
102          </row>
103          <row>
104            <entry><para>Filter Iterator Adaptor</para></entry>
105            <entry><para>This filtering iterator adaptor filters out
106            slots that have been disconnected, so we never see a
107            disconnected slot in later stages.</para></entry>
108          </row>
109          <row>
110            <entry><para>Projection Iterator Adaptor</para></entry>
111            <entry><para>The projection iterator adaptor returns a
112            reference to the first member of the pair that constitutes
113            a connected slot (e.g., just the
114            <code><classname>boost::any</classname></code> object that
115            holds the slot function).</para></entry>
116          </row>
117          <row>
118            <entry><para>Transform Iterator Adaptor</para></entry>
119            <entry><para>This transform iterator adaptor performs an
120            <code><functionname>any_cast</functionname></code> to
121            extract a reference to the slot function with the
122            appropriate slot function type.</para></entry>
123          </row>
124          <row>
125            <entry><para>Transform Iterator Adaptor</para></entry>
126            <entry><para>This transform iterator adaptor calls the
127            function object returned by dereferencing the underlying
128            iterator with the set of arguments given to the signal
129            itself, and returns the result of that slot
130            call.</para></entry>
131          </row>         
132          <row>
133            <entry><para>Input Caching Iterator Adaptor</para></entry>
134            <entry><para>This iterator adaptor caches the result of
135            dereferencing the underlying iterator. Therefore,
136            dereferencing this iterator multiple times will only
137            result in the underlying iterator being dereferenced once;
138            thus, a slot can only be called once but its result can be
139            used multiple times.</para></entry>
140          </row>
141          <row>
142            <entry><para>Slot Call Iterator</para></entry>
143            <entry><para>Iterates over calls to each slot.</para></entry>
144          </row>
145        </tbody>
146      </tgroup>
147    </informaltable>
148  </section>
149
150  <section>
151    <title><code>visit_each</code> function template</title>
152   
153    <para> The <code><functionname>visit_each</functionname></code>
154    function template is a mechanism for discovering objects that are
155    stored within another object. Function template
156    <code><functionname>visit_each</functionname></code> takes three
157    arguments: an object to explore, a visitor function object that is
158    invoked with each subobject, and the <code>int</code> 0. </para>
159
160    <para> The third parameter is merely a temporary solution to the
161    widespread lack of proper function template partial ordering. The
162    primary <code><functionname>visit_each</functionname></code>
163    function template specifies this third parameter type to be
164    <code>long</code>, whereas any user specializations must specify
165    their third parameter to be of type <code>int</code>. Thus, even
166    though a broken compiler cannot tell the ordering between, e.g., a
167    match against a parameter <code>T</code> and a parameter
168    <code>A&lt;T&gt;</code>, it can determine that the conversion from
169    the integer 0 to <code>int</code> is better than the conversion to
170    <code>long</code>. The ordering determined by this conversion thus
171    achieves partial ordering of the function templates in a limited,
172    but successful, way. The following example illustrates the use of
173    this technique:</para>
174
175    <programlisting>
176template&lt;typename&gt; class A {};
177template&lt;typename T&gt; void foo(T, long);
178template&lt;typename T&gt; void foo(A&lt;T&gt;, int);
179A&lt;T&gt; at;
180foo(at, 0);
181</programlisting>
182
183    <para> In this example, we assume that our compiler can not tell
184    that <code>A&lt;T&gt;</code> is a better match than
185    <code>T</code>, and therefore assume that the function templates
186    cannot be ordered based on that parameter. Then the conversion
187    from 0 to <code>int</code> is better than the conversion from 0 to
188    <code>long</code>, and the second function template is
189    chosen. </para>
190  </section>
191</section>
Note: See TracBrowser for help on using the repository browser.