c++boostboost-icl

boost interval_map vs split_interval_map


I'm having difficulty understanding interval_map & split_interval_map, I implemented both & result is same. Below is the code for split interval map.

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

using namespace std;
using namespace boost::icl;


/* The most simple example of an interval_map is an overlap counter.
   If intervals are added that are associated with the value 1,
   all overlaps of added intervals are counted as a result in the
   associated values. 
*/
typedef split_interval_map<int, int> OverlapCounterT;

void print_overlaps(const OverlapCounterT& counter)
{
    for(OverlapCounterT::const_iterator it = counter.begin(); it != counter.end(); it++)
    {
        discrete_interval<int> itv  = (*it).first;
        int overlaps_count = (*it).second;
        if(overlaps_count == 1)
            cout << "in interval " << itv << " intervals do not overlap" << endl;
        else
            cout << "in interval " << itv << ": "<< overlaps_count << " intervals overlap" << endl;
    }
}

void overlap_counter()
{
    OverlapCounterT overlap_counter;
    discrete_interval<int> inter_val;

    inter_val = discrete_interval<int>::right_open(4,9);
    cout << "adding   " << inter_val << endl;
    overlap_counter += make_pair(inter_val, 1);
    print_overlaps(overlap_counter);

    inter_val = discrete_interval<int>::right_open(6,9);
    cout << "adding   " << inter_val << endl;
    overlap_counter += make_pair(inter_val, 1);
    print_overlaps(overlap_counter);


    inter_val = discrete_interval<int>::right_open(1,9);
    cout << "adding   " << inter_val << endl;
    overlap_counter += make_pair(inter_val, 1);
    print_overlaps(overlap_counter);


}

int main()
{
    cout << ">>Interval Container Library: Sample overlap_counter.cpp <<\n";
    cout << "-----------------------------------------------------------\n";
    overlap_counter();
    return 0;
}

Output is :

adding   [4,9)

in interval [4,9) intervals do not overlap

adding   [6,9)

in interval [4,6) intervals do not overlap

in interval [6,9): 2 intervals overlap

adding   [1,9)

in interval [1,4) intervals do not overlap

in interval [4,6): 2 intervals overlap

in interval [6,9): 3 intervals overlap

Similarly in above code I change split_interval_map to interval_map & output was same. Is there something i'm missing ?


Solution

  • The difference becomes apparent when you insert intervals that are immediately adjacent. The "normal" map will merge them, splitting will not (so it preserves all interval borders).

    See also the relevant docs: Combining Styles

    Sample:

    Live On Coliru

    #include <iostream>
    #include <boost/icl/split_interval_map.hpp>
    #include <boost/icl/interval_map.hpp>
    namespace icl = boost::icl;
    
    template <typename Map> void test() {
        std::cout << __PRETTY_FUNCTION__ << ":\n";
    
        Map s { { Map::interval_type::right_open(2,10), 3 } };
        std::cout << s << "\n";
    
        s.add({ {10,12}, 3 });
        std::cout << s << "\n";
    }
    
    int main()
    {
        test<icl::interval_map<int, int> >();
        test<icl::split_interval_map<int, int> >();
    }
    

    Prints

    void test() [with Map = boost::icl::interval_map<int, int>]:
    {([2,10)->3)}
    {([2,12)->3)}
    void test() [with Map = boost::icl::split_interval_map<int, int>]:
    {([2,10)->3)}
    {([2,10)->3)([10,12)->3)}