• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/license
2
3Boost.Bimap
4
5Copyright (c) 2006-2007 Matias Capeletto
6
7Distributed under the Boost Software License, Version 1.0.
8(See accompanying file LICENSE_1_0.txt or copy at
9http://www.boost.org/LICENSE_1_0.txt)
10
11]
12
13[/ QuickBook Document version 1.4 ]
14
15[section History]
16
17[section The long path from Code Project to Boost]
18
19[variablelist
20[[2002 - bimap at Code Project]
21[
22Joaquin Lopez Muñoz posted his first
23[@https://www.codeproject.com/Articles/3016/An-STL-like-bidirectional-map#test_suite bimap library]
24in 2002. Tons of users have been using it. He then
25[@https://lists.boost.org/Archives/boost/2002/10/38123.php asked the
26list for interest] in his library in 2003. Luckily, there was a lot of
27interest and Joaquin started to boostify the code. At some point all the
28developers seemed to agree that, rather than a bidirectional map, it would
29be better to work on an N-indexed set that contained Joaquin's library as a
30particular case.
31]]
32
33[[2003 - multiindex_set]
34[
35The library grew enormously and was ready for a formal review in
362003. At this point, the container was a lot more powerful, but
37everything comes with a price and this new beast lacked the simplicity
38of the original bimap.
39]]
40
41[[2004 - indexed_set]
42[
43In 2004, the formal review ended well for the new multi-indexed
44container. This Swiss army knife introduced several new features, such
45as non-unique indexes, hashed indices and sequenced indices. In the list
46of improvements to the library, it was mentioned that a bidirectional
47map should be coded in top of this container.
48]]
49
50[[2005 - multi_index_container]
51[
52Once in Boost, the library switched to the now familiar name
53"Boost.MultiIndex". Late in 2004, it formally became a member of Boost.
54Joaquin continued to enhance the library and added new features such as
55composite keys and random-access indices.
56]]
57
58[[2006 - Multi Index Specialized Containers SoC project]
59[
60In 2006, during the formal review of Boost.Property_tree, the need
61for a bidirectional map container built on top of Boost.MultiIndex arose
62again. Boost entered the Google SoC 2006 as a mentor organization at the
63same time. Joaquin put himself forward as a mentor. He proposed to build
64not only a bidirectional map, but a myriad multi-indexed specialized
65containers. Matias Capeletto presented an application to code Boost.Misc
66for the SoC and was elected, along with nine other students. Matias's and
67Joaquin's SoC project ends with a working implementation of the bimap
68library that was presented in an informal review. By the end of the year
69the library was queued for a formal review.
70]]
71
72[[2007 - Boost.Bimap]
73[
74The formal review took place at the beginning of the year and Boost.Bimap
75was accepted in Boost.
76]]
77]
78
79[endsect]
80
81[section MultiIndex and Bimap]
82
83This is the conversation thread that began during Boost.PropertyTree formal
84review process. The review was very interesting and very deep topics were
85addressed. It is quite interesting and it is now part of this library history.
86Enjoy!
87
88
89[*Marcin]
90[:['
91The biggest virtue of property_tree is easy to use interface.
92If we try to make generic tree of it, it will be compromised.
93]]
94
95[*Gennadiy]
96[:['
97IMO the same result (as library presents) could be achieved
98just by using multi_index.
99]]
100
101[*Marcin]
102[:['
103Could you elaborate more on that? I considered use of
104multi_index to implement indexing for properties, but it only affected the
105implementation part of library, not interface, and because I already had a
106working, exception safe solution, I didn't see the reason to dump it and add
107another dependency on another library.
108]]
109
110[*Gennadiy]
111[:['
112I mean why do I need this half baked property_tree as another
113data structure? Property tree supports nothing in itself. It's just a data
114structure. You have parsers that produce property tree out of different sources.
115But you mat as well produce maps or something else. Here for example All that
116I need to do to "implement" similar functionality as your property tree:
117]]
118
119``
120// Data structure itself
121template<typename ValueType,typename KeyType>
122struct Node;
123template<typename ValueType,typename KeyType>
124struct ptree_gen {
125    typedef std::pair<KeyType,Node<ValueType,KeyType> > mi_value;
126    typedef multi_index_container<mi_value, indexed_by<...> > type;
127};
128template<typename ValueType,typename KeyType>
129struct Node {
130    ValueType v;
131    ptree_gen<ValueType,KeyType>::type children;
132};
133// serialization support
134template<class Archive,typename ValueType,typename KeyType>
135void serialize(Archive & ar, Node<ValueType,KeyType>& n,
136               const unsigned int version)
137{
138    ar & n.v;
139    ar & n.children;
140}
141// some access methods
142template<typename ValueType,typename KeyType>
143ValueType const&
144get( string const& keys, ptree_gen<ValueType,KeyType>::type const& src )
145{
146    std::pait<string,string> sk = split( keys, "." );
147    Node const& N = src.find( sk.first );
148    return sk.second.empty() ? N.v : get( sk.second, N.children );
149}
150``
151
152[:['
153Use it like this:
154]]
155
156``
157ptree_gen<string,string>::type PT;
158boost::archive::text_iarchive ia( std::ifstream ifs("filename") );
159ia >> PT;
160string value = get( "a.b.c.d", PT );
161``
162
163[:['
164Now tell me how property_tree interface is easier? And what is the value in
16550k of Code you need to implement this data structure.
166]]
167
168[*Thorsten]
169[:['
170Seriously Gennadiy, do you really see newbies writing
171the code you just did?
172]]
173
174[*Marcin]
175[:['
176What you just implemented is stripped down, bare bones version
177of property_tree that, among other things, does not allow you to produce human
178editable XML files. Now add more interface (aka get functions), add more
179archives to serialization lib, add customization, add transparent
180translation from strings to arbitrary types and vice versa. Spend some weeks
181trying to get all the corner cases right, and then some more weeks trying to
182smooth rough edges in the interface. Then write tests. Write docs. At the
183end, I believe you will not get much less code than there is in the library
184already. Maybe you get some savings by using multi_index instead of manual
185indexing.
186]]
187[:['
188The reason why ptree does not use multi index is because implementation
189existed long before I considered submitting to boost, probably before even I
190knew of multi index existence. It was working well. Later, when I was
191improving it during pre-review process, I seriously considered using
192multi-index. But I decided it is not worth throwing everything out.
193]]
194[:['
195Although ptree has large interface with many functions modifying state of
196the tree, it uses "single point of change" approach. Every insert eventually
197goes through one function, which takes care of exception safety and keeping
198index in sync with data. The same applies to erase. This function has 9
199lines of code in case of insert, and (by coincidence) also 9 in case of
200erase. By using multi index these functions would obviously be simplified,
201maybe to 4 lines each. Net gain: 10 lines of code (out of several hundred in
202ptree_implementation.hpp).
203]]
204[:['
205I'm aware that there are performance gains to be reaped as well, but at that
206time I was rather focusing on getting the interface right.
207]]
208
209[*Dave]
210[:['
211That's perfectly reasonable, but (through no fault of yours)
212it misses the point I was trying to make.  I guess I should have said,
213"...that demonstrates it to be the best implementation."
214]]
215[:['
216All I'm saying is that the extent to which a Boost library
217implementation should leverage other Boost libraries is not a question
218that can always be decided based on following simple guidelines, and
219that if this library is accepted, it's worth revisiting your decision.
220]]
221
222[*Thorsten]
223[:['
224I think it is important to focus on the interface in
225the review, but I also see several benefits of an implementation that builds on
226Boost.MultiIndex:'
227]]
228[:['- fewer bugs like the one Joaquin found]]
229[:['- better space efficiency]]
230[:['- exception-safety guarantees are immediately full-filled (I haven't
231looked, but I suspect that there are several bugs in this area)]]
232
233[*Daniel]
234[:['
235Multi_index supports everything a bimap would, but its
236interface is more cumbersome. I for one won't use a W3DOM-like library
237if we get one, but I would happily use property_tree. I've also only
238used multi_index once, and that was to use it as a bidirectional map.
239Property_tree covers other areas as well as being a potential subset of
240an XML library, but I still hold there is value in such a subset.
241]]
242
243[*Boris]
244[:['
245I haven't used program_options yet. But if I understand
246correctly both libraries seem to support storing and accessing data with
247strings that might describe some kind of hierarchy. This seems to be the core
248idea of both libraries - is this correct?
249]]
250[:['
251Then it wouldn't matter much what container is used. However a generic tree
252which can store data hierarchically probably makes most sense. If I
253understand correctly both libraries could make use of such a class?
254]]
255
256[*Marcin]
257[:['
258I think generic tree container is material for another library.
259Whether property_tree should be based on it or not is a matter of internal
260implementation, and generally of little interest to users. The biggest value
261of property_tree is in its easy to use interface, that should not be
262compromised, if at all possible. I have been already reassured in this view
263by quite many people who took their time to review the library.
264]]
265
266[*Boris]
267[:['
268I was trying to see the big picture: I rather prefer a C++
269standard based on a few well-known concepts like containers, iterators,
270algorithms etc. instead of having a C++ standard with hundreds of components
271which are tailored for specific needs, collaborate with only a handful of other
272components and think they provide an easy-to-use interface while all the
273easy-to-use interfaces make the whole standard less easy-to-use.
274]]
275[:['
276That said I have used your property tree library myself to read and write a
277configuration file. It was indeed very easy to use. However it would have
278been even easier if it was something I had known before like eg. an
279iterator. For now I will definitely use your property tree library but would
280appreciate if existing concepts were reused many C++ developers are familiar
281with. My opinion is that your library should be a part of Boost but should
282be more generalized in the future.
283]]
284
285[*Thorsten]
286[:['
287Well, I think we need both. Boost.MultiIndex is a great
288library and can do all kinds of wonderful things. But I would still like to see
289a bidirectional map (boost::bimap) written as a wrapper around it to
290get an easy and specialized interface.
291]]
292
293[*Pavel]
294[:['
295Bimap is available in libs/multi-index/examples/bimap.cpp.
296]]
297
298[*Thorsten]
299[:['
300Right, but the real value comes when somebody designs a nice
301STL-like interface and write docs etc, at least that was my point.
302]]
303
304[*Dave]
305[:['
306IMO Thorsten is exactly right.  This is precisely the sort of
307thing that could be added to the library as part of its ongoing maintenance
308and development (without review, of course).
309]]
310
311[*Joaquin]
312[:['
313Thorsten, we have talked about this privately in the past,
314but I feel like bringing it to the list in the hope of getting the attention
315of potential contributors:
316]]
317[:['
318There are some data structures buildable with B.MI which are regarded as
319particularly useful or common, like for instance the bidirectional map or
320bimap. A lean and mean implementation is provided in the aforementioned
321example, but certainly a much carefully crafted interface can be provided
322keeping B.MI as the implementation core: operator\[\], selection of
3231-1/1-N/N-1/N-N variants, hashing/ordering, etc.
324]]
325[:['
326I'm afraid I don't have the time to pursue this, as the current roadmap for
327core features of B.MI is taking all the spare time I can dedicate to the
328library. For this reason, I would love to see some volunteer jumping in who
329can develop this and other singular containers using B.MI (a cache container
330comes to mind) and then propose the results here either as a stand alone
331library of as part of B.MI --I'd prefer the former so as to keep the size
332of B.MI bounded.
333]]
334[:['
335If there's such a volunteer I can provide her with some help/mentoring. I also
336wonder whether this is a task suitable to be proposed for Google Summer of
337Code.
338]]
339
340[*Thorsten]
341[:['
342I think it would be good for SOC. All the really hard things
343are taken care of by B.MI, and so it seems reasonable for a student to be able
344to fill in the details.
345]]
346
347[*Dave]
348[:['
349Great!
350]]
351
352[*Jeff]
353[:['
354Please write a proposal!
355]]
356
357[*Joaquin]
358[:['
359I've just done so:
360]]
361
362[blurb *Specialized containers with Boost.MultiIndex*
363
364    *Introduction*
365
366    Boost.MultiIndex allows the construction of complex data structures involving
367    two or more indexing mechanisms on the same set of elements. Out of the
368    unlimited range of possible data structures specifiable within
369    Boost.MultiIndex, some particular configurations arise recurrently:
370
371    *a.* A bidirectional map or bimap is a container of elements of type pair<T,Q>
372    where fast look up is provided both for the T and the Q field,
373    in contrast with a regular STL map which only allows for fast look up on T.
374
375    *b.* An MRU (most recently used) list keeps the n last referenced elements:
376    when a new item is inserted and the list has reached its maximum length, the
377    oldest element is erased, whereas if an insertion is tried of a preexistence
378    element, this gets promoted to the first position. MRU lists can be used to
379    implement dynamic caches and the kind of behavior exhibited by programs
380    featuring a "Recent files" menu command, for instance.
381
382    Although Boost.MultiIndex provides the mechanisms to build these common structures,
383    the resulting interface can be cumbersome and too general in comparison with
384    specialized containers focusing on such particular structures.
385
386    *Goal*
387
388    To write a library of specialized containers like the ones described above, using
389    Boost.MultiIndex as the implementation core. Besides bimap and MRU list, the student
390    can also propose other specialized containers of interest in the community. It is
391    expected that the library meets the standards of quality required by Boost for an
392    eventual inclusion in this project, which implies a strong emphasis on interface
393    design, documentation and unit testing; the mentor will be guiding the student
394    through the complete cycle from specification and requirements gathering to
395    documentation and actual coding. The final result of the project must then contain:
396
397    *a.* Source code following
398    [@http://boost.org/more/lib_guide.htm#Guidelines Boost programming guidelines].
399
400    *b.* User documentation. Requirements on the format are loose, though the
401    [@http://www.boost.org/tools/quickbook/ QuickBook] format is
402    gaining acceptance within Boost.
403
404    *c.* Complete set of unit tests powered by
405    [@http://www.boost.org/boost-build2/ Boost Build System V2].
406
407    *Requirements*
408
409    *a.* Intermediate-to-high level in C++, with emphasis in generic programming
410    (templates).
411
412    *b.* Knowledge of the STL framework and design principles. Of course, knowledge
413    of Boost in general and Boost.MultiIndex in particular is a big plus.
414
415    *c.* Acquaintance with at least two different C++ programming environments.
416
417    *d.* Some fluency in the English language; subsequent reviews of the documentation
418    can help smooth rough edges here, though.
419
420    *e.* A mathematical inclination and previous exposure to a formal Algorithms course
421    would help very much.
422
423    *f.* A craving for extreme quality work.
424
425    *Benefits for the student*
426
427    The student taking on this project will have the opportunity to learn the complete
428    process of software production inside a highly regarded C++ open source institution,
429    and even see her work included in Boost eventually. The completion of the project
430    involves non-trivial problems in C++ interface design and so-called modern C++
431    programming, high quality user documentation and unit testing. The student will
432    also learn, perhaps to her surprise, that most of the time will be spent gathering
433    and trying ideas and, in general, thinking, rather than writing actual code.
434]
435
436[*Matias]
437[:['
438I am planning to submit an application to SoC. I will love to make real
439the specialized containers you mention and try to include some useful others.
440]]
441
442[:[^
443And then... after long hours of coding (and fun) this library saw the light.
444]]
445
446[:__BOOST_BIMAP_LOGO__]
447
448[endsect]
449
450[endsect]
451