mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
443 lines
17 KiB
443 lines
17 KiB
|
2 years ago
|
/*
|
||
|
|
This file is part of Magnum.
|
||
|
|
|
||
|
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
|
||
|
|
2020, 2021, 2022, 2023 Vladimír Vondruš <mosra@centrum.cz>
|
||
|
|
|
||
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||
|
|
copy of this software and associated documentation files (the "Software"),
|
||
|
|
to deal in the Software without restriction, including without limitation
|
||
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
||
|
|
Software is furnished to do so, subject to the following conditions:
|
||
|
|
|
||
|
|
The above copyright notice and this permission notice shall be included
|
||
|
|
in all copies or substantial portions of the Software.
|
||
|
|
|
||
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||
|
|
DEALINGS IN THE SOFTWARE.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include <new>
|
||
|
|
#include <sstream> /** @todo remove once Debug is STL-free */
|
||
|
|
#include <Corrade/TestSuite/Tester.h>
|
||
|
|
#include <Corrade/Utility/DebugStl.h> /** @todo remove once Debug is STL-free */
|
||
|
|
|
||
|
|
#include "Magnum/Math/Time.h"
|
||
|
|
|
||
|
|
struct Time {
|
||
|
|
unsigned secondsSinceEpoch;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct Keyframe {
|
||
|
|
float duration;
|
||
|
|
};
|
||
|
|
|
||
|
|
namespace Magnum { namespace Math {
|
||
|
|
|
||
|
|
namespace Implementation {
|
||
|
|
|
||
|
|
template<> struct NanosecondsConverter<Long, Time> {
|
||
|
|
constexpr static Nanoseconds<Long> from(Time other) {
|
||
|
|
return Nanoseconds<Long>{Long(other.secondsSinceEpoch)*1000000000ll};
|
||
|
|
}
|
||
|
|
constexpr static Time to(Nanoseconds<Long> other) {
|
||
|
|
return {unsigned(Long(other)/1000000000ll)};
|
||
|
|
}
|
||
|
|
};
|
||
|
|
template<> struct SecondsConverter<Float, Keyframe> {
|
||
|
|
constexpr static Seconds<Float> from(Keyframe other) {
|
||
|
|
return Seconds<Float>{other.duration};
|
||
|
|
}
|
||
|
|
constexpr static Keyframe to(Seconds<Float> other) {
|
||
|
|
return {Float(other)};
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
namespace Test { namespace {
|
||
|
|
|
||
|
|
struct TimeTest: TestSuite::Tester {
|
||
|
|
explicit TimeTest();
|
||
|
|
|
||
|
|
void limits();
|
||
|
|
|
||
|
|
void construct();
|
||
|
|
void constructDefault();
|
||
|
|
void constructNoInit();
|
||
|
|
void constructCopy();
|
||
|
|
void constructFromBase();
|
||
|
|
void convert();
|
||
|
|
|
||
|
|
void literals();
|
||
|
|
void conversion();
|
||
|
|
void nanosecondFloatScaling();
|
||
|
|
|
||
|
|
void debugNanoseconds();
|
||
|
|
void debugNanosecondsPacked();
|
||
|
|
void debugSeconds();
|
||
|
|
void debugSecondsPacked();
|
||
|
|
};
|
||
|
|
|
||
|
|
using Magnum::Nanoseconds;
|
||
|
|
using Magnum::Seconds;
|
||
|
|
|
||
|
|
using namespace Math::Literals;
|
||
|
|
|
||
|
|
TimeTest::TimeTest() {
|
||
|
|
addTests({&TimeTest::limits,
|
||
|
|
|
||
|
|
&TimeTest::construct,
|
||
|
|
&TimeTest::constructDefault,
|
||
|
|
&TimeTest::constructNoInit,
|
||
|
|
&TimeTest::constructCopy,
|
||
|
|
&TimeTest::constructFromBase,
|
||
|
|
&TimeTest::convert,
|
||
|
|
|
||
|
|
&TimeTest::literals,
|
||
|
|
&TimeTest::conversion,
|
||
|
|
&TimeTest::nanosecondFloatScaling,
|
||
|
|
|
||
|
|
&TimeTest::debugNanoseconds,
|
||
|
|
&TimeTest::debugNanosecondsPacked,
|
||
|
|
&TimeTest::debugSeconds,
|
||
|
|
&TimeTest::debugSecondsPacked});
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::limits() {
|
||
|
|
/* There's apparently no way to say -0x8000000000000000ll, so there's also
|
||
|
|
no non-error-prone way to verify the values are correct. */
|
||
|
|
|
||
|
|
/* It should be all 64 bits (so 16 nibbles) being set */
|
||
|
|
CORRADE_COMPARE(UnsignedLong(Long(Nanoseconds::min()))|
|
||
|
|
UnsignedLong(Long(Nanoseconds::max())),
|
||
|
|
/* 0123456789abcdef */
|
||
|
|
0xffffffffffffffffull);
|
||
|
|
|
||
|
|
/* Assuming signed integer overflow is defined sanely, which it should */
|
||
|
|
CORRADE_COMPARE(Nanoseconds::min() - 1_nsec, Nanoseconds::max());
|
||
|
|
CORRADE_COMPARE(Nanoseconds::max() + 1_nsec, Nanoseconds::min());
|
||
|
|
|
||
|
|
/* This should also hold */
|
||
|
|
CORRADE_COMPARE(Nanoseconds::min() + Nanoseconds::max(), -1_nsec);
|
||
|
|
CORRADE_COMPARE(Nanoseconds::max() - Nanoseconds::min(), -1_nsec);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::construct() {
|
||
|
|
Nanoseconds a{-123456789123456789ll};
|
||
|
|
Seconds b{123.45f};
|
||
|
|
CORRADE_COMPARE(Long(a), -123456789123456789ll);
|
||
|
|
CORRADE_COMPARE(Float(b), 123.45f);
|
||
|
|
|
||
|
|
constexpr Nanoseconds ca{-123456789123456789ll};
|
||
|
|
constexpr Seconds cb{123.45f};
|
||
|
|
CORRADE_COMPARE(Long(ca), -123456789123456789ll);
|
||
|
|
CORRADE_COMPARE(Float(cb), 123.45f);
|
||
|
|
|
||
|
|
/* Implicit conversion is not allowed */
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<Long, Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<Float, Seconds>::value);
|
||
|
|
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_constructible<Nanoseconds, Long>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_constructible<Seconds, Float>::value);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::constructDefault() {
|
||
|
|
Nanoseconds a1;
|
||
|
|
Nanoseconds a2{ZeroInit};
|
||
|
|
Seconds b1;
|
||
|
|
Seconds b2{ZeroInit};
|
||
|
|
CORRADE_COMPARE(Long(a1), 0ll);
|
||
|
|
CORRADE_COMPARE(Long(a2), 0ll);
|
||
|
|
CORRADE_COMPARE(Float(b1), 0.0f);
|
||
|
|
CORRADE_COMPARE(Float(b2), 0.0f);
|
||
|
|
|
||
|
|
constexpr Nanoseconds ca1;
|
||
|
|
constexpr Nanoseconds ca2{ZeroInit};
|
||
|
|
constexpr Seconds cb1;
|
||
|
|
constexpr Seconds cb2{ZeroInit};
|
||
|
|
CORRADE_COMPARE(Long(ca1), 0ll);
|
||
|
|
CORRADE_COMPARE(Long(ca2), 0ll);
|
||
|
|
CORRADE_COMPARE(Float(cb1), 0.0f);
|
||
|
|
CORRADE_COMPARE(Float(cb2), 0.0f);
|
||
|
|
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_default_constructible<Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_default_constructible<Seconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_constructible<Nanoseconds, ZeroInitT>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_constructible<Seconds, ZeroInitT>::value);
|
||
|
|
|
||
|
|
/* Implicit construction is not allowed */
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<ZeroInitT, Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<ZeroInitT, Seconds>::value);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::constructNoInit() {
|
||
|
|
Nanoseconds a{123456789123456789ll};
|
||
|
|
Seconds b{123.45f};
|
||
|
|
new(&a) Nanoseconds{Magnum::NoInit};
|
||
|
|
new(&b) Seconds{Magnum::NoInit};
|
||
|
|
{
|
||
|
|
/* Explicitly check we're not on Clang because certain Clang-based IDEs
|
||
|
|
inherit __GNUC__ if GCC is used instead of leaving it at 4 like
|
||
|
|
Clang itself does */
|
||
|
|
#if defined(CORRADE_TARGET_GCC) && !defined(CORRADE_TARGET_CLANG) && __GNUC__*100 + __GNUC_MINOR__ >= 601
|
||
|
|
/* The warning is reported for both debug and release build */
|
||
|
|
#pragma GCC diagnostic push
|
||
|
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||
|
|
/* On GCC 13 it's -Wuninitialized now, the compiler is now EVEN MORE
|
||
|
|
DEFINITELY RIGHT that I'm doing something wrong */
|
||
|
|
#if __GNUC__ >= 13
|
||
|
|
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||
|
|
#endif
|
||
|
|
#ifdef __OPTIMIZE__
|
||
|
|
CORRADE_EXPECT_FAIL("GCC 6.1+ misoptimizes and overwrites the value.");
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
CORRADE_COMPARE(Long(a), 123456789123456789ll);
|
||
|
|
CORRADE_COMPARE(Float(b), 123.45f);
|
||
|
|
#if defined(CORRADE_TARGET_GCC) && !defined(CORRADE_TARGET_CLANG) && __GNUC__*100 + __GNUC_MINOR__ >= 601
|
||
|
|
#pragma GCC diagnostic pop
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_constructible<Nanoseconds, Magnum::NoInitT>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_constructible<Seconds, Magnum::NoInitT>::value);
|
||
|
|
|
||
|
|
/* Implicit construction is not allowed */
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<Magnum::NoInitT, Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<Magnum::NoInitT, Seconds>::value);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::constructCopy() {
|
||
|
|
Nanoseconds a{-987654321987654321ll};
|
||
|
|
Nanoseconds b{a};
|
||
|
|
Seconds c{-543.21f};
|
||
|
|
Seconds d{c};
|
||
|
|
CORRADE_COMPARE(Long(b), -987654321987654321ll);
|
||
|
|
CORRADE_COMPARE(Float(d), -543.21f);
|
||
|
|
|
||
|
|
constexpr Nanoseconds ca{-987654321987654321ll};
|
||
|
|
constexpr Nanoseconds cb{ca};
|
||
|
|
constexpr Seconds cc{-543.21f};
|
||
|
|
constexpr Seconds cd{cc};
|
||
|
|
CORRADE_COMPARE(Long(cb), -987654321987654321ll);
|
||
|
|
CORRADE_COMPARE(Float(cd), -543.21f);
|
||
|
|
|
||
|
|
#ifndef CORRADE_NO_STD_IS_TRIVIALLY_TRAITS
|
||
|
|
CORRADE_VERIFY(std::is_trivially_copy_constructible<Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_trivially_copy_constructible<Seconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_trivially_copy_assignable<Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_trivially_copy_assignable<Seconds>::value);
|
||
|
|
#endif
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Seconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Seconds>::value);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::constructFromBase() {
|
||
|
|
/* The operation returns Unit instead of the leaf type, so this can work
|
||
|
|
only if the base class has a "copy constructor" from the base type */
|
||
|
|
Nanoseconds a = 15.0_usec + 3.5_msec;
|
||
|
|
Seconds b = Seconds{15.0_msec} + Seconds{3.5_sec};
|
||
|
|
CORRADE_COMPARE(a, 3.515_msec);
|
||
|
|
/* Comparing as seconds because precision loss involved */
|
||
|
|
CORRADE_COMPARE_AS(b, 3.515_sec, Seconds);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::convert() {
|
||
|
|
/* From external type */
|
||
|
|
Time a0{1707678819};
|
||
|
|
Keyframe b0{56.72f};
|
||
|
|
Nanoseconds a1{a0};
|
||
|
|
Seconds b1{b0};
|
||
|
|
CORRADE_COMPARE(a1, 1707678819.0_sec);
|
||
|
|
CORRADE_COMPARE_AS(b1, 56.72_sec, Seconds);
|
||
|
|
|
||
|
|
constexpr Time ca0{1707678819};
|
||
|
|
constexpr Keyframe cb0{56.72f};
|
||
|
|
constexpr Nanoseconds ca1{ca0};
|
||
|
|
constexpr Seconds cb1{cb0};
|
||
|
|
CORRADE_COMPARE(ca1, 1707678819.0_sec);
|
||
|
|
CORRADE_COMPARE_AS(cb1, 56.72_sec, Seconds);
|
||
|
|
|
||
|
|
/* To external type */
|
||
|
|
Nanoseconds c0 = 1707678819.0_sec;
|
||
|
|
Seconds d0 = 56.72_sec;
|
||
|
|
Time c1(c0);
|
||
|
|
Keyframe d1(d0);
|
||
|
|
CORRADE_COMPARE(c1.secondsSinceEpoch, 1707678819);
|
||
|
|
CORRADE_COMPARE(d1.duration, 56.72f);
|
||
|
|
|
||
|
|
constexpr Nanoseconds cc0 = 1707678819.0_sec;
|
||
|
|
constexpr Seconds cd0 = 56.72_sec;
|
||
|
|
constexpr Time cc1(cc0);
|
||
|
|
constexpr Keyframe cd1(cd0);
|
||
|
|
CORRADE_COMPARE(cc1.secondsSinceEpoch, 1707678819);
|
||
|
|
CORRADE_COMPARE(cd1.duration, 56.72f);
|
||
|
|
|
||
|
|
/* It should not be possible to convert in a direction that may result in a
|
||
|
|
precision loss, i.e. Seconds with a NanosecondsConverter */
|
||
|
|
CORRADE_VERIFY(std::is_constructible<Seconds, Keyframe>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_constructible<Seconds, Time>::value);
|
||
|
|
CORRADE_VERIFY(std::is_constructible<Nanoseconds, Time>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_constructible<Nanoseconds, Keyframe>::value);
|
||
|
|
CORRADE_VERIFY(std::is_constructible<Time, Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_constructible<Time, Seconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_constructible<Keyframe, Seconds>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_constructible<Keyframe, Nanoseconds>::value);
|
||
|
|
|
||
|
|
/* Implicit conversion is not allowed */
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<Keyframe, Seconds>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<Time, Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<Nanoseconds, Time>::value);
|
||
|
|
CORRADE_VERIFY(!std::is_convertible<Seconds, Keyframe>::value);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::literals() {
|
||
|
|
/* Testing the full precision, 19 digits. Max representable 63-bit value is
|
||
|
|
9223372036854775807. */
|
||
|
|
auto a = 9087654321987654321_nsec;
|
||
|
|
auto b = 9087654321987654.321_usec;
|
||
|
|
auto c = 9087654321987.654321_msec;
|
||
|
|
auto d = 9087654321.987654321_sec;
|
||
|
|
CORRADE_VERIFY(std::is_same<decltype(a), Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_same<decltype(b), Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_same<decltype(c), Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_same<decltype(d), Nanoseconds>::value);
|
||
|
|
CORRADE_COMPARE(Long(a), 9087654321987654321ll);
|
||
|
|
/* Not sure what Emscripten does here, but it behaves as if long double was
|
||
|
|
actually the full precision */
|
||
|
|
#if !defined(CORRADE_LONG_DOUBLE_SAME_AS_DOUBLE) || defined(CORRADE_TARGET_EMSCRIPTEN)
|
||
|
|
/* 80-bit long double has a 63-bit mantissa, which means this is converted
|
||
|
|
without any precision loss. Otherwise the precision is just 52 bits. */
|
||
|
|
CORRADE_COMPARE(Long(b), 9087654321987654321ll);
|
||
|
|
/* Well, almost. On x86 this conversion has a slight imprecision in the
|
||
|
|
lowest bit for the _ms variant, on ARM64 and Emscripten for the _s
|
||
|
|
variant. */
|
||
|
|
#if (defined(CORRADE_TARGET_ARM) && !defined(CORRADE_TARGET_32BIT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
|
||
|
|
CORRADE_COMPARE(Long(c), 9087654321987654321ll);
|
||
|
|
CORRADE_COMPARE(Long(d), 9087654321987654320ll);
|
||
|
|
#else
|
||
|
|
CORRADE_COMPARE(Long(c), 9087654321987654320ll);
|
||
|
|
CORRADE_COMPARE(Long(d), 9087654321987654321ll);
|
||
|
|
#endif
|
||
|
|
#else
|
||
|
|
CORRADE_COMPARE(Long(b), 9087654321987653632ll);
|
||
|
|
CORRADE_COMPARE(Long(c), 9087654321987654656ll);
|
||
|
|
CORRADE_COMPARE(Long(d), 9087654321987653632ll);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
constexpr auto ca = 9087654321987654321_nsec;
|
||
|
|
constexpr auto cb = 9087654321987654.321_usec;
|
||
|
|
constexpr auto cc = 9087654321987.654321_msec;
|
||
|
|
constexpr auto cd = 9087654321.987654321_sec;
|
||
|
|
CORRADE_VERIFY(std::is_same<decltype(ca), const Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_same<decltype(cb), const Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_same<decltype(cc), const Nanoseconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_same<decltype(cd), const Nanoseconds>::value);
|
||
|
|
CORRADE_COMPARE(Long(ca), 9087654321987654321ll);
|
||
|
|
#if !defined(CORRADE_LONG_DOUBLE_SAME_AS_DOUBLE) || defined(CORRADE_TARGET_EMSCRIPTEN)
|
||
|
|
CORRADE_COMPARE(Long(cb), 9087654321987654321ll);
|
||
|
|
#if (defined(CORRADE_TARGET_ARM) && !defined(CORRADE_TARGET_32BIT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
|
||
|
|
CORRADE_COMPARE(Long(cc), 9087654321987654321ll);
|
||
|
|
CORRADE_COMPARE(Long(cd), 9087654321987654320ll);
|
||
|
|
#else
|
||
|
|
CORRADE_COMPARE(Long(cc), 9087654321987654320ll);
|
||
|
|
CORRADE_COMPARE(Long(cd), 9087654321987654321ll);
|
||
|
|
#endif
|
||
|
|
#else
|
||
|
|
CORRADE_COMPARE(Long(cb), 9087654321987653632ll);
|
||
|
|
CORRADE_COMPARE(Long(cc), 9087654321987654656ll);
|
||
|
|
CORRADE_COMPARE(Long(cd), 9087654321987653632ll);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::conversion() {
|
||
|
|
/* Implicit conversion should be allowed. Again testing (almost) the full
|
||
|
|
nanosecond precision, although not much of it is left when converting
|
||
|
|
to a 32-bit float. */
|
||
|
|
Nanoseconds a = Seconds{-987654321.987654321f};
|
||
|
|
Seconds b = 987654321987654321_nsec;
|
||
|
|
CORRADE_COMPARE(Long(a), -987654336000000000ll);
|
||
|
|
CORRADE_COMPARE(Float(b), 987654336.0f);
|
||
|
|
|
||
|
|
constexpr Nanoseconds ca = Seconds{987654321.987654321f};
|
||
|
|
constexpr Seconds cb = -987654321987654321_nsec;
|
||
|
|
CORRADE_COMPARE(Long(ca), 987654336000000000ll);
|
||
|
|
CORRADE_COMPARE(Float(cb), -987654336.0f);
|
||
|
|
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_constructible<Nanoseconds, Seconds>::value);
|
||
|
|
CORRADE_VERIFY(std::is_nothrow_constructible<Seconds, Nanoseconds>::value);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::nanosecondFloatScaling() {
|
||
|
|
/* Nanoseconds is an integer type, but multiplying it with float should
|
||
|
|
give a reasonable output. The actual logic is in the Unit class, just
|
||
|
|
verify that it works from the high level perspective here. */
|
||
|
|
|
||
|
|
CORRADE_COMPARE(1000000000_nsec*1.25, 1250000000_nsec);
|
||
|
|
CORRADE_COMPARE(1000000000_nsec*1.25f, 1250000000_nsec);
|
||
|
|
CORRADE_COMPARE(1000000000_nsec/0.8, 1250000000_nsec);
|
||
|
|
CORRADE_COMPARE(1000000000_nsec/0.8f, 1250000000_nsec);
|
||
|
|
|
||
|
|
/* Compared to above this looks like it should "obviously work", although
|
||
|
|
internally both cases are the same, operating on Nanoseconds */
|
||
|
|
CORRADE_COMPARE(1.0_sec*1.25, 1.25_sec);
|
||
|
|
CORRADE_COMPARE(1.0_sec*1.25f, 1.25_sec);
|
||
|
|
CORRADE_COMPARE(1.0_sec/0.8, 1.25_sec);
|
||
|
|
CORRADE_COMPARE(1.0_sec/0.8f, 1.25_sec);
|
||
|
|
|
||
|
|
/* This would be nice if it worked, but so far it doesn't, as it's
|
||
|
|
calculated as an integer value */
|
||
|
|
CORRADE_COMPARE(1.0f/0.018f, 55.5556f);
|
||
|
|
{
|
||
|
|
CORRADE_EXPECT_FAIL("This doesn't work correctly.");
|
||
|
|
CORRADE_COMPARE(1.0_sec/18.0_msec, 55.5556f);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::debugNanoseconds() {
|
||
|
|
std::ostringstream out;
|
||
|
|
|
||
|
|
/* Also verify that the second expression compiles (it's the Unit type,
|
||
|
|
not Nanoseconds) */
|
||
|
|
Debug{&out} << 987654321987654321_nsec << 15.0_sec - 7.5_sec;
|
||
|
|
CORRADE_COMPARE(out.str(), "Nanoseconds(987654321987654321) Nanoseconds(7500000000)\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::debugNanosecondsPacked() {
|
||
|
|
std::ostringstream out;
|
||
|
|
|
||
|
|
/* Second is not packed, the first should not make any flags persistent */
|
||
|
|
Debug{&out} << Debug::packed << 15.0_sec << 45.0_sec;
|
||
|
|
CORRADE_COMPARE(out.str(), "15000000000 Nanoseconds(45000000000)\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::debugSeconds() {
|
||
|
|
std::ostringstream out;
|
||
|
|
|
||
|
|
/* Also verify that the second expression compiles (it's the Unit type,
|
||
|
|
not Nanoseconds) */
|
||
|
|
Debug{&out} << Seconds{123.45_sec} << Seconds{15.0_sec} - Seconds{7.5_sec};
|
||
|
|
CORRADE_COMPARE(out.str(), "Seconds(123.45) Seconds(7.5)\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
void TimeTest::debugSecondsPacked() {
|
||
|
|
std::ostringstream out;
|
||
|
|
|
||
|
|
/* Second is not packed, the first should not make any flags persistent */
|
||
|
|
Debug{&out} << Debug::packed << Seconds{123.45_sec} << Seconds{45.0_sec};
|
||
|
|
CORRADE_COMPARE(out.str(), "123.45 Seconds(45)\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
}}}}
|
||
|
|
|
||
|
|
CORRADE_TEST_MAIN(Magnum::Math::Test::TimeTest)
|