I would do it like this:
template <class Rep, class Period> std::chrono::duration<Rep, Period> abs(std::chrono::duration<Rep, Period> d) { Rep x = d.count(); return std::chrono::duration<Rep, Period>(x >= 0 ? x : -x); }
See my list of <chrono> Utilities for the other <chrono> utilities that I desire were standard. Please feel free to use them, recommend them to your standards or suggest them yourself.
Update
I was offside when I wrote above. I do not delete it, as it serves as a good lesson for me and others on how not to write chrono utilities.
Things I don't like:
It unnecessarily reduces type safety by directly manipulating Rep .
The letter 0 is supposed to be implicitly converted, or at least compared to Rep .
There is no reason for this not to be constexpr .
I am not happy with the behavior for unsigned Rep . If you say:
auto d = abs (t1 - t0);
and t1 and t0 are based on unsigned lengths, then this is most likely a logical error in the code. If t1 < t0 , then you are likely to get the wrong, very long duration. If this is what you really want, then you shouldn't use abs , but instead, just coding is easier:
auto d = t1 - t0;
To solve these problems, I rewrote abs for the duration as:
template <class Rep, class Period, class = typename std::enable_if < std::chrono::duration<Rep, Period>::min() < std::chrono::duration<Rep, Period>::zero() >::type > constexpr inline std::chrono::duration<Rep, Period> abs(std::chrono::duration<Rep, Period> d) { return d >= d.zero() ? d : -d; }
duration is unary - just use it.
duration has a custom zero sign, so you don't have to assume close collaboration with 0 from Rep . Just use it.
All used constexpr operations are labeled abs constexpr .
The static functions min and zero are equal to constexpr . Using these parameters to determine if a Rep is signed is more general than using a tag such as !std::is_unsigned . That is, Rep can be BigNum , or C11 timespec (supplemented by overloaded arithmetic operators). Therefore, the question "signed" is answered by min() < zero() . And now this version of abs will not accept duration<unsigned, milli> (for example).
Howard hinnant
source share