]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <html> |
2 | <head> | |
3 | <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> | |
4 | <title>The student and the mentor</title> | |
5 | <link rel="stylesheet" href="../../boostbook.css" type="text/css"> | |
6 | <meta name="generator" content="DocBook XSL Stylesheets V1.77.1"> | |
7 | <link rel="home" href="../../index.html" title="Chapter 1. Boost.Bimap"> | |
8 | <link rel="up" href="../rationale.html" title="Rationale"> | |
9 | <link rel="prev" href="code.html" title="Code"> | |
10 | <link rel="next" href="../history.html" title="History"> | |
11 | </head> | |
12 | <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> | |
13 | <table cellpadding="2" width="100%"><tr> | |
14 | <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> | |
15 | <td align="center"><a href="../../../../../../index.html">Home</a></td> | |
16 | <td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> | |
17 | <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> | |
18 | <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> | |
19 | <td align="center"><a href="../../../../../../more/index.htm">More</a></td> | |
20 | </tr></table> | |
21 | <hr> | |
22 | <div class="spirit-nav"> | |
23 | <a accesskey="p" href="code.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../history.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> | |
24 | </div> | |
25 | <div class="section boost_bimap_rationale_the_student_and_the_mentor"> | |
26 | <div class="titlepage"><div><div><h3 class="title"> | |
27 | <a name="boost_bimap.rationale.the_student_and_the_mentor"></a><a class="link" href="the_student_and_the_mentor.html" title="The student and the mentor">The | |
28 | student and the mentor</a> | |
29 | </h3></div></div></div> | |
30 | <div class="tip"><table border="0" summary="Tip"> | |
31 | <tr> | |
32 | <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> | |
33 | <th align="left">Tip</th> | |
34 | </tr> | |
35 | <tr><td align="left" valign="top"><p> | |
36 | It is a good idea to read the original <a href="http://h1.ripway.com/mcape/boost/libs/misc/" target="_top">Boost.Misc | |
37 | SoC proposal</a> first. | |
38 | </p></td></tr> | |
39 | </table></div> | |
40 | <div class="blockquote"><blockquote class="blockquote"><p> | |
41 | <code class="literal">- The discussion starts with Joaquin trying to strip out the "misc" | |
42 | name out of the library -</code> | |
43 | </p></blockquote></div> | |
44 | <p> | |
45 | <span class="inlinemediaobject"><img src="../../images/people/joaquin.png" alt="joaquin"></span> | |
46 | </p> | |
47 | <p> | |
48 | <span class="bold"><strong>Joaquin</strong></span> | |
49 | </p> | |
50 | <div class="blockquote"><blockquote class="blockquote"><p> | |
51 | <span class="emphasis"><em> Thinking about it, the unifying principle of MISC containers | |
52 | is perhaps misleading: certainly all miscs use multi-indexing internally, | |
53 | but this does not reflect much in the external interface (as it should | |
54 | be, OTOH). So, from the user's point of view, miscs are entirely heterogeneous | |
55 | beasts. Moreover, there isn't in your proposal any kind of global facility | |
56 | common to all miscs. What about dropping the misc principle and working | |
57 | on each container as a separate library, then? You'd have boost::bimap, | |
58 | boost::mru, etc, and no common intro to them. This also opens up the possibility | |
59 | to add other containers to the suite which aren't based on B.MI. What's | |
60 | your stance on this? Do you see a value in keeping miscs conceptually together? | |
61 | </em></span> | |
62 | </p></blockquote></div> | |
63 | <p> | |
64 | <span class="inlinemediaobject"><img src="../../images/people/matias.png" alt="matias"></span> | |
65 | </p> | |
66 | <p> | |
67 | <span class="bold"><strong>Matias</strong></span> | |
68 | </p> | |
69 | <div class="blockquote"><blockquote class="blockquote"><p> | |
70 | <span class="emphasis"><em> As the original proposal states only two containers (bimap and | |
71 | mru set) both based in B.MI, it was straight forward to group them together. | |
72 | When I was writing the SoC proposal I experienced a similar feeling when | |
73 | the two families begin to grow. As you say, the only common denominator | |
74 | is their internal implementation. I thought a bit about a more general | |
75 | framework to join this two families (and other internally related ones) | |
76 | and finally came up with an idea: Boost.MultiIndex! So I think that it | |
77 | is not a good idea to try to unify the two families and I voted in favor | |
78 | of get rid of the misc part of boost::misc::bimap and boost::misc::mru. | |
79 | Anyway, for my SoC application it seems OK to put the two families in the | |
80 | same project because although from the outside they are completely unrelated, | |
81 | the work I will have to do in order to build the libraries will be consistent | |
82 | and what I will learn coding the bimap family will be used when I start | |
83 | to code the mru family. When the mru family is in place, I will surely | |
84 | have learnt other things to improve the bimap group. </em></span> | |
85 | </p></blockquote></div> | |
86 | <div class="blockquote"><blockquote class="blockquote"><p> | |
87 | <span class="emphasis"><em> On the other hand, I think it will be useful for the general | |
88 | user to have at least some document linked in the B.MI documentation that | |
89 | enumerates the most common cases of uses (a bimap and an mru set for example) | |
90 | and points where to find clean implementation for this useful containers. | |
91 | For now, a link to boost::bimap and other one to boost::mru will suffice. | |
92 | If you think about the title of such a document, you will probably come | |
93 | up with something like: Common Multi Index Specialized Containers, and | |
94 | we are back to our misc proposal. So, to order some ideas: </em></span> | |
95 | </p></blockquote></div> | |
96 | <div class="blockquote"><blockquote class="blockquote"><p> | |
97 | <span class="emphasis"><em>- A new family of containers that can be accessed by both key | |
98 | will be created. (boost::bimap)</em></span> | |
99 | </p></blockquote></div> | |
100 | <div class="blockquote"><blockquote class="blockquote"><p> | |
101 | <span class="emphasis"><em>- A new family of time aware containers will see the light. (boost::mru)</em></span> | |
102 | </p></blockquote></div> | |
103 | <div class="blockquote"><blockquote class="blockquote"><p> | |
104 | <span class="emphasis"><em>- A page can be added to B.MI documentation, titled misc that | |
105 | links this new libraries.</em></span> | |
106 | </p></blockquote></div> | |
107 | <div class="blockquote"><blockquote class="blockquote"><p> | |
108 | <span class="emphasis"><em> This is a clearer framework for the user. They can use a mru | |
109 | container without hearing about Boost.MultiIndex at all. And B.MI users | |
110 | will get some of their common containers already implemented with an STL | |
111 | friendly interface in other libraries. And as you stated this is more extensible | |
112 | because opens the door to use other libraries in bimap and mru families | |
113 | than just Boost.MultiIndex without compromising the more general boost | |
114 | framework. The word "misc" it is going to disappear from the | |
115 | code and the documentation of bimap and mru. From now on the only use for | |
116 | it will be to identify our SoC project. I am thinking in a name for the | |
117 | bimap library. What about Boost.BidirectionalMap? Ideas? </em></span> | |
118 | </p></blockquote></div> | |
119 | <p> | |
120 | <span class="bold"><strong>Joaquin</strong></span> | |
121 | </p> | |
122 | <div class="blockquote"><blockquote class="blockquote"><p> | |
123 | <span class="emphasis"><em> Yes, Boost.Bimap. In my opinion, bimap is a well known name | |
124 | in the Boost and even in the C++ community. It sounds and is short. Why | |
125 | not to vindicate yourself as the owner of this name? </em></span> | |
126 | </p></blockquote></div> | |
127 | <p> | |
128 | <code class="literal">- Then after a week of work -</code> | |
129 | </p> | |
130 | <p> | |
131 | <span class="bold"><strong>Matias</strong></span> | |
132 | </p> | |
133 | <div class="blockquote"><blockquote class="blockquote"><p> | |
134 | <span class="emphasis"><em> Now that Boost.Bimap is getting some shape, I see that as you | |
135 | have told me, we must offer a "one_to_many_map" and a "multi_bimap" | |
136 | as part of the library. The framework I am actually working allowed to | |
137 | construct this kind of bidirectional maps and it is easy to understand | |
138 | from the user side. </em></span> | |
139 | </p></blockquote></div> | |
140 | <p> | |
141 | <span class="bold"><strong>Joaquin</strong></span> | |
142 | </p> | |
143 | <div class="blockquote"><blockquote class="blockquote"><p> | |
144 | <span class="emphasis"><em> OK, I am glad we agree on this point. </em></span> | |
145 | </p></blockquote></div> | |
146 | <p> | |
147 | <span class="bold"><strong>Matias</strong></span> | |
148 | </p> | |
149 | <div class="blockquote"><blockquote class="blockquote"><p> | |
150 | <span class="emphasis"><em> With respect to the symmetry of the key access names, I have | |
151 | to agree that there is not much a difference between the following ones: | |
152 | </em></span> | |
153 | </p></blockquote></div> | |
154 | <div class="blockquote"><blockquote class="blockquote"><p> | |
155 | <span class="emphasis"><em>- to - from</em></span> | |
156 | </p></blockquote></div> | |
157 | <div class="blockquote"><blockquote class="blockquote"><p> | |
158 | <span class="emphasis"><em>- to - b</em></span> | |
159 | </p></blockquote></div> | |
160 | <div class="blockquote"><blockquote class="blockquote"><p> | |
161 | <span class="emphasis"><em>- 0 - 1</em></span> | |
162 | </p></blockquote></div> | |
163 | <div class="blockquote"><blockquote class="blockquote"><p> | |
164 | <span class="emphasis"><em>- left - right</em></span> | |
165 | </p></blockquote></div> | |
166 | <div class="blockquote"><blockquote class="blockquote"><p> | |
167 | <span class="emphasis"><em> In my opinion it is a matter of taste, but left/right sounds | |
168 | more symmetrical than the others. </em></span> | |
169 | </p></blockquote></div> | |
170 | <p> | |
171 | <span class="bold"><strong>Joaquin</strong></span> | |
172 | </p> | |
173 | <div class="blockquote"><blockquote class="blockquote"><p> | |
174 | <span class="emphasis"><em> I like very much the left/right notation, it is very simple | |
175 | to remember and it is a lot more symmetrical than to/from. </em></span> | |
176 | </p></blockquote></div> | |
177 | <p> | |
178 | <span class="bold"><strong>Matias</strong></span> | |
179 | </p> | |
180 | <div class="blockquote"><blockquote class="blockquote"><p> | |
181 | <span class="emphasis"><em> At first my idea was to obtain ease of use hiding the B.MI core, | |
182 | making it more STL-intuitive. Nevertheless I have realized that B.MI is | |
183 | a lot more coherent and easy to use that I had imagined. This makes me | |
184 | think again in the problem. In the design that I am coding now, bimap | |
185 | <span class="bold"><strong>is-a</strong></span> multi_index_container specializes | |
186 | with a data type very comfortable called bipair, that can be seen like | |
187 | any of the two maps that integrates it using map views. This scheme has | |
188 | great benefits for users: </em></span> | |
189 | </p></blockquote></div> | |
190 | <div class="blockquote"><blockquote class="blockquote"><p> | |
191 | <span class="emphasis"><em> - If the user already knows B.MI, he can take advantage of the | |
192 | tools that it provides and that are not present in the STL containers. | |
193 | In addition, in some cases the use to indices to see the data can be very | |
194 | useful. </em></span> | |
195 | </p></blockquote></div> | |
196 | <div class="blockquote"><blockquote class="blockquote"><p> | |
197 | <span class="emphasis"><em> - If the user does not know anything about B.MI but have an | |
198 | STL framework, the learning curve is reduced to understand the bimap instantiation | |
199 | and how a is obtained the desired map view. </em></span> | |
200 | </p></blockquote></div> | |
201 | <div class="blockquote"><blockquote class="blockquote"><p> | |
202 | <span class="emphasis"><em> Another very important benefit holds: All the algorithms done | |
203 | for B.MI continues to work with Boost.Bimap and if B.MI continues growing, | |
204 | bimap grow automatically. </em></span> | |
205 | </p></blockquote></div> | |
206 | <p> | |
207 | <span class="bold"><strong>Joaquin</strong></span> | |
208 | </p> | |
209 | <div class="blockquote"><blockquote class="blockquote"><p> | |
210 | <span class="emphasis"><em> Umm... This is an interesting design decision, but controversial | |
211 | in my opinion. Basically you decide to expose the implementation of bimap; | |
212 | that has advantages, as you stated, but also a nonsmall disadvantage: once | |
213 | <span class="bold"><strong>you have documented</strong></span> the implementation, | |
214 | it is not possible to change it anymore. It is a marriage with B.MI without | |
215 | the chance of divorce. The other possibility, to hide the implementation | |
216 | and to duplicate and document the provided functionality, explicitly or | |
217 | implicitly due to the same characteristics of the implementation, is of | |
218 | course heavier to maintain, but it gives a degree of freedom to change | |
219 | the guts of your software if you need to. Do not take this like a frontal | |
220 | objection, but I think that it is quite important design decision, not | |
221 | only in the context of bimap but in general. </em></span> | |
222 | </p></blockquote></div> | |
223 | <p> | |
224 | <span class="bold"><strong>Matias</strong></span> | |
225 | </p> | |
226 | <div class="blockquote"><blockquote class="blockquote"><p> | |
227 | <span class="emphasis"><em> You are quite right here. I think we have to choose the hardest | |
228 | path and hide the B.MI core from the user. I am sending you the first draft | |
229 | of bimap along with some documentation. </em></span> | |
230 | </p></blockquote></div> | |
231 | <p> | |
232 | <code class="literal">- This completes the second week, the documentation was basically | |
233 | the first section of this rationale -</code> | |
234 | </p> | |
235 | <p> | |
236 | <span class="bold"><strong>Joaquin</strong></span> | |
237 | </p> | |
238 | <div class="blockquote"><blockquote class="blockquote"><p> | |
239 | <span class="emphasis"><em> I must confess that I am beginning to like what I see. I am | |
240 | mathematical by vocation, and when I see symmetry in a formulation I believe | |
241 | that it is in the right track. </em></span> | |
242 | </p></blockquote></div> | |
243 | <p> | |
244 | <span class="bold"><strong>Matias</strong></span> | |
245 | </p> | |
246 | <div class="blockquote"><blockquote class="blockquote"><p> | |
247 | <span class="emphasis"><em> We are two mathematicians by vocation then. </em></span> | |
248 | </p></blockquote></div> | |
249 | <p> | |
250 | <span class="bold"><strong>Joaquin</strong></span> | |
251 | </p> | |
252 | <div class="blockquote"><blockquote class="blockquote"><p> | |
253 | <span class="emphasis"><em> I think that the part of std::set theory is very clear. To me, | |
254 | it turns out to me somewhat strange to consider the rank of a map (values | |
255 | X) like a std::set, but of course the formulation is consistent. </em></span> | |
256 | </p></blockquote></div> | |
257 | <p> | |
258 | <span class="bold"><strong>Matias</strong></span> | |
259 | </p> | |
260 | <div class="blockquote"><blockquote class="blockquote"><p> | |
261 | <span class="emphasis"><em> I like it very much, it can be a little odd at first, but now | |
262 | that I have get used to it, it is very easy to express in the code my contrains | |
263 | on the data, and I believe that if somebody reads the code and sees the | |
264 | bimap instantiation he is not going to have problems understanding it. | |
265 | Perhaps it is easier to understand it if we use your notation: ordered_nonunique, | |
266 | unordered_unique, but this goes against our STL facade. In my opinion the | |
267 | user that comes from STL must have to learn as less as possible. </em></span> | |
268 | </p></blockquote></div> | |
269 | <p> | |
270 | <span class="bold"><strong>Joaquin</strong></span> | |
271 | </p> | |
272 | <div class="blockquote"><blockquote class="blockquote"><p> | |
273 | <span class="emphasis"><em> Considering a relation like a <code class="computeroutput"><span class="keyword">struct</span> | |
274 | <span class="special">{</span><span class="identifier">left</span><span class="special">,</span> <span class="identifier">right</span><span class="special">}</span></code> is clean and clear. If I understand it | |
275 | well, one relation has views of type <code class="computeroutput"><span class="identifier">pair</span><span class="special">{</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">second</span><span class="special">}</span></code>, is this correct? </em></span> | |
276 | </p></blockquote></div> | |
277 | <p> | |
278 | <span class="bold"><strong>Matias</strong></span> | |
279 | </p> | |
280 | <div class="blockquote"><blockquote class="blockquote"><p> | |
281 | <span class="emphasis"><em> Yes, I believe that the left/right notation to express symmetry | |
282 | is great. I believe that to people is going to love it. </em></span> | |
283 | </p></blockquote></div> | |
284 | <p> | |
285 | <span class="bold"><strong>Joaquin</strong></span> | |
286 | </p> | |
287 | <div class="blockquote"><blockquote class="blockquote"><p> | |
288 | <span class="emphasis"><em> OK, perfect. I likes this very much: </em></span> | |
289 | </p></blockquote></div> | |
290 | <div class="blockquote"><blockquote class="blockquote"><p> | |
291 | <span class="emphasis"><em>- bm.left is compatible with std::map<A,B></em></span> | |
292 | </p></blockquote></div> | |
293 | <div class="blockquote"><blockquote class="blockquote"><p> | |
294 | <span class="emphasis"><em>- bm.right is compatible with std::map<B,A></em></span> | |
295 | </p></blockquote></div> | |
296 | <div class="blockquote"><blockquote class="blockquote"><p> | |
297 | <span class="emphasis"><em>- bm is compatible with std::set<relation<A,B>></em></span> | |
298 | </p></blockquote></div> | |
299 | <div class="blockquote"><blockquote class="blockquote"><p> | |
300 | <span class="emphasis"><em> It is elegant and symmetric. I feel good vibrations here. </em></span> | |
301 | </p></blockquote></div> | |
302 | <p> | |
303 | <span class="bold"><strong>Matias</strong></span> | |
304 | </p> | |
305 | <div class="blockquote"><blockquote class="blockquote"><p> | |
306 | <span class="emphasis"><em> Great! </em></span> | |
307 | </p></blockquote></div> | |
308 | <p> | |
309 | <span class="bold"><strong>Joaquin</strong></span> | |
310 | </p> | |
311 | <div class="blockquote"><blockquote class="blockquote"><p> | |
312 | <span class="emphasis"><em> Moving on, the support for N-1, N-N, and hashed index is very | |
313 | easy to grasp, and it fits well in framework. However I do not finish to | |
314 | understand very well the "set<relation> constraints" section. | |
315 | Will you came up with some examples of which is the meaning of the different | |
316 | cases that you enumerate? </em></span> | |
317 | </p></blockquote></div> | |
318 | <p> | |
319 | <span class="bold"><strong>Matias - </strong></span> | |
320 | </p> | |
321 | <div class="blockquote"><blockquote class="blockquote"><p> | |
322 | <span class="emphasis"><em> Yes, I mean: </em></span> | |
323 | </p></blockquote></div> | |
324 | <div class="blockquote"><blockquote class="blockquote"><p> | |
325 | <span class="emphasis"><em>- based on the left</em></span> | |
326 | </p></blockquote></div> | |
327 | <div class="blockquote"><blockquote class="blockquote"><p> | |
328 | <span class="emphasis"><em>- based on the right</em></span> | |
329 | </p></blockquote></div> | |
330 | <div class="blockquote"><blockquote class="blockquote"><p> | |
331 | <span class="emphasis"><em> The bimap core must be based on some index of multi index. If | |
332 | the index of the left is of the type hash, then in fact the main view is | |
333 | going to be an unordered_set< relation<A,B> >. Perhaps this | |
334 | is not what the user prefers and he wants to base its main view on the | |
335 | right index. </em></span> | |
336 | </p></blockquote></div> | |
337 | <div class="blockquote"><blockquote class="blockquote"><p> | |
338 | <span class="emphasis"><em>- set_of_relation </em></span> | |
339 | </p></blockquote></div> | |
340 | <div class="blockquote"><blockquote class="blockquote"><p> | |
341 | <span class="emphasis"><em>- multiset_of_relation </em></span> | |
342 | </p></blockquote></div> | |
343 | <div class="blockquote"><blockquote class="blockquote"><p> | |
344 | <span class="emphasis"><em>- unordered_set_of_relation </em></span> | |
345 | </p></blockquote></div> | |
346 | <div class="blockquote"><blockquote class="blockquote"><p> | |
347 | <span class="emphasis"><em>- unordered_multiset_of_relation </em></span> | |
348 | </p></blockquote></div> | |
349 | <div class="blockquote"><blockquote class="blockquote"><p> | |
350 | <span class="emphasis"><em> However, if both of them are hash indexes, the user may want | |
351 | the main view to be ordered. As we have a B.MI core this is very easy to | |
352 | support, we just have to add another index to it. </em></span> | |
353 | </p></blockquote></div> | |
354 | <p> | |
355 | <span class="bold"><strong>Joaquin</strong></span> | |
356 | </p> | |
357 | <div class="blockquote"><blockquote class="blockquote"><p> | |
358 | <span class="emphasis"><em> I understand it now. OK, I do not know if we have to include | |
359 | this in the first version, is going to be a functionality avalanche! </em></span> | |
360 | </p></blockquote></div> | |
361 | <p> | |
362 | <span class="bold"><strong>Matias</strong></span> | |
363 | </p> | |
364 | <div class="blockquote"><blockquote class="blockquote"><p> | |
365 | <span class="emphasis"><em> The user is not affected by the addition of this functionality, | |
366 | because by default it will be based on the left index that is a very natural | |
367 | behaviour. I do not think that this is functionality bloat, but I agree | |
368 | with you that it is a functionality avalanche. </em></span> | |
369 | </p></blockquote></div> | |
370 | <p> | |
371 | <span class="bold"><strong>Joaquin</strong></span> | |
372 | </p> | |
373 | <div class="blockquote"><blockquote class="blockquote"><p> | |
374 | <span class="emphasis"><em> There are restrictions between the left and right set types | |
375 | and the possible main view set types. For example if some of the index | |
376 | is of unique type, then the main view cannot be of type multiset_of_relation. | |
377 | To the inverse one, if the main view is of type set_of_relation the left | |
378 | and the right index cannot be of type multi_set. All this subject of the | |
379 | unicity constrictions and the resulting interactions between indexes is | |
380 | one of the subtle subjects of B.MI. </em></span> | |
381 | </p></blockquote></div> | |
382 | <p> | |
383 | <span class="bold"><strong>Matias</strong></span> | |
384 | </p> | |
385 | <div class="blockquote"><blockquote class="blockquote"><p> | |
386 | <span class="emphasis"><em> This can be checked at compile time and informed as an error | |
387 | in compile time. </em></span> | |
388 | </p></blockquote></div> | |
389 | <p> | |
390 | <span class="bold"><strong>Joaquin</strong></span> | |
391 | </p> | |
392 | <div class="blockquote"><blockquote class="blockquote"><p> | |
393 | <span class="emphasis"><em> It can be interesting. </em></span> | |
394 | </p></blockquote></div> | |
395 | <p> | |
396 | <code class="literal">- And right when everything seems to be perfect... - </code> | |
397 | </p> | |
398 | <p> | |
399 | <span class="bold"><strong>Joaquin</strong></span> | |
400 | </p> | |
401 | <div class="blockquote"><blockquote class="blockquote"><p> | |
402 | <span class="emphasis"><em> I have some worse news with respect to mutant, it is very a | |
403 | well designed and manageable class, unfortunately, C++ does not guarantee | |
404 | layout-compatibility almost in any case. For example, the C++ standard | |
405 | does not guarantee that the classes <code class="computeroutput"><span class="keyword">struct</span><span class="special">{</span><span class="identifier">T1</span> <span class="identifier">a</span><span class="special">;</span> <span class="identifier">T2</span> | |
406 | <span class="identifier">b</span><span class="special">;}</span></code> | |
407 | and <code class="computeroutput"><span class="keyword">struct</span><span class="special">{</span><span class="identifier">T1</span> <span class="identifier">b</span><span class="special">;</span> <span class="identifier">T2</span> <span class="identifier">a</span><span class="special">;}</span></code> are | |
408 | layout-compatible, and therefore the trick of reinterpret_cast is an undefined | |
409 | behavior. I am with you in which that in the 100% of the cases this scheme | |
410 | will really work, but the standard is the standard. If you can look the | |
411 | layout-compatibility subject in it (http://www.kuzbass.ru/docs/isocpp/). | |
412 | As you see, sometimes the standard is cruel. Although mutant seems a lost | |
413 | case, please do not hurry to eliminate it. We will see what can be done | |
414 | for it. </em></span> | |
415 | </p></blockquote></div> | |
416 | <p> | |
417 | <span class="bold"><strong>Matias</strong></span> | |
418 | </p> | |
419 | <div class="blockquote"><blockquote class="blockquote"><p> | |
420 | <span class="emphasis"><em> I read the standard, and you were right about it. Mutant was | |
421 | an implementation detail. It is a pity because I am sure that it will work | |
422 | perfect in any compiler. Perhaps the standard becomes more strict some | |
423 | day and mutant returns to life... We can then try a wrapper around a relation<A,B> | |
424 | that have two references named first and second that bind to A and B, or | |
425 | B and A. </em></span> | |
426 | </p></blockquote></div> | |
427 | <p> | |
428 | </p> | |
429 | <pre class="programlisting"><span class="identifier">relation</span><span class="special"><</span><span class="identifier">TA</span><span class="special">,</span><span class="identifier">TB</span><span class="special">></span> <span class="identifier">r</span><span class="special">;</span> | |
430 | <span class="identifier">const_reference_pair</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">B</span><span class="special">></span> <span class="identifier">pba</span><span class="special">(</span><span class="identifier">r</span><span class="special">);</span> | |
431 | <span class="identifier">const_reference_pair</span><span class="special"><</span><span class="identifier">B</span><span class="special">,</span><span class="identifier">A</span><span class="special">></span> <span class="identifier">pbb</span><span class="special">(</span><span class="identifier">r</span><span class="special">);</span> | |
432 | </pre> | |
433 | <p> | |
434 | </p> | |
435 | <div class="blockquote"><blockquote class="blockquote"><p> | |
436 | <span class="emphasis"><em> It is not difficult to code the relation class in this way but | |
437 | two references are initialized with every access and the use of <code class="computeroutput"><span class="identifier">pba</span><span class="special">.</span><span class="identifier">first</span></code> will be slower than <code class="computeroutput"><span class="identifier">r</span><span class="special">.</span><span class="identifier">left</span></code> | |
438 | in most compilers. It is very difficult to optimize this kind of references. | |
439 | </em></span> | |
440 | </p></blockquote></div> | |
441 | <p> | |
442 | <span class="bold"><strong>Joaquin</strong></span> | |
443 | </p> | |
444 | <div class="blockquote"><blockquote class="blockquote"><p> | |
445 | <span class="emphasis"><em> This workaround is not possible, due to technical problems with | |
446 | the expected behavior of the iterators. If the iterators of bm.left are | |
447 | of bidirectional type, then standard stated that it have to return an object | |
448 | of type const value_type& when dereferenced. You will have to return | |
449 | a const_reference_pair created in the flight, making it impossible to return | |
450 | a reference. </em></span> | |
451 | </p></blockquote></div> | |
452 | <p> | |
453 | <span class="bold"><strong>Matias</strong></span> | |
454 | </p> | |
455 | <div class="blockquote"><blockquote class="blockquote"><p> | |
456 | <span class="emphasis"><em> I understand... I have workaround for that also but surely the | |
457 | standard will attack me again! We must manage to create the class relation | |
458 | that responds as we want, the rest of the code will flow from this point. | |
459 | This clear separation between the relation class and the rest of the library, | |
460 | is going to help to us to separate the problems and to attack them better. | |
461 | </em></span> | |
462 | </p></blockquote></div> | |
463 | <p> | |
464 | <span class="bold"><strong>Joaquin</strong></span> | |
465 | </p> | |
466 | <div class="blockquote"><blockquote class="blockquote"><p> | |
467 | <span class="emphasis"><em> What workaround? It already pricks my curiosity,I have dedicated | |
468 | a long time to the subject and I do not find any solution except that we | |
469 | allow the relation class to occupy more memory. </em></span> | |
470 | </p></blockquote></div> | |
471 | <p> | |
472 | <span class="bold"><strong>Matias</strong></span> | |
473 | </p> | |
474 | <div class="blockquote"><blockquote class="blockquote"><p> | |
475 | <span class="emphasis"><em> We must achieve that the relation<A,B> size equals the | |
476 | pair<A,B> size if we want this library to be really useful. I was | |
477 | going to write my workaround and I realized that It does not work. Look | |
478 | at this: http://www.boost.org/libs/iterator/doc/new-iter-concepts.html | |
479 | Basically the problem that we are dealing is solved if we based our iterators | |
480 | on this proposal. The present standard forces that the bidirectional iterators | |
481 | also are of the type input and output. Using the new concepts there is | |
482 | no inconvenient in making our iterators "Readable Writable Swappable | |
483 | Bidirectional Traversal". Therefore the const_reference_pair returns | |
484 | to be valid. </em></span> | |
485 | </p></blockquote></div> | |
486 | <p> | |
487 | <span class="bold"><strong>Joaquin</strong></span> | |
488 | </p> | |
489 | <div class="blockquote"><blockquote class="blockquote"><p> | |
490 | <span class="emphasis"><em> It is correct in the sense that you simply say that your iterators | |
491 | are less powerful than those of the std::map. It is not that it is wrong, | |
492 | simply that instead of fixing the problem, you confess it. </em></span> | |
493 | </p></blockquote></div> | |
494 | <p> | |
495 | <span class="bold"><strong>Matias</strong></span> | |
496 | </p> | |
497 | <div class="blockquote"><blockquote class="blockquote"><p> | |
498 | <span class="emphasis"><em> OK, but in our particular case; What are the benefits of offering | |
499 | a LValue iterator against a Read Write iterator? It does not seem to me | |
500 | that it is less powerful in this case. </em></span> | |
501 | </p></blockquote></div> | |
502 | <p> | |
503 | <span class="bold"><strong>Joaquin</strong></span> | |
504 | </p> | |
505 | <div class="blockquote"><blockquote class="blockquote"><p> | |
506 | <span class="emphasis"><em> The main problem with a ReadWrite is that the following thing: | |
507 | <code class="computeroutput"><span class="identifier">value_type</span> <span class="special">*</span> | |
508 | <span class="identifier">p</span><span class="special">=&(*</span><span class="identifier">it</span><span class="special">);</span></code> | |
509 | fails or stores a transitory direction in p. Is this important in the real | |
510 | life? I do not know. How frequently you store the direction of the elements | |
511 | of a map? Perhaps it is not very frequent, since the logical thing is to | |
512 | store the iterators instead of the directions of the elements. Let us review | |
513 | our options: </em></span> | |
514 | </p></blockquote></div> | |
515 | <div class="blockquote"><blockquote class="blockquote"><p> | |
516 | <span class="emphasis"><em> 1. We used mutant knowing that is not standard, but of course | |
517 | it is supported in the 100% of the cases. </em></span> | |
518 | </p></blockquote></div> | |
519 | <div class="blockquote"><blockquote class="blockquote"><p> | |
520 | <span class="emphasis"><em> 2. We used const_reference_pair and we declared the iterators | |
521 | not LValue. </em></span> | |
522 | </p></blockquote></div> | |
523 | <div class="blockquote"><blockquote class="blockquote"><p> | |
524 | <span class="emphasis"><em> 3. We found some trick that still we do not know. I have thus | |
525 | been playing with unions and things, without much luck. </em></span> | |
526 | </p></blockquote></div> | |
527 | <div class="blockquote"><blockquote class="blockquote"><p> | |
528 | <span class="emphasis"><em> 4. We leverage the restriction that views have to support the | |
529 | first, second notation. If we made this decision, there are several possibilities: | |
530 | </em></span> | |
531 | </p></blockquote></div> | |
532 | <div class="blockquote"><blockquote class="blockquote"><p> | |
533 | <span class="emphasis"><em> a. The left map has standard semantics first/second while the | |
534 | right map has the inverse semantics. </em></span> | |
535 | </p></blockquote></div> | |
536 | <div class="blockquote"><blockquote class="blockquote"><p> | |
537 | <span class="emphasis"><em> b. Instead of first and second we provide first() and second(), | |
538 | with which the problem is trivial. </em></span> | |
539 | </p></blockquote></div> | |
540 | <div class="blockquote"><blockquote class="blockquote"><p> | |
541 | <span class="emphasis"><em> c. The map view do not support first/second but left/right as | |
542 | the father relation </em></span> | |
543 | </p></blockquote></div> | |
544 | <div class="blockquote"><blockquote class="blockquote"><p> | |
545 | <span class="emphasis"><em> 5. We solve the problem using more memory than sizeof(pair<A,B>). | |
546 | </em></span> | |
547 | </p></blockquote></div> | |
548 | <div class="blockquote"><blockquote class="blockquote"><p> | |
549 | <span class="emphasis"><em> In any case, I would say that the only really unacceptable option | |
550 | is the last one. </em></span> | |
551 | </p></blockquote></div> | |
552 | <p> | |
553 | <span class="bold"><strong>Matias</strong></span> | |
554 | </p> | |
555 | <div class="blockquote"><blockquote class="blockquote"><p> | |
556 | <span class="emphasis"><em> Lets see. </em></span> | |
557 | </p></blockquote></div> | |
558 | <div class="blockquote"><blockquote class="blockquote"><p> | |
559 | <span class="emphasis"><em> 1. I want the "standard compliant" label in the library. | |
560 | </em></span> | |
561 | </p></blockquote></div> | |
562 | <div class="blockquote"><blockquote class="blockquote"><p> | |
563 | <span class="emphasis"><em> 2. This is the natural choice, but knowing that there is another | |
564 | option that always works and it is more efficient is awful. </em></span> | |
565 | </p></blockquote></div> | |
566 | <div class="blockquote"><blockquote class="blockquote"><p> | |
567 | <span class="emphasis"><em> 3. I have also tried to play with unions, the problem is that | |
568 | the union members must be POD types. </em></span> | |
569 | </p></blockquote></div> | |
570 | <div class="blockquote"><blockquote class="blockquote"><p> | |
571 | <span class="emphasis"><em> 4. This option implies a big lost to the library. </em></span> | |
572 | </p></blockquote></div> | |
573 | <div class="blockquote"><blockquote class="blockquote"><p> | |
574 | <span class="emphasis"><em> 5. Totally agree. </em></span> | |
575 | </p></blockquote></div> | |
576 | <div class="blockquote"><blockquote class="blockquote"><p> | |
577 | <span class="emphasis"><em> I want to add another option to this list. Using metaprogramming, | |
578 | the relation class checks if the compiler supports the mutant idiom. If | |
579 | it supports it then it uses it and obtains zero overhead plus LValue iterators, | |
580 | but if it do not supports it then uses const_reference_pair and obtains | |
581 | minimum overhead with ReadWrite iterators. This might be controversial | |
582 | but the advantages that mutant offers are very big and the truth is that | |
583 | I do not believe that in any actual compiler this idiom is not supported. | |
584 | This scheme would adjust perfectly to the present standard since we are | |
585 | not supposing anything. The only drawback here is that although the mutant | |
586 | approach allows to make LValue iterators we have to degrade they to Read | |
587 | Write in both cases, because we want that the same code can be compiled | |
588 | in any standard compliant compiler. </em></span> | |
589 | </p></blockquote></div> | |
590 | <p> | |
591 | <code class="literal">- Hopefully we find our way out of the problem -</code> | |
592 | </p> | |
593 | <p> | |
594 | <span class="bold"><strong>Joaquin</strong></span> | |
595 | </p> | |
596 | <div class="blockquote"><blockquote class="blockquote"><p> | |
597 | <span class="emphasis"><em> Changing the subject, I believe that the general concept of | |
598 | hooking data is good, but I do not like the way you implement it. It has | |
599 | to be easy to migrate to B.MI to anticipate the case in that Boost.Bimap | |
600 | becomes insufficient. It is more natural for a B.MI user that the data | |
601 | is accessed without the indirection of <code class="computeroutput"><span class="special">.</span><span class="identifier">data</span></code>. I do not know how this can be articulated | |
602 | in your framework. </em></span> | |
603 | </p></blockquote></div> | |
604 | <p> | |
605 | <span class="bold"><strong>Matias</strong></span> | |
606 | </p> | |
607 | <div class="blockquote"><blockquote class="blockquote"><p> | |
608 | <span class="emphasis"><em> I have a technical problem to implement the data_hook in this | |
609 | way. If the standard would let us use the mutant idiom directly, I can | |
610 | implement it using multiple inheritance. But as we must use const_reference_pair | |
611 | too, It becomes impossible for me to support it. We have three options | |
612 | here: </em></span> | |
613 | </p></blockquote></div> | |
614 | <div class="blockquote"><blockquote class="blockquote"><p> | |
615 | <span class="emphasis"><em> 1) relation { left, right, data } and pair_view { first, second, | |
616 | data } </em></span> | |
617 | </p></blockquote></div> | |
618 | <div class="blockquote"><blockquote class="blockquote"><p> | |
619 | <span class="emphasis"><em> - This is more intuitive within the bimap framework, since it | |
620 | does not mix the data with the index, as a table in a data base does, but | |
621 | gives more importance to the index. </em></span> | |
622 | </p></blockquote></div> | |
623 | <div class="blockquote"><blockquote class="blockquote"><p> | |
624 | <span class="emphasis"><em> - It is not necessary that the user puts the mutable keyword | |
625 | in each member of the data class. </em></span> | |
626 | </p></blockquote></div> | |
627 | <div class="blockquote"><blockquote class="blockquote"><p> | |
628 | <span class="emphasis"><em> - This moves away just a little bit from B.MI because the model | |
629 | of it is similar to a table, but it continues to exist a clear path of | |
630 | migration. </em></span> | |
631 | </p></blockquote></div> | |
632 | <div class="blockquote"><blockquote class="blockquote"><p> | |
633 | <span class="emphasis"><em> 2) relation { left,right, d1,d2... dn } and pair_view { first, | |
634 | second, data } </em></span> | |
635 | </p></blockquote></div> | |
636 | <div class="blockquote"><blockquote class="blockquote"><p> | |
637 | <span class="emphasis"><em> - The path to B.MI is the one you have proposed. </em></span> | |
638 | </p></blockquote></div> | |
639 | <div class="blockquote"><blockquote class="blockquote"><p> | |
640 | <span class="emphasis"><em> - It is very asymmetric. It is necessary to explain that the | |
641 | views are handled different that the relation. </em></span> | |
642 | </p></blockquote></div> | |
643 | <div class="blockquote"><blockquote class="blockquote"><p> | |
644 | <span class="emphasis"><em> - The user must place the mutable keyboards in the data class. | |
645 | </em></span> | |
646 | </p></blockquote></div> | |
647 | <div class="blockquote"><blockquote class="blockquote"><p> | |
648 | <span class="emphasis"><em> 3) Only relation { left,right, d1,d2... dn } </em></span> | |
649 | </p></blockquote></div> | |
650 | <div class="blockquote"><blockquote class="blockquote"><p> | |
651 | <span class="emphasis"><em> - Simple migration path to B.MI. </em></span> | |
652 | </p></blockquote></div> | |
653 | <div class="blockquote"><blockquote class="blockquote"><p> | |
654 | <span class="emphasis"><em> - You are not able to access the hooked data from the views. | |
655 | </em></span> | |
656 | </p></blockquote></div> | |
657 | <div class="blockquote"><blockquote class="blockquote"><p> | |
658 | <span class="emphasis"><em> My vote goes to the first proposal. </em></span> | |
659 | </p></blockquote></div> | |
660 | <p> | |
661 | <span class="bold"><strong>Joaquin</strong></span> | |
662 | </p> | |
663 | <div class="blockquote"><blockquote class="blockquote"><p> | |
664 | <span class="emphasis"><em> Yes, the first option is the one that less surprises hold to | |
665 | the user. I also vote for 1. </em></span> | |
666 | </p></blockquote></div> | |
667 | <p> | |
668 | <code class="literal">- The third week was over -</code> | |
669 | </p> | |
670 | <p> | |
671 | <span class="bold"><strong>Matias</strong></span> | |
672 | </p> | |
673 | <div class="blockquote"><blockquote class="blockquote"><p> | |
674 | <span class="emphasis"><em> There is still one problem that I have to solve. I need to know | |
675 | if it is necessary to create a map_view associated to nothing. If it is | |
676 | necessary there are two options: that it behaves as an empty container | |
677 | or that it throws an exception or assert when trying to use it. If it is | |
678 | not necessary, the map_view is going to keep a reference instead of a pointer. | |
679 | To me, the map_view always must be viewing something. In the case of the | |
680 | iterators being able to create them empty, makes them easy to use in contexts | |
681 | that require constructors by default, like being the value_type of a container, | |
682 | but I do not believe that this is the case of map_view. </em></span> | |
683 | </p></blockquote></div> | |
684 | <p> | |
685 | <span class="bold"><strong>Joaquin</strong></span> | |
686 | </p> | |
687 | <div class="blockquote"><blockquote class="blockquote"><p> | |
688 | <span class="emphasis"><em> How would an empty map_view be useful? My intuition is like | |
689 | yours, map_view would have to be always associate to something. If we wished | |
690 | to obtain the semantics "is associated or not" we can use a pointer | |
691 | to a map_view. </em></span> | |
692 | </p></blockquote></div> | |
693 | <p> | |
694 | <span class="bold"><strong>Matias</strong></span> | |
695 | </p> | |
696 | <div class="blockquote"><blockquote class="blockquote"><p> | |
697 | <span class="emphasis"><em> OK, then you agree to that map_views stores a reference instead | |
698 | of a pointer? </em></span> | |
699 | </p></blockquote></div> | |
700 | <p> | |
701 | <span class="bold"><strong>Joaquin</strong></span> | |
702 | </p> | |
703 | <div class="blockquote"><blockquote class="blockquote"><p> | |
704 | <span class="emphasis"><em> It depends on the semantics you want to give to map_views, and | |
705 | in concrete to the copy of map_views. </em></span> | |
706 | </p></blockquote></div> | |
707 | <p> | |
708 | </p> | |
709 | <pre class="programlisting"><span class="identifier">map_view</span> <span class="identifier">x</span><span class="special">=...;</span> | |
710 | <span class="identifier">map_view</span> <span class="identifier">y</span><span class="special">=...;</span> | |
711 | <span class="identifier">x</span><span class="special">=</span><span class="identifier">y</span><span class="special">;</span> | |
712 | </pre> | |
713 | <p> | |
714 | </p> | |
715 | <div class="blockquote"><blockquote class="blockquote"><p> | |
716 | <span class="emphasis"><em> What is supposed to do this last line? </em></span> | |
717 | </p></blockquote></div> | |
718 | <div class="blockquote"><blockquote class="blockquote"><p> | |
719 | <span class="emphasis"><em> 1. Rebinding of x, that is to say, x points at the same container | |
720 | that y. </em></span> | |
721 | </p></blockquote></div> | |
722 | <div class="blockquote"><blockquote class="blockquote"><p> | |
723 | <span class="emphasis"><em> 2. Copy of the underlying container. </em></span> | |
724 | </p></blockquote></div> | |
725 | <div class="blockquote"><blockquote class="blockquote"><p> | |
726 | <span class="emphasis"><em> If you want to implement 1, you cannot use references internally. | |
727 | If you want to implement 2, it is almost the same to use a reference or | |
728 | a pointer. </em></span> | |
729 | </p></blockquote></div> | |
730 | <p> | |
731 | <span class="bold"><strong>Matias</strong></span> | |
732 | </p> | |
733 | <div class="blockquote"><blockquote class="blockquote"><p> | |
734 | <span class="emphasis"><em> If I want that they behave exactly as std::maps then I must | |
735 | go for 2. But if I think they as "views" of something, I like | |
736 | 1. The question is complicated. I add another option: </em></span> | |
737 | </p></blockquote></div> | |
738 | <div class="blockquote"><blockquote class="blockquote"><p> | |
739 | <span class="emphasis"><em> 3. Error: operator= is declare as private in boost::bimap::map_view | |
740 | std_container </em></span> | |
741 | </p></blockquote></div> | |
742 | <div class="blockquote"><blockquote class="blockquote"><p> | |
743 | <span class="emphasis"><em> Also What happens with <code class="computeroutput"><span class="identifier">std_container</span> | |
744 | <span class="special">=</span> <span class="identifier">view</span><span class="special">;</span></code>? and with <code class="computeroutput"><span class="identifier">view</span> | |
745 | <span class="special">=</span> <span class="identifier">std_container</span><span class="special">;</span></code>? </em></span> | |
746 | </p></blockquote></div> | |
747 | </div> | |
748 | <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> | |
749 | <td align="left"></td> | |
750 | <td align="right"><div class="copyright-footer">Copyright © 2006-2012 Matias Capeletto<p> | |
751 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
752 | file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) | |
753 | </p> | |
754 | </div></td> | |
755 | </tr></table> | |
756 | <hr> | |
757 | <div class="spirit-nav"> | |
758 | <a accesskey="p" href="code.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../history.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> | |
759 | </div> | |
760 | </body> | |
761 | </html> |