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