[bimap] How to erase a single association in a many-to-many bimap?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[bimap] How to erase a single association in a many-to-many bimap?

Vicente Botet
Hi,

I have a bimap

typedef bimap<
     multiset_of<  tagged< Person*,                     consultant> >,
     multiset_of<  tagged< Company*,                 client> >,
     with_info<    tagged< ConsultancyContract*, contract> >
 > Consultancy;

initialized as follows

   Consultancy consultancy;
   Person John("John"), Jane("Jane");
   Company Dell("Dell"), HP("HP");
   ConsultancyContract JohnContractD(10,1);
   ConsultancyContract JaneContractD(20, 2);
   ConsultancyContract JaneContractH(30, 3);

   consultancy.insert(Consultancy::value_type(&Jane, &Dell,
&JaneContractD));
   consultancy.insert(Consultancy::value_type(&Jane, &HP, &JaneContractH));

and I want to remove only the specific association Jane<->Dell and so
I'm using

   consultancy.erase(Consultancy::value_type(&Jane, &Dell));

but then the resulting consultancy bimap is empty, while I expect the
association Jane<->HP to be there yet.

If I add before erasing
   consultancy.insert(Consultancy::value_type(&John, &Dell,
&JohnContractD));

and then
   consultancy.erase(Consultancy::value_type(&Jane, &Dell));

all the associations concerning Jane are removed.

What I'm doing wrong? How to erase a single association?

Best,
Vicente
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [bimap] How to erase a single association in a many-to-many bimap?

Vicente Botet
Le 15/05/12 12:09, Vicente J. Botet Escriba a écrit :
Hi,

I have a bimap

typedef bimap<
    multiset_of<  tagged< Person*,                     consultant> >,
    multiset_of<  tagged< Company*,                 client> >,
    with_info<    tagged< ConsultancyContract*, contract> >
> Consultancy;

initialized as follows

  Consultancy consultancy;
  Person John("John"), Jane("Jane");
  Company Dell("Dell"), HP("HP");
  ConsultancyContract JohnContractD(10,1);
  ConsultancyContract JaneContractD(20, 2);
  ConsultancyContract JaneContractH(30, 3);

  consultancy.insert(Consultancy::value_type(&Jane, &Dell, &JaneContractD));
  consultancy.insert(Consultancy::value_type(&Jane, &HP, &JaneContractH));

and I want to remove only the specific association Jane<->Dell and so I'm using

  consultancy.erase(Consultancy::value_type(&Jane, &Dell));

but then the resulting consultancy bimap is empty, while I expect the association Jane<->HP to be there yet.

If I add before erasing
  consultancy.insert(Consultancy::value_type(&John, &Dell, &JohnContractD));

and then
  consultancy.erase(Consultancy::value_type(&Jane, &Dell));

all the associations concerning Jane are removed.

What I'm doing wrong? How to erase a single association?

I have reached to get what I was locking for.

I have added  set_of_relation<> to the bimap definition

typedef bimap<
    multiset_of<  tagged< Person*,                     consultant> >,
    multiset_of<  tagged< Company*,                 client> >,
    with_info<    tagged< ConsultancyContract*, contract> > ,
    multiset_of_relation<>
> Consultancy;

Is there another way when the collection of relation is the default left_based?
I find the default behavior a little bit surprising. Why provide a erase function requesting the value_type if only the left side is taken in account?

What is the rationale to have the default left_based? Space optimization?

It works also with multiset_of_relation. I don't see a use case for this. When the user could want the same association to be several times? Could some one give me an example?

Best,
Vicente


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [bimap] How to erase a single association in a many-to-many bimap?

Matias Capeletto
Hi Vicente,

On Tue, May 15, 2012 at 12:43 PM, Vicente J. Botet Escriba
<[hidden email]> wrote:

> Le 15/05/12 12:09, Vicente J. Botet Escriba a écrit :
>> I have a bimap
>>
>> typedef bimap<
>>     multiset_of<  tagged< Person*,                     consultant> >,
>>     multiset_of<  tagged< Company*,                 client> >,
>>     with_info<    tagged< ConsultancyContract*, contract> >
>> > Consultancy;
>>
>> initialized as follows
>>
>>   Consultancy consultancy;
>>   Person John("John"), Jane("Jane");
>>   Company Dell("Dell"), HP("HP");
>>   ConsultancyContract JohnContractD(10,1);
>>   ConsultancyContract JaneContractD(20, 2);
>>   ConsultancyContract JaneContractH(30, 3);
>>
>>   consultancy.insert(Consultancy::value_type(&Jane, &Dell, &JaneContractD));
>>   consultancy.insert(Consultancy::value_type(&Jane, &HP, &JaneContractH));
>>
>> and I want to remove only the specific association Jane<->Dell and so I'm
>> using
>>
>>   consultancy.erase(Consultancy::value_type(&Jane, &Dell));
>>
>> but then the resulting consultancy bimap is empty, while I expect the
>> association Jane<->HP to be there yet.

> I have reached to get what I was locking for.
>
> I have added  set_of_relation<> to the bimap definition

Yes, exactly this.

> Is there another way when the collection of relation is the default
> left_based?

No, but you could write your own function to erase them.

> I find the default behavior a little bit surprising. Why provide a erase
> function requesting the value_type if only the left side is taken in
> account?

I understand that is a little bit surprising, but it is exactly the
same that will happen if you use and std::set<relation> with a custom
Compare functor that compares left keys. In a left based set of
relations, the relations are indexed by the left key and the equality
is defined ignoring completely the right one.

> What is the rationale to have the default left_based? Space optimization?

It is not only space optimization, but also performance. When you do
not use the default, the internal Boost.MultiIndex ends up having
three indexes instead of two.
Maybe we should have set the default to unconstrained_set_of_relation.
In that case, you will be forced to use the left or right view always.
I think that we are a little bit to late in the game for that.

> It works also with multiset_of_relation. I don't see a use case for this.
> When the user could want the same association to be several times? Could
> some one give me an example?

If you do not want to pay the extra cost of the third index, while
being able to access the relations from above as a set of (left,right)
values. So you can write code like the one you posted, where you
directly use insert on the bimap instead of the views. I think the set
abstraction over your data is useful. The only important thing to have
in mind is that you are dealing with a set<relation> with the compare
functor looking only the left key. Insertion, ordering, deletion will
behave the same as in the left view. Again... using
unconstrained_set_of_relation was the other option for the default,
and I agree it is a very arguable choice.

Best regards
Matias
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users