| Home | Libraries | People | FAQ | More

### Std copy

The standard algorithm `std::copy` can be used to fill interval containers from standard containers of intervals or interval value pairs (segments). Because intervals do not represent elements but sets, that can be empty or contain more than one element, the usage of `std::copy` differs from what we are familiar with using containers of elements.

- Use `icl::inserter` from `#include <boost/icl/iterator.hpp>` instead of `std::inserter` to call insertions on the target interval container.
- As shown in the examples above and below this point, most of the time we will not be interested to `insert` segments into `interval_maps` but to add them, in order to generate the desired aggregation results. You can use `std::copy` with an `icl::adder` instead of an `icl::inserter` to achieve this.

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

    using namespace std;
    using namespace boost;
    using namespace boost::icl;

    // 'make_segments' returns a vector of interval value pairs, which
    // are not sorted. The values are taken from the minimal example
    // in section 'interval combining styles'.
    vector<pair<discrete_interval<int>, int> > make_segments()
    {
        vector<pair<discrete_interval<int>, int> > segment_vec;
        segment_vec.push_back(make_pair(discrete_interval<int>::right_open(2,4), 1));
        segment_vec.push_back(make_pair(discrete_interval<int>::right_open(4,5), 1));
        segment_vec.push_back(make_pair(discrete_interval<int>::right_open(1,3), 1));
        return segment_vec;
    }

    // 'show_segments' displays the source segements.
    void show_segments(const vector<pair<discrete_interval<int>, int> >& segments)
    {
        vector<pair<discrete_interval<int>, int> >::const_iterator iter = segments.begin();
        while(iter != segments.end())
        {
            cout << "(" << iter->first << "," << iter->second << ")";
            ++iter;
        }
    }

    void std_copy()
    {
        // So we have some segments stored in an std container.
        vector<pair<discrete_interval<int>, int> > segments = make_segments();
        // Display the input
        cout << "input sequence: "; show_segments(segments); cout << "\n\n";

        // We are going to 'std::copy' those segments into an interval_map:
        interval_map<int,int> segmap;

        // Use an 'icl::inserter' from <boost/icl/iterator.hpp> to call
        // insertion on the interval container.
        std::copy(segments.begin(), segments.end(),
                  icl::inserter(segmap, segmap.end()));
        cout << "icl::inserting: " << segmap << endl;
        segmap.clear();

        // When we are feeding data into interval_maps, most of the time we are
        // intending to compute an aggregation result. So we are not interested
        // the std::insert semantincs but the aggregating icl::addition semantics.
        // To achieve this there is an icl::add_iterator and an icl::adder function
        // provided in <boost/icl/iterator.hpp>.
        std::copy(segments.begin(), segments.end(),
                  icl::adder(segmap, segmap.end())); //Aggregating associated values
        cout << "icl::adding   : " << segmap << endl;

        // In this last case, the semantics of 'std::copy' transforms to the
        // generalized addition operation, that is implemented by operator
        // += or + on itl maps and sets.
    }

    int main()
    {
        cout << ">>    Interval Container Library: Example std_copy.cpp    <<\n";
        cout << "-----------------------------------------------------------\n";
        cout << "Using std::copy to fill an interval_map:\n\n";

        std_copy();
        return 0;
    }

    // Program output:
    /*---------------------------------------------------------
    >>    Interval Container Library: Example std_copy.cpp    <<
    -----------------------------------------------------------
    Using std::copy to fill an interval_map:

    input sequence: ([2,4),1)([4,5),1)([1,3),1)

    icl::inserting: {([1,5)->1)}
    icl::adding   : {([1,2)->1)([2,3)->2)([3,5)->1)}
    ---------------------------------------------------------*/