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