Boost logo

Boost :

From: Matias Capeletto (matias.capeletto_at_[hidden])
Date: 2007-05-27 11:32:02


Hello,

Change the way operator[] works for map views.
Both John and Thorsten agree that operator[] was implemented in a rather
convoluted way. First a const version of the operator was provided going
against the standard. This version present the semantics of the new C++0x
function for maps:

  /* T& at(const key_type& x);
   * const T& at(const key_type& x) const;
   *
   * Returns: A reference to the element whose key is
   * equivalent to x, if such an element is present in the map.
   *
   * Throws: out_of_range if no such element is present.
   */

Thorsten advice was to add the const version to map and remove the
non-standard conforming const version of operator[]. This was changed in the
library.
The non-const version was very complicated because it has to return a proxy
in order to be modified. The only operation the proxy would allow was to used
operator=(data). The rationale was to support the common coding style for
maps:

    bimap<int,string> bm;

    bm.left[1] = "one";
    bm.left[2] = "two";
    bm.left[3] = "three";

    assert( bm.right["two"] == 2 );

When at() was included the last line has to be coded like

    assert( bm.right.at("two") == 2;

So the only reason for non const version of operator[] where the first lines

    bm.left[1] = "one";

  This line expands to:

    if (1,_) is not in the bimap
        try to insert (1,"one")
    else
        try to replace (1,_) with (1,"one")

    if (1,"one") was not inserted
        throw duplicate_value

The rationale was to respect the standard library and throw an exception
if that was impossible.
This function will be removed for the moment. It can be reintroduce later
with out problems.
The user can also write a helper free function to obtain the same functionality

    template< class BimapView >
    void force_insertion(BimapView& b,const typename BimapView::value_type& d)
    {
        typename BimapView::iterator iter = b.find(d.first);
        if( ! ( iter == b.end() ? view.insert(d).second : view.replace(d) ) )
        {
            ::boost::throw_exception( std::exception() );
        }
    }

  And then use it like

    force_insertion( bm.left, bm_type::left_value_type(1,"one") );

There are some bimaps that allow to provide operator[] and non const version
of at() conforming to the standard. This happens when the data type of the
map view is mutable. For example in bimap< int, list_of<double> >.
In these cases this two function are provided.

Summarizing:

removed --- const data & operator[](const key &) const
removed --- proxy & operator[](const key &)

added --- const data & at(const key &) const

added(*) --- data & at(const key &)
added(*) --- data & operator[](const key &)

(*) Enable if the data_type of the map view is mutable

What do you think of this change?

Best Regards
Matias


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