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