Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Why does boost::icl::interval_map::flip() just clear the map?

I am learning Boost.Icl. While scrolling through its source code, I've noticed that the flip() function simply calls clear() on the interval_map if its traits is total_absorber. According to the documentation, it is supposed to erase the interval if the map contains it or add it, otherwise. So I went to check it and with the given code:

#include <iostream>
#include <boost/icl/interval_map.hpp>

using namespace boost::icl;
using namespace std;

int main()
{
    interval_map<int, int, total_absorber> imap;

    imap += make_pair(interval<int>::right_open(1, 9), 1);

    cout << imap << endl;

    imap.flip(make_pair(interval<int>::right_open(3, 5), 1));

    cout << imap << endl;

    imap.flip(make_pair(interval<int>::right_open(10, 15), 1));

    cout << imap << endl;
}

The output really is just an empty map (even though the second flip should be a plain addition):

{([1,9)->1)}
{}
{}

If I use the default traits, it works as expected:

{([1,9)->1)}
{([1,3)->1)([5,9)->1)}
{([1,3)->1)([5,9)->1)([10,15)->1)}

I don't understand why is it different for a total_absorber. Does it logically make no sense? If so, why? Because I can manually collect a map with these ranges:

    interval_map<int, int, total_absorber> imap;

    imap += make_pair(interval<int>::right_open(1, 3), 1);
    imap += make_pair(interval<int>::right_open(5, 9), 1);
    imap += make_pair(interval<int>::right_open(10, 15), 1);

    cout << imap << endl;

Result:

{([1,3)->1)([5,9)->1)([10,15)->1)}
like image 748
Rabter Avatar asked Oct 16 '25 13:10

Rabter


1 Answers

it is supposed to erase the interval if the map contains it

Combine this with what total_absorber means:

Alternatively an icl Map can be total. It is then considered to contain a neutral value for all key values that are not stored in the map.

A "total absorber" map semantically contains all keys. So it always contains whatever interval you provide. So no matter what, the correct behavior is to erase the interval.

Furthermore, it looks like this operation is defined between maps, not between a map and an interval. That means your interval is promoted to a "total absorber" map. That is, it is not just the interval that gets looked at, but all keys. And since all keys are also in the original map, they all get erased. That is, just clear() the map and you're done.

like image 154
JaMiT Avatar answered Oct 19 '25 03:10

JaMiT



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!