eec351b2c80dc738b2a1f9af550e447ecbadea5f
[libi2ncommon] / src / timefunc.hxx
1 /*
2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
4
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
7
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
13
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
16
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
19 */
20 /** @file
21  * @brief time related functions.
22  *
23  * @copyright Copyright © 2001-2008 by Intra2net AG
24  */
25
26 #ifndef __TIMEFUNC_HXX
27 #define __TIMEFUNC_HXX
28
29 #include <errno.h>
30 #include <string>
31 #include <list>
32
33 #include <boost/optional.hpp>
34
35 #include <week.hpp>
36
37 double prec_time(void);
38
39 time_t date_to_seconds(const std::string &date);
40
41 std::string make_nice_time(int seconds);
42 std::string format_full_time(time_t seconds);
43 std::string format_date(time_t seconds);
44 void seconds_to_hour_minute(int seconds, int *hour, int *minute);
45 void split_daysec(int daysec, int *outhours=NULL, int *outminutes=NULL, int *outseconds=NULL);
46 std::string output_hour_minute(int hour, int minute, bool h_for_00=true, int seconds=0);
47
48 inline std::string output_hour_minute_from_seconds(int seconds)
49 {
50     int hour, minute;
51     split_daysec(seconds,&hour,&minute);
52     return output_hour_minute(hour,minute);
53 }
54
55 std::string get_month_name(unsigned char month);
56
57 /**
58  * @brief structure representing a single (half-open) interval.
59  */
60 class Interval
61 {
62     public:
63         Interval()
64         : m_lower_bound(0)
65         , m_upper_bound(0)
66         , m_weak_mark(0)
67         , m_changed(false)
68         {
69         } //
70
71         Interval( unsigned int start, unsigned int end, int weak_mark= 0 )
72         : m_lower_bound(start)
73         , m_upper_bound(end)
74         , m_weak_mark(weak_mark)
75         , m_changed(false)
76         {
77         } //
78
79
80         void clear();
81
82         bool is_valid() const
83         {
84             return m_lower_bound <= m_upper_bound;
85         } // eo is_valid() const
86
87         bool empty() const
88         {
89             return m_lower_bound == m_upper_bound;
90         } // eo empty() const
91
92
93         unsigned int lower_bound() const { return m_lower_bound; }
94         unsigned int upper_bound() const { return m_upper_bound; }
95
96         int weak_mark() const { return m_weak_mark; }
97
98         bool changed() const { return m_changed; }
99
100
101         bool operator== (const Interval& other) const
102         {
103             return m_lower_bound == other.m_lower_bound and m_upper_bound == other.m_upper_bound;
104         } // eo operator==(const Interval&)
105
106
107         bool  operator!=(const Interval& other) const
108         {
109             return not (*this == other);
110         } // eo operator!=(const Interval&)
111
112
113         /**
114          * @brief less operator. compares only the start times!
115          * @param other the other interval to compare with.
116          * @return @a true if the current start is less than the other start.
117          */
118         bool operator<(const Interval& other) const
119         {
120             return m_lower_bound < other.m_lower_bound;
121         } // eo operator<(const Interval&)
122
123
124         bool intersects(const Interval& other) const;
125         bool contains(const Interval& other) const;
126
127
128     protected:
129
130         friend class Intervals;
131
132         unsigned int m_lower_bound;
133         unsigned int m_upper_bound;
134
135         int m_weak_mark;
136         bool m_changed;
137
138 }; // eo Interval
139
140
141
142 /**
143  * @brief structure representing a combination of single disjoint (half open) intervals.
144  *
145  * Basic idea is that this structure provides an interface for adding and
146  * subtracting single intervals and keeps the internal list of intervals as
147  * a list of disjoint intervals.
148  *
149  * @note the list is sorted by the start; lower comes first.
150  *
151  * @note the class provides some methods similar to STL container classes;
152  * i.e. it can be used with (at least some) STL algorithms.
153  * 
154  * @internal
155  * we use a std::list for the intervals; this means we don't invalidate all
156  * iterators when we insert or delete within loops...
157  * And we use that fact!!
158  */
159 class Intervals
160 {
161     public:
162         typedef std::list< Interval > IntervalList;
163         typedef IntervalList::value_type        value_type;
164         typedef IntervalList::const_iterator    const_iterator;
165         typedef IntervalList::const_iterator    iterator; // we allow only const...
166         typedef IntervalList::size_type         size_type;
167
168     public:
169         Intervals();
170
171         void add(const Interval& new_frame);
172         void sub(const Interval& new_frame);
173
174         void clear();
175
176         const_iterator begin() const { return m_intervals.begin(); }
177         const_iterator end() const { return m_intervals.end(); }
178
179         bool empty() const { return m_intervals.empty(); }
180         const Interval& front() const { return m_intervals.front(); }
181         const Interval& back() const { return m_intervals.back(); }
182
183         size_type size() const { return m_intervals.size(); }
184
185         bool intersects(const Interval& other) const;
186         bool intersects(const Intervals& other) const;
187
188         bool contains(const Interval& other) const;
189         bool contains(const Intervals& other) const;
190
191         bool contains_exact(const Interval& other) const;
192
193         bool operator==(const Intervals& other) const;
194         bool operator!=(const Intervals& other) const { return not (*this == other) ; }
195
196         Intervals& operator+=(const Interval& other);
197         Intervals& operator-=(const Interval& other);
198
199         Intervals& operator+=(const Intervals& other);
200         Intervals& operator-=(const Intervals& other);
201
202     protected:
203
204         std::list< Interval > m_intervals;
205
206 }; // eo Intervals
207
208
209 /*
210 ** clock funcs:
211 */
212
213
214 bool monotonic_clock_gettime(long int& seconds, long int& nano_seconds);
215 long long monotonic_clock_gettime_nano();
216
217 bool realtime_clock_gettime(long int& seconds, long int& nano_seconds);
218
219 namespace I2n {
220
221 namespace clock {
222
223     namespace type {
224         /*
225          * represent the clock id options from clock_gettime(2) as
226          * a pair of enums. by default, CLOCK_MONOTONIC_COARSE is used
227          * everywhere since that’s what we want in most cases.
228          */
229         enum id {
230             mono,      /* CLOCK_MONOTONIC_COARSE */
231             real,      /* CLOCK_REALIME_COARSE */
232             boot,      /* CLOCK_BOOTTIME */
233             cpu,       /* CLOCK_CPUTIME_* */
234         };
235
236         /*
237          * for clocks that support it: non-coarse or raw variants; if a variant
238          * does not apply to a given clock, it is ignored
239          */
240         enum variant {
241             dflt,       /* all */
242             exact,      /* mono, real: not (*_COARSE) */
243             raw,        /* mono: _RAW */
244             process,    /* cpu: *_PROCESS_* */
245             thread,     /* cpu: *_THREAD_* */
246         };
247
248     } /* [namespace type] */
249
250
251     class Time {
252
253         private:
254             struct timespec           value;
255
256         public:
257             const enum type::id       id;
258             const enum type::variant  variant;
259             int                       err;
260
261         /* ctors *************************************************************/
262         public:
263
264             Time (const enum type::id      id  = type::mono,
265                   const enum type::variant var = type::dflt);
266
267         /* value access ******************************************************/
268         public:
269
270             inline const struct timespec &get_time (void)
271             { return this->value; }
272
273             inline const time_t &get_sec (void)
274             { return this->value.tv_sec; };
275
276             inline const long &get_nsec (void)
277             { return this->value.tv_nsec; }
278
279             int64_t as_nanosec (void);
280
281             long as_nanosec_L (void);
282
283         /* setting time ******************************************************/
284         public:
285
286             inline void
287             set (const struct timespec &ts)
288             { this->value = ts; };
289
290             inline void
291             set (const time_t sec, const long nsec)
292             {
293                 this->value.tv_sec  = sec;
294                 this->value.tv_nsec = nsec;
295             };
296
297             bool set (void);
298
299             void unset (void);
300
301     }; /* [class Time] */
302
303     boost::optional<Time>
304     now (const enum type::id      id  = type::mono,
305          const enum type::variant var = type::dflt);
306
307 } /* [namespace clock] */
308
309 } /* [namespace I2n] */
310
311
312 #endif