template<class T>
Magnum::Math::Nanoseconds class new in Git master

Nanoseconds.

Along with Seconds provides convenience classes to make time specification and conversion less error-prone. As there's little need to represent fractions of nanoseconds, the Magnum::Nanoseconds typedef uses a 64-bit signed integer, which covers a span of ±292 years. In scenarios where nanosecond precision or a large range isn't needed, the Magnum::Seconds typedef, which is a 32-bit floating-point type, may be sufficient.

Usage

You can create the value by using one of the time literals. For all of them the result type is Nanoseconds for preserving maximum precision, but you can directly convert the literal value Seconds:

using namespace Math::Literals;

Nanoseconds fiveSeconds = 5.0_sec;  // 5000000000
Seconds frameTime = 16.667_msec;    // 0.016667

Or by explicitly converting a unitless value (such as an output from some function) to either nanoseconds or seconds. And same can be done in the other direction:

Float fileCopyDuration();

/* Assuming std::time_t is seconds */
Nanoseconds a{std::time(nullptr)*1000000000};
Seconds b{fileCopyDuration()};

/* And usleep() takes microseconds */
usleep(Long(2.0_sec)/1000);

The classes support all arithmetic operations, such as addition, subtraction or multiplication/division by a unitless number:

Seconds a = 0.15_sec + 16.67_msec;  // 0.16667
Nanoseconds b = 1000.0_usec*1.25;   // 1250000
//auto c = 10.0_msec*10.0_sec;      // error, undefined resulting unit

It is also possible to compare time values with all comparison operators. As the literals are all producing Nanoseconds, it's most convenient to compare to nanosecond values. Comparison of Nanoseconds and Seconds is not possible without conversion to a common type first.

Nanoseconds frameTime();

if(frameTime() < 15.0_msec)
    stillCanDoSomething();

STL compatibility

Instances of Nanoseconds are explicitly convertible from and to std::chrono::duration and std::chrono::time_point types if you include Magnum/Math/TimeStl.h. The conversion is provided in a separate header to avoid unconditional #include <chrono>, which can significantly affect compile times. The following table lists allowed conversions, conversions in certain directions aren't allowed as they cause a precision loss:

Magnum typeSTL type
Nanosecondsstd::chrono::nanoseconds
Nanosecondsstd::chrono::microseconds
Nanosecondsstd::chrono::milliseconds
Nanosecondsstd::chrono::seconds
Nanosecondsstd::chrono::minutes
Nanosecondsstd::chrono::hours
Nanosecondsstd::chrono::duration
Nanosecondsstd::chrono::duration<Rep, std::nano>
Nanosecondsstd::chrono::time_point
Nanosecondsstd::chrono::time_point<Clock, std::chrono::duration<Rep, std::nano>>

Example:

#include <Magnum/Math/TimeStl.h>

Nanoseconds a{std::chrono::high_resolution_clock::now()};

std::chrono::nanoseconds b(16.67_msec);

Base classes

template<template<class> class Derived, class T>
class Unit<Nanoseconds, T>
Base class for units.

Public static functions

static auto min() -> Nanoseconds<T> constexpr
Minimal representable value.
static auto max() -> Nanoseconds<T> constexpr
Maximal representable value.

Constructors, destructors, conversion operators

Nanoseconds() constexpr noexcept
Default constructor.
Nanoseconds(ZeroInitT) explicit constexpr noexcept
Construct a zero time.
Nanoseconds(Magnum::NoInitT) explicit noexcept
Construct without initializing the contents.
Nanoseconds(T value) explicit constexpr noexcept
Explicit constructor from a unitless type.
Nanoseconds(Unit<Math::Nanoseconds, T> other) constexpr noexcept
Copy constructor.
template<class U>
Nanoseconds(Unit<Seconds, U> value) constexpr noexcept
Construct nanoseconds from seconds.
template<class U, class V = decltype(Implementation::NanosecondsConverter<T, U>::from(std::declval<U>()))>
Nanoseconds(const U& other) explicit constexpr noexcept
Construct nanoseconds from external representation.
template<class U, class V = decltype(Implementation::NanosecondsConverter<T, U>::to(std::declval<Nanoseconds<T>>()))>
operator U() const explicit constexpr
Convert nanoseconds to external representation.

Function documentation

template<class T>
static Nanoseconds<T> Magnum::Math::Nanoseconds<T>::min() constexpr

Minimal representable value.

Returns -0x8000000000000000_nsec.

template<class T>
static Nanoseconds<T> Magnum::Math::Nanoseconds<T>::max() constexpr

Maximal representable value.

Returns 0x7fffffffffffffff_nsec.

template<class T>
Magnum::Math::Nanoseconds<T>::Nanoseconds() constexpr noexcept

Default constructor.

Equivalent to Nanoseconds(ZeroInitT).

template<class T> template<class U>
Magnum::Math::Nanoseconds<T>::Nanoseconds(Unit<Seconds, U> value) constexpr noexcept

Construct nanoseconds from seconds.

The floating-point value is multiplied by a billion and rounded.

template<class T>
Nanoseconds<Long> operator""_nsec(unsigned long long value) constexpr new in Git master

Nanosecond value literal.

Compared to the microsecond, millisecond and second literals, this literal is an integer value and not a floating-point, as it's not possible to represent fractions of nanoseconds. Usage example:

using namespace Math::Literals;

Nanoseconds twoSeconds = 2000000000_nsec;

template<class T>
Nanoseconds<Long> operator""_usec(long double value) constexpr new in Git master

Microsecond value literal.

As the value is converted to whole nanoseconds, everything after thousandths is truncated. Additionally, up to thousandths the conversion is without precision loss only on systems with a 80-bit long double (which has a 63-bit mantissa). If you need to ensure nanosecond-level precision on systems that have a 64-bit long double, use operator""_nsec() instead. On the other hand, if nanosecond-level precision isn't needed, it's possible to convert directly to Seconds that offer a microsecond-level precision on a range of roughly ±8 seconds. For example:

using namespace Math::Literals;

Nanoseconds a = 2000000.0_usec;
Seconds b = 2000000.0_usec;

template<class T>
Nanoseconds<Long> operator""_msec(long double value) constexpr new in Git master

Millisecond value literal.

As the value is converted to whole nanoseconds, everything after millionths is truncated. Additionally, up to millionths the conversion is without precision loss only on systems with a 80-bit long double (which has a 63-bit mantissa). If you need to ensure nanosecond-level precision on systems that have a 64-bit long double, use operator""_nsec() instead. On the other hand, if nanosecond-level precision isn't needed, it's possible to convert directly to Seconds that offer a millisecond-level precision on a range of roughly ±2 hours. For example:

using namespace Math::Literals;

Nanoseconds a = 16.67_msec;
Seconds b = 16.67_msec;

template<class T>
Nanoseconds<Long> operator""_sec(long double value) constexpr new in Git master

Second value literal.

As the value is converted to whole nanoseconds, everything after billionths is truncated. Additionally, up to billionths the conversion is without precision loss only on systems with a 80-bit long double (which has a 63-bit mantissa). If you need to ensure nanosecond-level precision on systems that have a 64-bit long double, use operator""_nsec() instead. On the other hand, if nanosecond-level precision isn't needed, it's possible to convert directly to Seconds that offer a millisecond-level precision on a range of roughly ±2 hours. For example:

using namespace Math::Literals;

Nanoseconds a = 45.0_sec;
Seconds b = 45.0_sec;

template<class T>
Utility::Debug& operator<<(Utility::Debug& debug, const Unit<Nanoseconds, Long>& value) new in Git master

Debug output operator.