150 lines
5.0 KiB
C++
150 lines
5.0 KiB
C++
/*-----------------------------------------------------------------------------+
|
|
Interval Container Library
|
|
Author: Joachim Faulhaber
|
|
Copyright (c) 2007-2009: Joachim Faulhaber
|
|
Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
|
|
+------------------------------------------------------------------------------+
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file LICENCE.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
+-----------------------------------------------------------------------------*/
|
|
/** Example std_transform.cpp \file std_transform.cpp
|
|
\brief Fill interval containers from user defined objects using std::transform.
|
|
|
|
Example std_transform shows how algorithm std::transform can be used to
|
|
fill interval containers from std::containers of objects of a user
|
|
defined class.
|
|
|
|
\include std_transform_/std_transform.cpp
|
|
*/
|
|
//[example_std_transform
|
|
#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;
|
|
|
|
// Suppose we are working with a class called MyObject, containing some
|
|
// information about interval bounds e.g. _from, _to and some data members
|
|
// that carry associated information like e.g. _value.
|
|
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;
|
|
};
|
|
|
|
// ... in order to use the std::transform algorithm to fill
|
|
// interval maps with MyObject data we need a function
|
|
// 'to_segment' that maps an object of type MyObject into
|
|
// the value type to the interval map we want to tranform to ...
|
|
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());
|
|
}
|
|
|
|
// ... there may be another function that returns the interval
|
|
// of an object only
|
|
discrete_interval<int> to_interval(const MyObject& myObj)
|
|
{
|
|
return discrete_interval<int>::closed(myObj.from(), myObj.to());
|
|
}
|
|
|
|
|
|
// ... make_object computes a sequence of objects to test.
|
|
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;
|
|
}
|
|
|
|
// ... show_objects displays the sequence of input objects.
|
|
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()
|
|
{
|
|
// This time we want to transform objects into a splitting interval map:
|
|
split_interval_map<int,int> segmap;
|
|
vector<MyObject> myObjects = make_objects();
|
|
|
|
// Display the input
|
|
cout << "input sequence: "; show_objects(myObjects); cout << "\n\n";
|
|
|
|
// Use an icl::inserter to fill the interval map via inserts
|
|
std::transform(myObjects.begin(), myObjects.end(),
|
|
icl::inserter(segmap, segmap.end()),
|
|
to_segment);
|
|
cout << "icl::inserting: " << segmap << endl;
|
|
segmap.clear();
|
|
|
|
// In order to compute aggregation results on associated values, we
|
|
// usually want to use an icl::adder instead of an std or icl::inserter
|
|
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()),
|
|
// could be a icl::inserter(segset, segset.end()), here: same effect
|
|
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;
|
|
}
|
|
|
|
// Program output:
|
|
/*----------------------------------------------------------
|
|
>> Interval Container Library: Example std_transform.cpp <<
|
|
------------------------------------------------------------
|
|
Using std::transform to fill a split_interval_map:
|
|
|
|
input sequence: ([2,3],1)([4,4],1)([1,2],1)
|
|
|
|
icl::inserting: {([1,2)->1)([2,3]->1)([4,4]->1)}
|
|
icl::adding : {([1,2)->1)([2,2]->2)((2,3]->1)([4,4]->1)}
|
|
|
|
Using std::transform to fill a separate_interval_set:
|
|
|
|
icl::adding : {[1,3][4,4]}
|
|
----------------------------------------------------------*/
|
|
//]
|
|
|