Boost logo

Boost :

From: Matias Capeletto (matias.capeletto_at_[hidden])
Date: 2007-05-27 12:30:40


Hello,

In Bimap and MultiIndex section of Bimap docs (
http://tinyurl.com/2wrb6k ) there is a discussion about the relation
between this two libraries.

I have a new feature in mind for Boost.Bimap but I want to know if it
is the correct path to follow.

Bidirectional relations may have associated information about the relationship.
Suppose we want to represent a books and author bidirectional map.

-----------------------------------------------------------------------------------------------

stuct author {};
struct book_name {};

typedef bimap<
       tagged< multiset_of< string >, author >,
       tagged< set_of< string >, book_name >
> bm_type;

bm_type bm;

assign::insert( bm )
  ( "Bjarne Stroustrup" , "The C++ Programming Language")
  ( "Scott Meyers" , "Effective C++" )
  ( "Andrei Alexandrescu", "Modern C++ Design by" );

std::cout << bm.by<book_name>().at( "Modern C++ Design by" );

-----------------------------------------------------------------------------------------------

Suppose now that we want to store abstract of each book. There is no
support in bimap for that. So we have two options:

1) Books name are unique identifiers, so we can create a separate
std::map< string, string > that relates books names with abstracts.

2) We can use MultiIndex for the new beast.

Option 1 is the wrong approach, we lost what bimap has won us. We now
have to maintain the logic of two interdependent containers and there is
an extra string stored for each book name. This is far away from being
a good solution.

Option 2 is correct. We start thinking books as entries in a table. So it
makes sense to start using Boost.MultiIndex. We can then add the year
of publication, the price, etc... and we can index this new items too. So
MultiIndex is a sound solution for our problem.

The thing is that there are cases where we want to maintain bimap
semantics (use at() to find an author given a book name and the other way
around) and add information about the relations that we are sure we will not
want to index later (like the abstracts). Option 1 is not possible, option 2
neither.

What I propose is to add support for information hooking to bimaps.
The information will be mutable using iterators.

The interface will be something along this line:

-----------------------------------------------------------------------------------------------

typedef bimap<
       tagged< multiset_of< string >, author >,
       tagged< set_of< string >, book_name >,

       hook_info< string >

> bm_type;

bm_type bm;

// Relations and bimap pairs constructors can take an extra argument

assign::insert( bm )

  ( "Bjarne Stroustrup" , "The C++ Programming Language",

    "For C++ old-timers, the first edition of this book is the one "
    "that started it all—the font of our knowledge." );

bm_type::map_by<book_name>::const_iterator iter =
     bm.by<book_name>.find("The C++ Programming Language")

std::cout << iter->info;

// A commodity function is included for unique maps:

std::cout << bm.by<book_name>().info_at("The C++ Programming Language");

-----------------------------------------------------------------------------------------------

I think that it is a good addition to the library, but others may think that
we should encourage the use of Boost.MultiIndex in this cases.
The thing is that there are a lot of bidirectional mappings that have
associated data, and it is a shame not to support them.

This is by no means decided. Comments are welcome.

King Regards
Matias


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk