std_transform.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. Example std_transform shows how algorithm std::transform can be used to
  14. fill interval containers from std::containers of objects of a user
  15. defined class.
  16. \include std_transform_/std_transform.cpp
  17. */
  18. //[example_std_transform
  19. #include <iostream>
  20. #include <vector>
  21. #include <algorithm>
  22. #include <boost/icl/split_interval_map.hpp>
  23. #include <boost/icl/separate_interval_set.hpp>
  24. using namespace std;
  25. using namespace boost;
  26. using namespace boost::icl;
  27. // Suppose we are working with a class called MyObject, containing some
  28. // information about interval bounds e.g. _from, _to and some data members
  29. // that carry associated information like e.g. _value.
  30. class MyObject
  31. {
  32. public:
  33. MyObject(){}
  34. MyObject(int from, int to, int value): _from(from), _to(to), _value(value){}
  35. int from()const {return _from;}
  36. int to()const {return _to;}
  37. int value()const{return _value;}
  38. private:
  39. int _from;
  40. int _to;
  41. int _value;
  42. };
  43. // ... in order to use the std::transform algorithm to fill
  44. // interval maps with MyObject data we need a function
  45. // 'to_segment' that maps an object of type MyObject into
  46. // the value type to the interval map we want to tranform to ...
  47. pair<discrete_interval<int>, int> to_segment(const MyObject& myObj)
  48. {
  49. return std::pair< discrete_interval<int>, int >
  50. (discrete_interval<int>::closed(myObj.from(), myObj.to()), myObj.value());
  51. }
  52. // ... there may be another function that returns the interval
  53. // of an object only
  54. discrete_interval<int> to_interval(const MyObject& myObj)
  55. {
  56. return discrete_interval<int>::closed(myObj.from(), myObj.to());
  57. }
  58. // ... make_object computes a sequence of objects to test.
  59. vector<MyObject> make_objects()
  60. {
  61. vector<MyObject> object_vec;
  62. object_vec.push_back(MyObject(2,3,1));
  63. object_vec.push_back(MyObject(4,4,1));
  64. object_vec.push_back(MyObject(1,2,1));
  65. return object_vec;
  66. }
  67. // ... show_objects displays the sequence of input objects.
  68. void show_objects(const vector<MyObject>& objects)
  69. {
  70. vector<MyObject>::const_iterator iter = objects.begin();
  71. while(iter != objects.end())
  72. {
  73. cout << "([" << iter->from() << "," << iter->to() << "],"
  74. << iter->value() << ")";
  75. ++iter;
  76. }
  77. }
  78. void std_transform()
  79. {
  80. // This time we want to transform objects into a splitting interval map:
  81. split_interval_map<int,int> segmap;
  82. vector<MyObject> myObjects = make_objects();
  83. // Display the input
  84. cout << "input sequence: "; show_objects(myObjects); cout << "\n\n";
  85. // Use an icl::inserter to fill the interval map via inserts
  86. std::transform(myObjects.begin(), myObjects.end(),
  87. icl::inserter(segmap, segmap.end()),
  88. to_segment);
  89. cout << "icl::inserting: " << segmap << endl;
  90. segmap.clear();
  91. // In order to compute aggregation results on associated values, we
  92. // usually want to use an icl::adder instead of an std or icl::inserter
  93. std::transform(myObjects.begin(), myObjects.end(),
  94. icl::adder(segmap, segmap.end()),
  95. to_segment);
  96. cout << "icl::adding : " << segmap << "\n\n";
  97. separate_interval_set<int> segset;
  98. std::transform(myObjects.begin(), myObjects.end(),
  99. icl::adder (segset, segset.end()),
  100. // could be a icl::inserter(segset, segset.end()), here: same effect
  101. to_interval);
  102. cout << "Using std::transform to fill a separate_interval_set:\n\n";
  103. cout << "icl::adding : " << segset << "\n\n";
  104. }
  105. int main()
  106. {
  107. cout << ">> Interval Container Library: Example std_transform.cpp <<\n";
  108. cout << "------------------------------------------------------------\n";
  109. cout << "Using std::transform to fill a split_interval_map:\n\n";
  110. std_transform();
  111. return 0;
  112. }
  113. // Program output:
  114. /*----------------------------------------------------------
  115. >> Interval Container Library: Example std_transform.cpp <<
  116. ------------------------------------------------------------
  117. Using std::transform to fill a split_interval_map:
  118. input sequence: ([2,3],1)([4,4],1)([1,2],1)
  119. icl::inserting: {([1,2)->1)([2,3]->1)([4,4]->1)}
  120. icl::adding : {([1,2)->1)([2,2]->2)((2,3]->1)([4,4]->1)}
  121. Using std::transform to fill a separate_interval_set:
  122. icl::adding : {[1,3][4,4]}
  123. ----------------------------------------------------------*/
  124. //]