Вместо того, чтобы писать петли, стандартный алгоритм std::трансформ
может быть использован для заполнения интервальных контейнеров из std контейнеров определенных пользовательских объектов. Нам нужна функция, которая отображает пользователь определенный объект в сегментный тип интервальной карты или интервальный тип интервального набора. На основе этого мы можем использовать std::трансформ
с icl::inserter
или icl::adder
для преобразования пользовательских объектов в интервальные контейнеры.
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/icl/split_interval_map.hpp>
#include <boost/icl/separate_interval_set.hpp>
using namespace std;
using namespace boost;
using namespace boost::icl;
class MyObject
{
public:
MyObject(){}
MyObject(int from, int to, int value): _from(from), _to(to), _value(value){}
int from()const {return _from;}
int to()const {return _to;}
int value()const{return _value;}
private:
int _from;
int _to;
int _value;
};
pair<discrete_interval<int>, int> to_segment(const MyObject& myObj)
{
return std::pair< discrete_interval<int>, int >
(discrete_interval<int>::closed(myObj.from(), myObj.to()), myObj.value());
}
discrete_interval<int> to_interval(const MyObject& myObj)
{
return discrete_interval<int>::closed(myObj.from(), myObj.to());
}
vector<MyObject> make_objects()
{
vector<MyObject> object_vec;
object_vec.push_back(MyObject(2,3,1));
object_vec.push_back(MyObject(4,4,1));
object_vec.push_back(MyObject(1,2,1));
return object_vec;
}
void show_objects(const vector<MyObject>& objects)
{
vector<MyObject>::const_iterator iter = objects.begin();
while(iter != objects.end())
{
cout << "([" << iter->from() << "," << iter->to() << "],"
<< iter->value() << ")";
++iter;
}
}
void std_transform()
{
split_interval_map<int,int> segmap;
vector<MyObject> myObjects = make_objects();
cout << "input sequence: "; show_objects(myObjects); cout << "\n\n";
std::transform(myObjects.begin(), myObjects.end(),
icl::inserter(segmap, segmap.end()),
to_segment);
cout << "icl::inserting: " << segmap << endl;
segmap.clear();
std::transform(myObjects.begin(), myObjects.end(),
icl::adder(segmap, segmap.end()),
to_segment);
cout << "icl::adding : " << segmap << "\n\n";
separate_interval_set<int> segset;
std::transform(myObjects.begin(), myObjects.end(),
icl::adder (segset, segset.end()),
to_interval);
cout << "Using std::transform to fill a separate_interval_set:\n\n";
cout << "icl::adding : " << segset << "\n\n";
}
int main()
{
cout << ">> Interval Container Library: Example std_transform.cpp <<\n";
cout << "------------------------------------------------------------\n";
cout << "Using std::transform to fill a split_interval_map:\n\n";
std_transform();
return 0;
}
Чтобы получить четкое представление о разном поведении интервальных контейнеров в примере, вы можете обратиться к разделу о интервале сочетающих стилей, который использует одни и те же данные.