} // eo realtime_clock_gettime(long int&,long int&)
+namespace I2n {
+
+namespace clock {
+
+ namespace {
+
+ static inline clockid_t
+ clockid_of_flags (const enum type::id id,
+ const enum type::variant var)
+ {
+ clockid_t cid = CLOCK_MONOTONIC_COARSE;
+
+ switch (id) {
+
+ default:
+ case type::mono: {
+ switch (var) {
+ default: {
+ break;
+ }
+ case type::raw: {
+ cid = CLOCK_MONOTONIC_RAW;
+ break;
+ }
+ case type::exact: {
+ cid = CLOCK_MONOTONIC;
+ break;
+ }
+ }
+ break;
+ }
+
+ case type::real: {
+ if (var == type::exact) {
+ cid = CLOCK_REALTIME;
+ } else {
+ cid = CLOCK_REALTIME_COARSE;
+ }
+ break;
+ }
+
+ case type::boot: {
+ if (var & type::exact) {
+ cid = CLOCK_BOOTTIME;
+ }
+ break;
+ }
+
+ case type::cpu: {
+ if (var == type::thread) {
+ cid = CLOCK_THREAD_CPUTIME_ID;
+ } else {
+ cid = CLOCK_PROCESS_CPUTIME_ID;
+ }
+ break;
+ }
+ } /* [switch id] */
+
+ return cid;
+ }
+
+ static const struct timespec zero_time = { 0, 0 };
+
+# define NANO (1000L * 1000 * 1000)
+
+ } /* [namespace] */
+
+ Time::Time (const enum type::id id, const enum type::variant var)
+ : value (zero_time)
+ , id (id)
+ , variant (var)
+ , err (0)
+ { }
+
+ int64_t
+ Time::as_nanosec (void)
+ { return int64_t (this->value.tv_sec) * NANO + this->value.tv_nsec; }
+
+ long
+ Time::as_nanosec_L (void) /* likely to overflow */
+ { return static_cast<long>(this->as_nanosec ()); }
+
+ void
+ Time::unset (void)
+ { this->value = zero_time; }
+
+ bool
+ Time::set (void)
+ {
+ struct timespec now;
+
+ errno = 0;
+ if (clock_gettime (clockid_of_flags (this->id, this->variant), &now)
+ == -1)
+ {
+ this->err = errno;
+ this->unset ();
+
+ return false;
+ }
+ this->err = 0;
+ this->value = now;
+
+ return true;
+ }
+
+ boost::optional<Time>
+ now (const enum type::id id, const enum type::variant var)
+ {
+ Time ret (id);
+
+ if (!ret.set ()) {
+ return boost::none;
+ }
+
+ return ret;
+ }
+
+} /* [namespace clock] */
+
+} /* [namespace I2n] */
+