implement a basic time/clock datastructure
[libi2ncommon] / src / timefunc.hxx
index 18b0314..eec351b 100644 (file)
@@ -26,9 +26,12 @@ on this file might be covered by the GNU General Public License.
 #ifndef __TIMEFUNC_HXX
 #define __TIMEFUNC_HXX
 
+#include <errno.h>
 #include <string>
 #include <list>
 
+#include <boost/optional.hpp>
+
 #include <week.hpp>
 
 double prec_time(void);
@@ -213,6 +216,97 @@ long long monotonic_clock_gettime_nano();
 
 bool realtime_clock_gettime(long int& seconds, long int& nano_seconds);
 
+namespace I2n {
+
+namespace clock {
+
+    namespace type {
+        /*
+         * represent the clock id options from clock_gettime(2) as
+         * a pair of enums. by default, CLOCK_MONOTONIC_COARSE is used
+         * everywhere since that’s what we want in most cases.
+         */
+        enum id {
+            mono,      /* CLOCK_MONOTONIC_COARSE */
+            real,      /* CLOCK_REALIME_COARSE */
+            boot,      /* CLOCK_BOOTTIME */
+            cpu,       /* CLOCK_CPUTIME_* */
+        };
+
+        /*
+         * for clocks that support it: non-coarse or raw variants; if a variant
+         * does not apply to a given clock, it is ignored
+         */
+        enum variant {
+            dflt,       /* all */
+            exact,      /* mono, real: not (*_COARSE) */
+            raw,        /* mono: _RAW */
+            process,    /* cpu: *_PROCESS_* */
+            thread,     /* cpu: *_THREAD_* */
+        };
+
+    } /* [namespace type] */
+
+
+    class Time {
+
+        private:
+            struct timespec           value;
+
+        public:
+            const enum type::id       id;
+            const enum type::variant  variant;
+            int                       err;
+
+        /* ctors *************************************************************/
+        public:
+
+            Time (const enum type::id      id  = type::mono,
+                  const enum type::variant var = type::dflt);
+
+        /* value access ******************************************************/
+        public:
+
+            inline const struct timespec &get_time (void)
+            { return this->value; }
+
+            inline const time_t &get_sec (void)
+            { return this->value.tv_sec; };
+
+            inline const long &get_nsec (void)
+            { return this->value.tv_nsec; }
+
+            int64_t as_nanosec (void);
+
+            long as_nanosec_L (void);
+
+        /* setting time ******************************************************/
+        public:
+
+            inline void
+            set (const struct timespec &ts)
+            { this->value = ts; };
+
+            inline void
+            set (const time_t sec, const long nsec)
+            {
+                this->value.tv_sec  = sec;
+                this->value.tv_nsec = nsec;
+            };
+
+            bool set (void);
+
+            void unset (void);
+
+    }; /* [class Time] */
+
+    boost::optional<Time>
+    now (const enum type::id      id  = type::mono,
+         const enum type::variant var = type::dflt);
+
+} /* [namespace clock] */
+
+} /* [namespace I2n] */
 
 
 #endif