1 /*-----------------------------------------------------------------------------+
2 Interval Container Library
3 Author: Joachim Faulhaber
4 Copyright (c) 2007-2009: Joachim Faulhaber
5 Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
6 +------------------------------------------------------------------------------+
7 Distributed under the Boost Software License, Version 1.0.
8 (See accompanying file LICENCE.txt or copy at
9 http://www.boost.org/LICENSE_1_0.txt)
10 +-----------------------------------------------------------------------------*/
11 /** Example std_transform.cpp \file std_transform.cpp
12 \brief Fill interval containers from user defined objects using std::transform.
13
14 Example std_transform shows how algorithm std::transform can be used to
15 fill interval containers from std::containers of objects of a user
16 defined class.
17
18 \include std_transform_/std_transform.cpp
19 */
20 //[example_std_transform
21 #include <iostream>
22 #include <vector>
23 #include <algorithm>
24 #include <boost/icl/split_interval_map.hpp>
25 #include <boost/icl/separate_interval_set.hpp>
26
27 using namespace std;
28 using namespace boost;
29 using namespace boost::icl;
30
31 // Suppose we are working with a class called MyObject, containing some
32 // information about interval bounds e.g. _from, _to and some data members
33 // that carry associated information like e.g. _value.
34 class MyObject
35 {
36 public:
MyObject()37 MyObject(){}
MyObject(int from,int to,int value)38 MyObject(int from, int to, int value): _from(from), _to(to), _value(value){}
from() const39 int from()const {return _from;}
to() const40 int to()const {return _to;}
value() const41 int value()const{return _value;}
42 private:
43 int _from;
44 int _to;
45 int _value;
46 };
47
48 // ... in order to use the std::transform algorithm to fill
49 // interval maps with MyObject data we need a function
50 // 'to_segment' that maps an object of type MyObject into
51 // the value type to the interval map we want to tranform to ...
to_segment(const MyObject & myObj)52 pair<discrete_interval<int>, int> to_segment(const MyObject& myObj)
53 {
54 return std::pair< discrete_interval<int>, int >
55 (discrete_interval<int>::closed(myObj.from(), myObj.to()), myObj.value());
56 }
57
58 // ... there may be another function that returns the interval
59 // of an object only
to_interval(const MyObject & myObj)60 discrete_interval<int> to_interval(const MyObject& myObj)
61 {
62 return discrete_interval<int>::closed(myObj.from(), myObj.to());
63 }
64
65
66 // ... make_object computes a sequence of objects to test.
make_objects()67 vector<MyObject> make_objects()
68 {
69 vector<MyObject> object_vec;
70 object_vec.push_back(MyObject(2,3,1));
71 object_vec.push_back(MyObject(4,4,1));
72 object_vec.push_back(MyObject(1,2,1));
73 return object_vec;
74 }
75
76 // ... show_objects displays the sequence of input objects.
show_objects(const vector<MyObject> & objects)77 void show_objects(const vector<MyObject>& objects)
78 {
79 vector<MyObject>::const_iterator iter = objects.begin();
80 while(iter != objects.end())
81 {
82 cout << "([" << iter->from() << "," << iter->to() << "],"
83 << iter->value() << ")";
84 ++iter;
85 }
86 }
87
88
std_transform()89 void std_transform()
90 {
91 // This time we want to transform objects into a splitting interval map:
92 split_interval_map<int,int> segmap;
93 vector<MyObject> myObjects = make_objects();
94
95 // Display the input
96 cout << "input sequence: "; show_objects(myObjects); cout << "\n\n";
97
98 // Use an icl::inserter to fill the interval map via inserts
99 std::transform(myObjects.begin(), myObjects.end(),
100 icl::inserter(segmap, segmap.end()),
101 to_segment);
102 cout << "icl::inserting: " << segmap << endl;
103 segmap.clear();
104
105 // In order to compute aggregation results on associated values, we
106 // usually want to use an icl::adder instead of an std or icl::inserter
107 std::transform(myObjects.begin(), myObjects.end(),
108 icl::adder(segmap, segmap.end()),
109 to_segment);
110 cout << "icl::adding : " << segmap << "\n\n";
111
112 separate_interval_set<int> segset;
113 std::transform(myObjects.begin(), myObjects.end(),
114 icl::adder (segset, segset.end()),
115 // could be a icl::inserter(segset, segset.end()), here: same effect
116 to_interval);
117
118 cout << "Using std::transform to fill a separate_interval_set:\n\n";
119 cout << "icl::adding : " << segset << "\n\n";
120 }
121
122
main()123 int main()
124 {
125 cout << ">> Interval Container Library: Example std_transform.cpp <<\n";
126 cout << "------------------------------------------------------------\n";
127 cout << "Using std::transform to fill a split_interval_map:\n\n";
128
129 std_transform();
130 return 0;
131 }
132
133 // Program output:
134 /*----------------------------------------------------------
135 >> Interval Container Library: Example std_transform.cpp <<
136 ------------------------------------------------------------
137 Using std::transform to fill a split_interval_map:
138
139 input sequence: ([2,3],1)([4,4],1)([1,2],1)
140
141 icl::inserting: {([1,2)->1)([2,3]->1)([4,4]->1)}
142 icl::adding : {([1,2)->1)([2,2]->2)((2,3]->1)([4,4]->1)}
143
144 Using std::transform to fill a separate_interval_set:
145
146 icl::adding : {[1,3][4,4]}
147 ----------------------------------------------------------*/
148 //]
149
150