| /*-----------------------------------------------------------------------------+ |
| 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]} |
| ----------------------------------------------------------*/ |
| //] |
| |