...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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.
icl::inserter
from #include
<boost/icl/iterator.hpp>
instead of std::inserter
to call insertions on the target interval container.
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)} ---------------------------------------------------------*/