the_student_and_the_mentor.html 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  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.79.1">
  7. <link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;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">
  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&lt;A,B&gt;</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&lt;B,A&gt;</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&lt;relation&lt;A,B&gt;&gt;</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&lt;relation&gt; 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&lt; relation&lt;A,B&gt; &gt;. 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&lt;A,B&gt;
  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">&lt;</span><span class="identifier">TA</span><span class="special">,</span><span class="identifier">TB</span><span class="special">&gt;</span> <span class="identifier">r</span><span class="special">;</span>
  430. <span class="identifier">const_reference_pair</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">B</span><span class="special">&gt;</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">&lt;</span><span class="identifier">B</span><span class="special">,</span><span class="identifier">A</span><span class="special">&gt;</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&amp; 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&lt;A,B&gt; size equals the
  476. pair&lt;A,B&gt; 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">=&amp;(*</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&lt;A,B&gt;).
  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 &#169; 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>