1[/ 2 Copyright (c) 2008-2010 Joachim Faulhaber 3 4 Distributed under the Boost Software License, Version 1.0. 5 (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt) 7] 8 9[section Examples] 10 11[section Overview] 12 13[table Overview over Icl Examples 14 [[level] [example] [classes] [features]] 15 [[intro][[link boost_icl.examples.party Party]] 16 [__itv_map__][Generates an attendance history of a party 17 by inserting into an __itv_map__. 18 Demonstrating 19 ['*aggregate on overlap*].]] 20 [[basic] [[link boost_icl.examples.interval Interval]] 21 [__dc_itv__, __ct_itv__ ] [Intervals for discrete and continuous instance types. 22 Closed and open interval borders.]] 23 [[basic] [[link boost_icl.examples.dynamic_interval Dynamic intervals]] 24 [__dc_itv__, __ct_itv__, __itv__ ] [Intervals with dynamic interval bounds as library default.]] 25 [[basic] [[link boost_icl.examples.static_interval Static intervals]] 26 [__ro_itv__, __itv__ ] [Intervals with static interval bounds and changing the library default.]] 27 [[basic] [[link boost_icl.examples.interval_container Interval container]] 28 [__itv_set__,\n__sep_itv_set__,\n__spl_itv_set__,\n__spl_itv_map__,\n__itv_map__] 29 [Basic characteristics of interval containers.]] 30 [[basic] [[link boost_icl.examples.overlap_counter Overlap counter]] 31 [__itv_map__][The most simple application of an interval map: 32 Counting the overlaps of added intervals.]] 33 [[advanced][[link boost_icl.examples.partys_height_average Party's height average]] 34 [__itv_map__][Using /aggregate on overlap/ a history of height averages of party guests is computed. 35 Associated values are user defined class objects, that implement 36 an appropriate `operator +=` for the aggregation.]] 37 [[advanced][[link boost_icl.examples.partys_tallest_guests Party's tallest guests]] 38 [__itv_map__,\n__spl_itv_map__] 39 [Using /aggregate on overlap/ the heights of the party's tallest guests are computed. 40 Associated values are aggregated via a maximum functor, that can 41 be chosen as template parameter of an interval_map class template.]] 42 [[advanced][[link boost_icl.examples.time_grids Time grids for months and weeks]] 43 [__spl_itv_set__] 44 [Shows how the ['*border preserving*] 45 __spl_itv_set__ can be used to create time partitions where different 46 periodic time intervals overlay each other.]] 47 [[advanced][[link boost_icl.examples.man_power Man power]] 48 [__itv_set__,\n__itv_map__] 49 [Set style operations on __itv_sets__ and __itv_maps__ like union, difference 50 and intersection can be used to obtain calculations in a flexible way. Example 51 [*man_power] demonstrates such operations in the process of calculating the 52 available man-power of a company in a given time interval.]] 53 [[advanced][[link boost_icl.examples.user_groups User groups]][__itv_map__] 54 [Example [*user_groups] shows how interval_maps can be unified or 55 intersected to calculate desired information.]] 56 57 [[and std] [[link boost_icl.examples.std_copy Std copy]] 58 [__itv_map__][Fill interval containers using `std::copy`.]] 59 [[and std] [[link boost_icl.examples.std_transform Std transform]] 60 [__itv_map__,\n__sep_itv_set__][Fill interval containers from user defined objects using `std::transform`.]] 61 62 [[customize] [[link boost_icl.examples.custom_interval Custom interval]] 63 [__itv_tr__][Use interval containers with your own interval class types.]] 64 65] 66 67[endsect] 68 69[section Party] 70[import ../example/boost_party_/boost_party.cpp] 71 72Example *party* demonstrates the possibilities of an interval map 73(__itv_map__ or __spl_itv_map__). 74An __itv_map__ maps intervals to a given content. In this case the 75content is a set of party guests represented by their name strings. 76 77As time goes by, groups of people join the party and leave later in the evening. 78So we add a time interval and a name set to the __itv_map__ for the attendance 79of each group of people, that come together and leave together. 80On every overlap of intervals, the corresponding name sets are accumulated. At 81the points of overlap the intervals are split. The accumulation of content 82is done via an operator += that has to be implemented 83for the content parameter of the __itv_map__. 84Finally the interval_map contains the history of attendance and all points in 85time, where the group of party guests changed. 86 87Party demonstrates a principle that we call 88['*aggregate on overlap*]: 89On insertion a value associated to the interval is aggregated with those 90values in the interval_map that overlap with the inserted value. 91There are two behavioral aspects to ['*aggregate on overlap*]: a ['*decompositional 92behavior*] and an ['*accumulative behavior*]. 93 94* The ['*decompositional behavior*] splits up intervals on the /time/ /dimension/ of the 95 interval_map so that the intervals are split whenever associated values 96 change. 97 98* The ['*accumulative behavior*] accumulates associated values on every overlap of 99 an insertion for the associated values. 100 101The aggregation function is += by default. Different aggregations can 102be used, if desired. 103 104 105[example_boost_party] 106 107[caution 108 109We are introducing __itv_maps__ using an 110['interval map ['*of sets of strings*]], 111because of it's didactic advantages. The party example is 112used to give an immediate access to the basic ideas of 113interval maps and /aggregate on overlap/. 114For real world applications, an interval_map of sets is 115not necessarily recommended. 116It has the same efficiency problems as 117a `std::map` of `std::sets`. 118There is a big realm though of using 119interval_maps with numerical and other 120efficient data types for the associated values. 121] 122 123[endsect] [/ Party] 124 125 126[section Interval] 127 128Example *interval* shows some basic functionality of __itvs__. 129 130* Different instances of __itvs__ for integral ([^int, Time]) and 131 continuous types ([^double, std::string]) are used. 132 133* The examples uses open and closed intervals bounds. 134 135* Some borderline functions calls on open interval borders are tested e.g.: 136 `interval<double>::rightopen(1/sqrt(2.0), sqrt(2.0)).contains(sqrt(2.0));` 137 138[import ../example/interval_/interval.cpp] 139[example_interval] 140[endsect] 141 142[section Dynamic interval] 143[import ../example/dynamic_interval_/dynamic_interval.cpp] 144[example_dynamic_interval] 145[endsect] 146 147[section Static interval] 148[import ../example/static_interval_/static_interval.cpp] 149[example_static_interval] 150[endsect] 151 152 153[section Interval container] 154 155Example [*interval container] demonstrates the characteristic behaviors 156of different interval containers that are also summarized 157in the introductory [link boost_icl.introduction.interval_combining_styles Interval Combining Styles]. 158 159[import ../example/interval_container_/interval_container.cpp] 160[example_interval_container] 161[endsect] 162 163 164[section Overlap counter] 165 166Example [*overlap counter] provides the simplest application 167of an interval_map that maps intervals to integers. 168An interval_map<int,int> serves as an overlap counter 169if we only add interval value pairs that carry 1 as 170associated value. 171 172Doing so, the associated values that are accumulated in 173the interval_map are just the number of overlaps of all added 174intervals. 175 176[import ../example/overlap_counter_/overlap_counter.cpp] 177[example_overlap_counter] 178[endsect] 179 180 181 182[section:partys_height_average Party's height average] 183 184In the example `partys_height_average.cpp` we compute yet another aggregation: 185The average height of guests. This is done by defining a `class counted_sum` 186that sums up heights and counts the number of guests 187via an `operator +=`. 188 189Based on the `operator +=` we can aggregate counted sums on addition 190of interval value pairs into an interval_map. 191 192[import ../example/partys_height_average_/partys_height_average.cpp] 193[example_partys_height_average] 194 195Required for `class counted_sum` is a default constructor 196`counted_sum()`and 197an `operator ==` to test equality. 198To enable additive aggregation on overlap also 199an `operator +=` is needed. 200 201Note that no `operator -=` for a subtraction of `counted_sum` values 202is defined. So you can only add to the 203`interval_map<ptime, counted_sum>` 204but not subtract from it. 205 206In many real world applications only addition is needed and user 207defined classes will work fine, if they only implement 208`operator +=`. Only if any of the `operator`s `-=` or `-` 209is called on the interval_map, the user defined class has to 210implement it's own `operator -=` to provide the subtractive 211aggregation on overlap. 212 213[endsect] 214 215 216[section:partys_tallest_guests Party's tallest guests] 217 218Defining `operator +=` (and `-=`) is probably the most important 219method to implement arbitrary kinds of user defined aggregations. 220An alternative way to choose a desired aggregation is to 221instantiate an interval_map class template with an 222appropriate ['*aggregation functor*]. For the most common 223kinds of aggregation the [*icl] 224provides such functors as shown in the example. 225 226Example `partys_tallest_guests.cpp` also demonstrates 227the difference between an __itv_map__ 228that joins intervals for equal associated values and a 229__spl_itv_map__ that preserves all borders of inserted 230intervals. 231 232[import ../example/partys_tallest_guests_/partys_tallest_guests.cpp] 233[example_partys_tallest_guests] 234 235[endsect] 236 237[section:time_grids Time grids for months and weeks] 238 239A __spl_itv_set__ preserves all interval borders on insertion 240and intersection operations. So given a __spl_itv_set__ and an addition of an interval 241`` 242x = {[1, 3)} 243x.add( [2, 4)) 244`` 245then the intervals are split at their borders 246`` 247x == {[1,2)[2,3)[3,4)} 248`` 249Using this property we can intersect __spl_itv_maps__ in 250order to iterate over intervals accounting for all occurring 251changes of interval borders. 252 253In this example we provide an intersection of two __spl_itv_sets__ 254representing a month and week time grid. 255 256[import ../example/month_and_week_grid_/month_and_week_grid.cpp] 257[example_month_and_week_grid] 258[endsect] 259 260[section Man power] 261 262__Itv_sets__ and __itv_maps__ can be filled and manipulated using 263set style operations such as union `+=`, difference `-=` and 264intersection `&=`. 265 266In this example [*man power] a number of those operations are 267demonstrated in the process of calculation the available working 268times (man-power) of a company's employees accounting for weekends, 269holidays, sickness times and vacations. 270 271[import ../example/man_power_/man_power.cpp] 272[example_man_power] 273[endsect] 274 275[section User groups] 276 277Example [*user groups] shows the availability of set operations 278on __itv_maps__. 279 280In the example there is a user group `med_users` of a hospital staff 281that has the authorisation to handle medical data of patients. 282User group `admin_users` has access to administrative data like 283health insurance and financial data. 284 285The membership for each user in one of the user groups has a time 286interval of validity. The group membership begins and ends. 287 288* Using a union operation `+` we can have an overview over the unified 289 user groups and the membership dates of employees. 290 291* Computing an intersection `&` shows who is member of both med_users 292 and admin_users at what times. 293 294[import ../example/user_groups_/user_groups.cpp] 295[example_user_groups] 296[endsect] 297 298 299[section Std copy] 300 301The standard algorithm 302[@http://www.cplusplus.com/reference/algorithm/copy/ `std::copy`] 303can be used to fill interval containers 304from standard containers of intervals or 305interval value pairs (segments). Because intervals 306do not represent ['*elements*] but ['*sets*], that 307can be empty or contain more than one element, 308the usage of `std::copy` differs from what we 309are familiar with using ['containers of elements]. 310 311* Use `icl::inserter` from `#include <boost/icl/iterator.hpp>` 312 instead of `std::inserter` to call insertions on the target 313 interval container. 314 315* As shown in the examples above and below this point, most of 316 the time we will not be interested to `insert` segments 317 into __itv_maps__ but to __biLadd__ 318 them, in order to generate the desired aggregation results. 319 You can use `std::copy` with an `icl::adder` instead of an 320 `icl::inserter` to achieve this. 321 322[import ../example/std_copy_/std_copy.cpp] 323[example_std_copy] 324 325[endsect][/ Std copy] 326 327 328[section Std transform] 329 330Instead of writing loops, the standard algorithm 331[@http://www.cplusplus.com/reference/algorithm/transform/ `std::transform`] 332can be used to fill interval containers 333from std containers of user defined objects. 334We need a function, that 335maps the ['user defined object] into the 336['segement type] of an interval map or the 337['interval type] of an interval set. 338Based on that we can use `std::transform` 339with an `icl::inserter` or `icl::adder` 340to transform the user objects into interval 341containers. 342 343[import ../example/std_transform_/std_transform.cpp] 344[example_std_transform] 345 346To get clear about the different behaviors of interval containers 347in the example, you may want to refer to the section about 348[link boost_icl.introduction.interval_combining_styles interval combining styles] 349that uses the same data. 350 351[/ 352Instead of `icl::inserter` we could also use an `std::inserter` 353with algorithms `std::copy` and `std::transform`. 354This is ['*depreciated*], because `std::inserter` is designed for 355containers of elements, where ['*exacty one*] element is inserted 356via `std::inserter` if it is not already in the container. 357In contrast to that, an interval or segemnt can represent zero, one, 358or many elements of an interval container. 359 360You can use `std::inserter` *only*, if you actively take care of 361two preconditions: 362 363# None of the intervals or segements of the source containers 364 must be empty. 365 366# A segment never carries a neutral element when your target 367 interval map absorbs identities. 368 369Violating those preconditions leads to ['*undefined behavior*]. 370] 371 372[endsect][/ std::transform] 373 374 375[section Custom interval] 376 377Example *custom interval* demonstrates how to use interval 378containers with an own interval class type. 379 380[import ../example/custom_interval_/custom_interval.cpp] 381[example_custom_interval] 382[endsect][/ Custom interval] 383 384 385 386[endsect][/ examples] 387 388