1/*-----------------------------------------------------------------------------+
2Interval Container Library
3Author: Joachim Faulhaber
4Copyright (c) 2007-2009: Joachim Faulhaber
5Copyright (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 man_power.cpp \file man_power.cpp
12 \brief Using set style operators to compute with interval sets and maps.
13
14 Interval sets and maps can be filled and manipulated using
15 set style operation like union (+=), difference (-=) and intersection
16 (&=).
17
18 In this example 'man_power' a number of those operations are
19 demonstrated in the process of calculation the available working
20 times (man-power) of a company's employees accounting for weekends,
21 holidays, sickness times and vacations.
22
23 \include man_power_/man_power.cpp
24*/
25//[example_man_power
26// The next line includes <boost/gregorian/date.hpp>
27// and a few lines of adapter code.
28#include <boost/icl/gregorian.hpp>
29#include <iostream>
30#include <boost/icl/discrete_interval.hpp>
31#include <boost/icl/interval_map.hpp>
32
33using namespace std;
34using namespace boost::gregorian;
35using namespace boost::icl;
36
37
38// Function weekends returns the interval_set of weekends that are contained in
39// the date interval 'scope'
40interval_set<date> weekends(const discrete_interval<date>& scope)
41{
42 interval_set<date> weekends;
43
44 date cur_weekend_sat
45 = first(object: scope)
46 + days(days_until_weekday(d: first(object: scope), wd: greg_weekday(Saturday)))
47 - weeks(1);
48 week_iterator week_iter(cur_weekend_sat);
49
50 for(; week_iter <= last(object: scope); ++week_iter)
51 weekends += discrete_interval<date>::right_open(lo: *week_iter, up: *week_iter + days(2));
52
53 weekends &= scope; // cut off the surplus
54
55 return weekends;
56}
57
58// The available working time for the employees of a company is calculated
59// for a period of 3 months accounting for weekends and holidays.
60// The available daily working time for the employees is calculated
61// using interval_sets and interval_maps demonstrating a number of
62// addition, subtraction and intersection operations.
63void man_power()
64{
65 date someday = from_string(s: "2008-08-01");
66 date thenday = someday + months(3);
67
68 discrete_interval<date> scope = discrete_interval<date>::right_open(lo: someday, up: thenday);
69
70 // ------------------------------------------------------------------------
71 // (1) In a first step, the regular working times are computed for the
72 // company within the given scope. From all available days, the weekends
73 // and holidays have to be subtracted:
74 interval_set<date> worktime(scope);
75 // Subtract the weekends
76 worktime -= weekends(scope);
77 // Subtract holidays
78 worktime -= from_string(s: "2008-10-03"); //German reunification ;)
79
80 // company holidays (fictitious ;)
81 worktime -= discrete_interval<date>::closed(lo: from_string(s: "2008-08-18"),
82 up: from_string(s: "2008-08-22"));
83
84 //-------------------------------------------------------------------------
85 // (2) Now we calculate the individual work times for some employees
86 //-------------------------------------------------------------------------
87 // In the company works Claudia.
88 // This is the map of her regular working times:
89 interval_map<date,int> claudias_working_hours;
90
91 // Claudia is working 8 hours a day. So the next statement says
92 // that every day in the whole scope is mapped to 8 hours worktime.
93 claudias_working_hours += make_pair(x&: scope, y: 8);
94
95 // But Claudia only works 8 hours on regular working days so we do
96 // an intersection of the interval_map with the interval_set worktime:
97 claudias_working_hours &= worktime;
98
99 // Yet, in addition Claudia has her own absence times like
100 discrete_interval<date> claudias_seminar (from_string(s: "2008-09-16"),
101 from_string(s: "2008-09-24"),
102 interval_bounds::closed());
103 discrete_interval<date> claudias_vacation(from_string(s: "2008-08-01"),
104 from_string(s: "2008-08-14"),
105 interval_bounds::closed());
106
107 interval_set<date> claudias_absence_times(claudias_seminar);
108 claudias_absence_times += claudias_vacation;
109
110 // All the absence times have to subtracted from the map of her working times
111 claudias_working_hours -= claudias_absence_times;
112
113 //-------------------------------------------------------------------------
114 // Claudia's boss is Bodo. He only works part time.
115 // This is the map of his regular working times:
116 interval_map<date,int> bodos_working_hours;
117
118 // Bodo is working 4 hours a day.
119 bodos_working_hours += make_pair(x&: scope, y: 4);
120
121 // Bodo works only on regular working days
122 bodos_working_hours &= worktime;
123
124 // Bodos additional absence times
125 discrete_interval<date> bodos_flu(from_string(s: "2008-09-19"), from_string(s: "2008-09-29"),
126 interval_bounds::closed());
127 discrete_interval<date> bodos_vacation(from_string(s: "2008-08-15"), from_string(s: "2008-09-03"),
128 interval_bounds::closed());
129
130 interval_set<date> bodos_absence_times(bodos_flu);
131 bodos_absence_times += bodos_vacation;
132
133 // All the absence times have to be subtracted from the map of his working times
134 bodos_working_hours -= bodos_absence_times;
135
136 //-------------------------------------------------------------------------
137 // (3) Finally we want to calculate the available manpower of the company
138 // for the selected time scope: This is done by adding up the employees
139 // working time maps:
140 interval_map<date,int> manpower;
141 manpower += claudias_working_hours;
142 manpower += bodos_working_hours;
143
144
145 cout << first(object: scope) << " - " << last(object: scope)
146 << " available man-power:" << endl;
147 cout << "---------------------------------------------------------------\n";
148
149 for(interval_map<date,int>::iterator it = manpower.begin();
150 it != manpower.end(); it++)
151 {
152 cout << first(object: it->first) << " - " << last(object: it->first)
153 << " -> " << it->second << endl;
154 }
155}
156
157int main()
158{
159 cout << ">>Interval Container Library: Sample man_power.cpp <<\n";
160 cout << "---------------------------------------------------------------\n";
161 man_power();
162 return 0;
163}
164
165// Program output:
166/*
167>>Interval Container Library: Sample man_power.cpp <<
168---------------------------------------------------------------
1692008-Aug-01 - 2008-Oct-31 available man-power:
170---------------------------------------------------------------
1712008-Aug-01 - 2008-Aug-01 -> 4
1722008-Aug-04 - 2008-Aug-08 -> 4
1732008-Aug-11 - 2008-Aug-14 -> 4
1742008-Aug-15 - 2008-Aug-15 -> 8
1752008-Aug-25 - 2008-Aug-29 -> 8
1762008-Sep-01 - 2008-Sep-03 -> 8
1772008-Sep-04 - 2008-Sep-05 -> 12
1782008-Sep-08 - 2008-Sep-12 -> 12
1792008-Sep-15 - 2008-Sep-15 -> 12
1802008-Sep-16 - 2008-Sep-18 -> 4
1812008-Sep-25 - 2008-Sep-26 -> 8
1822008-Sep-29 - 2008-Sep-29 -> 8
1832008-Sep-30 - 2008-Oct-02 -> 12
1842008-Oct-06 - 2008-Oct-10 -> 12
1852008-Oct-13 - 2008-Oct-17 -> 12
1862008-Oct-20 - 2008-Oct-24 -> 12
1872008-Oct-27 - 2008-Oct-31 -> 12
188*/
189//]
190
191

source code of boost/libs/icl/example/man_power_/man_power.cpp