summaryrefslogtreecommitdiff
path: root/indra/llcommon/tests/llunits_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/tests/llunits_test.cpp')
-rw-r--r--indra/llcommon/tests/llunits_test.cpp674
1 files changed, 337 insertions, 337 deletions
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index 57cf9810af..49f2d3085a 100644
--- a/indra/llcommon/tests/llunits_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llsingleton_test.cpp
* @date 2011-08-11
* @brief Unit test for the LLSingleton class
@@ -32,10 +32,10 @@
namespace LLUnits
{
- // using powers of 2 to allow strict floating point equality
- LL_DECLARE_BASE_UNIT(Quatloos, "Quat");
- LL_DECLARE_DERIVED_UNIT(Latinum, "Lat", Quatloos, / 4);
- LL_DECLARE_DERIVED_UNIT(Solari, "Sol", Latinum, * 16);
+ // using powers of 2 to allow strict floating point equality
+ LL_DECLARE_BASE_UNIT(Quatloos, "Quat");
+ LL_DECLARE_DERIVED_UNIT(Latinum, "Lat", Quatloos, / 4);
+ LL_DECLARE_DERIVED_UNIT(Solari, "Sol", Latinum, * 16);
}
LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Quatloos);
@@ -44,9 +44,9 @@ LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Solari);
namespace LLUnits
{
- LL_DECLARE_BASE_UNIT(Celcius, "c");
- LL_DECLARE_DERIVED_UNIT(Fahrenheit, "f", Celcius, * 9 / 5 + 32);
- LL_DECLARE_DERIVED_UNIT(Kelvin, "k", Celcius, + 273.15f);
+ LL_DECLARE_BASE_UNIT(Celcius, "c");
+ LL_DECLARE_DERIVED_UNIT(Fahrenheit, "f", Celcius, * 9 / 5 + 32);
+ LL_DECLARE_DERIVED_UNIT(Kelvin, "k", Celcius, + 273.15f);
}
LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Celcius);
@@ -56,333 +56,333 @@ LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Kelvin);
namespace tut
{
- using namespace LLUnits;
- struct units
- {
- };
-
- typedef test_group<units> units_t;
- typedef units_t::object units_object_t;
- tut::units_t tut_singleton("LLUnit");
-
- // storage type conversions
- template<> template<>
- void units_object_t::test<1>()
- {
- LLUnit<F32, Quatloos> float_quatloos;
- ensure("default float unit is zero", float_quatloos == F32Quatloos(0.f));
-
- LLUnit<F32, Quatloos> float_initialize_quatloos(1);
- ensure("non-zero initialized unit", float_initialize_quatloos == F32Quatloos(1.f));
-
- LLUnit<S32, Quatloos> int_quatloos;
- ensure("default int unit is zero", int_quatloos == S32Quatloos(0));
-
- int_quatloos = S32Quatloos(42);
- ensure("int assignment is preserved", int_quatloos == S32Quatloos(42));
- float_quatloos = int_quatloos;
- ensure("float assignment from int preserves value", float_quatloos == F32Quatloos(42.f));
-
- int_quatloos = float_quatloos;
- ensure("int assignment from float preserves value", int_quatloos == S32Quatloos(42));
-
- float_quatloos = F32Quatloos(42.1f);
- int_quatloos = float_quatloos;
- ensure("int units truncate float units on assignment", int_quatloos == S32Quatloos(42));
-
- LLUnit<U32, Quatloos> unsigned_int_quatloos(float_quatloos);
- ensure("unsigned int can be initialized from signed int", unsigned_int_quatloos == S32Quatloos(42));
-
- S32Solari int_solari(1);
-
- float_quatloos = int_solari;
- ensure("fractional units are preserved in conversion from integer to float type", float_quatloos == F32Quatloos(0.25f));
-
- int_quatloos = S32Quatloos(1);
- F32Solari float_solari = int_quatloos;
- ensure("can convert with fractional intermediates from integer to float type", float_solari == F32Solari(4.f));
- }
-
- // conversions to/from base unit
- template<> template<>
- void units_object_t::test<2>()
- {
- LLUnit<F32, Quatloos> quatloos(1.f);
- LLUnit<F32, Latinum> latinum_bars(quatloos);
- ensure("conversion between units is automatic via initialization", latinum_bars == F32Latinum(1.f / 4.f));
-
- latinum_bars = S32Latinum(256);
- quatloos = latinum_bars;
- ensure("conversion between units is automatic via assignment, and bidirectional", quatloos == S32Quatloos(1024));
-
- LLUnit<S32, Quatloos> single_quatloo(1);
- LLUnit<F32, Latinum> quarter_latinum = single_quatloo;
- ensure("division of integer unit preserves fractional values when converted to float unit", quarter_latinum == F32Latinum(0.25f));
- }
-
- // conversions across non-base units
- template<> template<>
- void units_object_t::test<3>()
- {
- LLUnit<F32, Quatloos> quatloos(1024);
- LLUnit<F32, Solari> solari(quatloos);
- ensure("conversions can work between indirectly related units: Quatloos -> Latinum -> Solari", solari == S32Solari(4096));
-
- LLUnit<F32, Latinum> latinum_bars = solari;
- ensure("Non base units can be converted between each other", latinum_bars == S32Latinum(256));
- }
-
- // math operations
- template<> template<>
- void units_object_t::test<4>()
- {
- // exercise math operations
- LLUnit<F32, Quatloos> quatloos(1.f);
- quatloos *= 4.f;
- ensure(quatloos == S32Quatloos(4));
- quatloos = quatloos * 2;
- ensure(quatloos == S32Quatloos(8));
- quatloos = 2.f * quatloos;
- ensure(quatloos == S32Quatloos(16));
-
- quatloos += F32Quatloos(4.f);
- ensure(quatloos == S32Quatloos(20));
- quatloos += S32Quatloos(4);
- ensure(quatloos == S32Quatloos(24));
- quatloos = quatloos + S32Quatloos(4);
- ensure(quatloos == S32Quatloos(28));
- quatloos = S32Quatloos(4) + quatloos;
- ensure(quatloos == S32Quatloos(32));
- quatloos += quatloos * 3;
- ensure(quatloos == S32Quatloos(128));
-
- quatloos -= quatloos / 4 * 3;
- ensure(quatloos == S32Quatloos(32));
- quatloos = quatloos - S32Quatloos(8);
- ensure(quatloos == S32Quatloos(24));
- quatloos -= S32Quatloos(4);
- ensure(quatloos == S32Quatloos(20));
- quatloos -= F32Quatloos(4.f);
- ensure(quatloos == S32Quatloos(16));
-
- quatloos /= 2.f;
- ensure(quatloos == S32Quatloos(8));
- quatloos = quatloos / 4;
- ensure(quatloos == S32Quatloos(2));
-
- F32 ratio = quatloos / LLUnit<F32, Quatloos>(2.f);
- ensure(ratio == 1);
- ratio = quatloos / LLUnit<F32, Solari>(8.f);
- ensure(ratio == 1);
-
- quatloos += LLUnit<F32, Solari>(8.f);
- ensure(quatloos == S32Quatloos(4));
- quatloos -= LLUnit<F32, Latinum>(1.f);
- ensure(quatloos == S32Quatloos(0));
- }
-
- // comparison operators
- template<> template<>
- void units_object_t::test<5>()
- {
- LLUnit<S32, Quatloos> quatloos(1);
- ensure("can perform less than comparison against same type", quatloos < S32Quatloos(2));
- ensure("can perform less than comparison against different storage type", quatloos < F32Quatloos(2.f));
- ensure("can perform less than comparison against different units", quatloos < S32Latinum(5));
- ensure("can perform less than comparison against different storage type and units", quatloos < F32Latinum(5.f));
-
- ensure("can perform greater than comparison against same type", quatloos > S32Quatloos(0));
- ensure("can perform greater than comparison against different storage type", quatloos > F32Quatloos(0.f));
- ensure("can perform greater than comparison against different units", quatloos > S32Latinum(0));
- ensure("can perform greater than comparison against different storage type and units", quatloos > F32Latinum(0.f));
-
- }
-
- bool accept_explicit_quatloos(S32Quatloos q)
- {
- return true;
- }
-
- bool accept_implicit_quatloos(S32Quatloos q)
- {
- return true;
- }
-
- // signature compatibility
- template<> template<>
- void units_object_t::test<6>()
- {
- S32Quatloos quatloos(1);
- ensure("can pass unit values as argument", accept_explicit_quatloos(S32Quatloos(1)));
- ensure("can pass unit values as argument", accept_explicit_quatloos(quatloos));
- }
-
- // implicit units
- template<> template<>
- void units_object_t::test<7>()
- {
- LLUnit<F32, Quatloos> quatloos;
- LLUnitImplicit<F32, Quatloos> quatloos_implicit = quatloos + S32Quatloos(1);
- ensure("can initialize implicit unit from explicit", quatloos_implicit == 1);
-
- quatloos = quatloos_implicit;
- ensure("can assign implicit unit to explicit unit", quatloos == S32Quatloos(1));
- quatloos += quatloos_implicit;
- ensure("can perform math operation using mixture of implicit and explicit units", quatloos == S32Quatloos(2));
-
- // math operations on implicits
- quatloos_implicit = 1;
- ensure(quatloos_implicit == 1);
-
- quatloos_implicit += 2;
- ensure(quatloos_implicit == 3);
-
- quatloos_implicit *= 2;
- ensure(quatloos_implicit == 6);
-
- quatloos_implicit -= 1;
- ensure(quatloos_implicit == 5);
-
- quatloos_implicit /= 5;
- ensure(quatloos_implicit == 1);
-
- quatloos_implicit = quatloos_implicit + 3 + quatloos_implicit;
- ensure(quatloos_implicit == 5);
-
- quatloos_implicit = 10 - quatloos_implicit - 1;
- ensure(quatloos_implicit == 4);
-
- quatloos_implicit = 2 * quatloos_implicit * 2;
- ensure(quatloos_implicit == 16);
-
- F32 one_half = quatloos_implicit / (quatloos_implicit * 2);
- ensure(one_half == 0.5f);
-
- // implicit conversion to POD
- F32 float_val = quatloos_implicit;
- ensure("implicit units convert implicitly to regular values", float_val == 16);
-
- S32 int_val = quatloos_implicit;
- ensure("implicit units convert implicitly to regular values", int_val == 16);
-
- // conversion of implicits
- LLUnitImplicit<F32, Latinum> latinum_implicit(2);
- ensure("implicit units of different types are comparable", latinum_implicit * 2 == quatloos_implicit);
-
- quatloos_implicit += F32Quatloos(10);
- ensure("can add-assign explicit units", quatloos_implicit == 26);
-
- quatloos_implicit -= F32Quatloos(10);
- ensure("can subtract-assign explicit units", quatloos_implicit == 16);
-
- // comparisons
- ensure("can compare greater than implicit unit", quatloos_implicit > F32QuatloosImplicit(0.f));
- ensure("can compare greater than non-implicit unit", quatloos_implicit > F32Quatloos(0.f));
- ensure("can compare greater than or equal to implicit unit", quatloos_implicit >= F32QuatloosImplicit(0.f));
- ensure("can compare greater than or equal to non-implicit unit", quatloos_implicit >= F32Quatloos(0.f));
- ensure("can compare less than implicit unit", quatloos_implicit < F32QuatloosImplicit(20.f));
- ensure("can compare less than non-implicit unit", quatloos_implicit < F32Quatloos(20.f));
- ensure("can compare less than or equal to implicit unit", quatloos_implicit <= F32QuatloosImplicit(20.f));
- ensure("can compare less than or equal to non-implicit unit", quatloos_implicit <= F32Quatloos(20.f));
- }
-
- // precision tests
- template<> template<>
- void units_object_t::test<8>()
- {
- U32Bytes max_bytes(U32_MAX);
- S32Megabytes mega_bytes = max_bytes;
- ensure("max available precision is used when converting units", mega_bytes == (S32Megabytes)4095);
-
- mega_bytes = (S32Megabytes)-5 + (U32Megabytes)1;
- ensure("can mix signed and unsigned in units addition", mega_bytes == (S32Megabytes)-4);
-
- mega_bytes = (U32Megabytes)5 + (S32Megabytes)-1;
- ensure("can mix unsigned and signed in units addition", mega_bytes == (S32Megabytes)4);
- }
-
- // default units
- template<> template<>
- void units_object_t::test<9>()
- {
- U32Gigabytes GB(1);
- U32Megabytes MB(GB);
- U32Kilobytes KB(GB);
- U32Bytes B(GB);
-
- ensure("GB -> MB conversion", MB.value() == 1024);
- ensure("GB -> KB conversion", KB.value() == 1024 * 1024);
- ensure("GB -> B conversion", B.value() == 1024 * 1024 * 1024);
-
- KB = U32Kilobytes(1);
- U32Kilobits Kb(KB);
- U32Bits b(KB);
- ensure("KB -> Kb conversion", Kb.value() == 8);
- ensure("KB -> b conversion", b.value() == 8 * 1024);
-
- U32Days days(1);
- U32Hours hours(days);
- U32Minutes minutes(days);
- U32Seconds seconds(days);
- U32Milliseconds ms(days);
-
- ensure("days -> hours conversion", hours.value() == 24);
- ensure("days -> minutes conversion", minutes.value() == 24 * 60);
- ensure("days -> seconds conversion", seconds.value() == 24 * 60 * 60);
- ensure("days -> ms conversion", ms.value() == 24 * 60 * 60 * 1000);
-
- U32Kilometers km(1);
- U32Meters m(km);
- U32Centimeters cm(km);
- U32Millimeters mm(km);
-
- ensure("km -> m conversion", m.value() == 1000);
- ensure("km -> cm conversion", cm.value() == 1000 * 100);
- ensure("km -> mm conversion", mm.value() == 1000 * 1000);
-
- U32Gigahertz GHz(1);
- U32Megahertz MHz(GHz);
- U32Kilohertz KHz(GHz);
- U32Hertz Hz(GHz);
-
- ensure("GHz -> MHz conversion", MHz.value() == 1000);
- ensure("GHz -> KHz conversion", KHz.value() == 1000 * 1000);
- ensure("GHz -> Hz conversion", Hz.value() == 1000 * 1000 * 1000);
-
- F32Radians rad(6.2831853071795f);
- S32Degrees deg(rad);
- ensure("radians -> degrees conversion", deg.value() == 360);
-
- F32Percent percent(50);
- F32Ratio ratio(percent);
- ensure("percent -> ratio conversion", ratio.value() == 0.5f);
-
- U32Kilotriangles ktris(1);
- U32Triangles tris(ktris);
- ensure("kilotriangles -> triangles conversion", tris.value() == 1000);
- }
-
- bool value_near(F32 value, F32 target, F32 threshold)
- {
- return fabsf(value - target) < threshold;
- }
-
- // linear transforms
- template<> template<>
- void units_object_t::test<10>()
- {
- F32Celcius float_celcius(100);
- F32Fahrenheit float_fahrenheit(float_celcius);
- ensure("floating point celcius -> fahrenheit conversion using linear transform", value_near(float_fahrenheit.value(), 212, 0.1f) );
-
- float_celcius = float_fahrenheit;
- ensure("floating point fahrenheit -> celcius conversion using linear transform (round trip)", value_near(float_celcius.value(), 100.f, 0.1f) );
-
- S32Celcius int_celcius(100);
- S32Fahrenheit int_fahrenheit(int_celcius);
- ensure("integer celcius -> fahrenheit conversion using linear transform", int_fahrenheit.value() == 212);
-
- int_celcius = int_fahrenheit;
- ensure("integer fahrenheit -> celcius conversion using linear transform (round trip)", int_celcius.value() == 100);
- }
+ using namespace LLUnits;
+ struct units
+ {
+ };
+
+ typedef test_group<units> units_t;
+ typedef units_t::object units_object_t;
+ tut::units_t tut_singleton("LLUnit");
+
+ // storage type conversions
+ template<> template<>
+ void units_object_t::test<1>()
+ {
+ LLUnit<F32, Quatloos> float_quatloos;
+ ensure("default float unit is zero", float_quatloos == F32Quatloos(0.f));
+
+ LLUnit<F32, Quatloos> float_initialize_quatloos(1);
+ ensure("non-zero initialized unit", float_initialize_quatloos == F32Quatloos(1.f));
+
+ LLUnit<S32, Quatloos> int_quatloos;
+ ensure("default int unit is zero", int_quatloos == S32Quatloos(0));
+
+ int_quatloos = S32Quatloos(42);
+ ensure("int assignment is preserved", int_quatloos == S32Quatloos(42));
+ float_quatloos = int_quatloos;
+ ensure("float assignment from int preserves value", float_quatloos == F32Quatloos(42.f));
+
+ int_quatloos = float_quatloos;
+ ensure("int assignment from float preserves value", int_quatloos == S32Quatloos(42));
+
+ float_quatloos = F32Quatloos(42.1f);
+ int_quatloos = float_quatloos;
+ ensure("int units truncate float units on assignment", int_quatloos == S32Quatloos(42));
+
+ LLUnit<U32, Quatloos> unsigned_int_quatloos(float_quatloos);
+ ensure("unsigned int can be initialized from signed int", unsigned_int_quatloos == S32Quatloos(42));
+
+ S32Solari int_solari(1);
+
+ float_quatloos = int_solari;
+ ensure("fractional units are preserved in conversion from integer to float type", float_quatloos == F32Quatloos(0.25f));
+
+ int_quatloos = S32Quatloos(1);
+ F32Solari float_solari = int_quatloos;
+ ensure("can convert with fractional intermediates from integer to float type", float_solari == F32Solari(4.f));
+ }
+
+ // conversions to/from base unit
+ template<> template<>
+ void units_object_t::test<2>()
+ {
+ LLUnit<F32, Quatloos> quatloos(1.f);
+ LLUnit<F32, Latinum> latinum_bars(quatloos);
+ ensure("conversion between units is automatic via initialization", latinum_bars == F32Latinum(1.f / 4.f));
+
+ latinum_bars = S32Latinum(256);
+ quatloos = latinum_bars;
+ ensure("conversion between units is automatic via assignment, and bidirectional", quatloos == S32Quatloos(1024));
+
+ LLUnit<S32, Quatloos> single_quatloo(1);
+ LLUnit<F32, Latinum> quarter_latinum = single_quatloo;
+ ensure("division of integer unit preserves fractional values when converted to float unit", quarter_latinum == F32Latinum(0.25f));
+ }
+
+ // conversions across non-base units
+ template<> template<>
+ void units_object_t::test<3>()
+ {
+ LLUnit<F32, Quatloos> quatloos(1024);
+ LLUnit<F32, Solari> solari(quatloos);
+ ensure("conversions can work between indirectly related units: Quatloos -> Latinum -> Solari", solari == S32Solari(4096));
+
+ LLUnit<F32, Latinum> latinum_bars = solari;
+ ensure("Non base units can be converted between each other", latinum_bars == S32Latinum(256));
+ }
+
+ // math operations
+ template<> template<>
+ void units_object_t::test<4>()
+ {
+ // exercise math operations
+ LLUnit<F32, Quatloos> quatloos(1.f);
+ quatloos *= 4.f;
+ ensure(quatloos == S32Quatloos(4));
+ quatloos = quatloos * 2;
+ ensure(quatloos == S32Quatloos(8));
+ quatloos = 2.f * quatloos;
+ ensure(quatloos == S32Quatloos(16));
+
+ quatloos += F32Quatloos(4.f);
+ ensure(quatloos == S32Quatloos(20));
+ quatloos += S32Quatloos(4);
+ ensure(quatloos == S32Quatloos(24));
+ quatloos = quatloos + S32Quatloos(4);
+ ensure(quatloos == S32Quatloos(28));
+ quatloos = S32Quatloos(4) + quatloos;
+ ensure(quatloos == S32Quatloos(32));
+ quatloos += quatloos * 3;
+ ensure(quatloos == S32Quatloos(128));
+
+ quatloos -= quatloos / 4 * 3;
+ ensure(quatloos == S32Quatloos(32));
+ quatloos = quatloos - S32Quatloos(8);
+ ensure(quatloos == S32Quatloos(24));
+ quatloos -= S32Quatloos(4);
+ ensure(quatloos == S32Quatloos(20));
+ quatloos -= F32Quatloos(4.f);
+ ensure(quatloos == S32Quatloos(16));
+
+ quatloos /= 2.f;
+ ensure(quatloos == S32Quatloos(8));
+ quatloos = quatloos / 4;
+ ensure(quatloos == S32Quatloos(2));
+
+ F32 ratio = quatloos / LLUnit<F32, Quatloos>(2.f);
+ ensure(ratio == 1);
+ ratio = quatloos / LLUnit<F32, Solari>(8.f);
+ ensure(ratio == 1);
+
+ quatloos += LLUnit<F32, Solari>(8.f);
+ ensure(quatloos == S32Quatloos(4));
+ quatloos -= LLUnit<F32, Latinum>(1.f);
+ ensure(quatloos == S32Quatloos(0));
+ }
+
+ // comparison operators
+ template<> template<>
+ void units_object_t::test<5>()
+ {
+ LLUnit<S32, Quatloos> quatloos(1);
+ ensure("can perform less than comparison against same type", quatloos < S32Quatloos(2));
+ ensure("can perform less than comparison against different storage type", quatloos < F32Quatloos(2.f));
+ ensure("can perform less than comparison against different units", quatloos < S32Latinum(5));
+ ensure("can perform less than comparison against different storage type and units", quatloos < F32Latinum(5.f));
+
+ ensure("can perform greater than comparison against same type", quatloos > S32Quatloos(0));
+ ensure("can perform greater than comparison against different storage type", quatloos > F32Quatloos(0.f));
+ ensure("can perform greater than comparison against different units", quatloos > S32Latinum(0));
+ ensure("can perform greater than comparison against different storage type and units", quatloos > F32Latinum(0.f));
+
+ }
+
+ bool accept_explicit_quatloos(S32Quatloos q)
+ {
+ return true;
+ }
+
+ bool accept_implicit_quatloos(S32Quatloos q)
+ {
+ return true;
+ }
+
+ // signature compatibility
+ template<> template<>
+ void units_object_t::test<6>()
+ {
+ S32Quatloos quatloos(1);
+ ensure("can pass unit values as argument", accept_explicit_quatloos(S32Quatloos(1)));
+ ensure("can pass unit values as argument", accept_explicit_quatloos(quatloos));
+ }
+
+ // implicit units
+ template<> template<>
+ void units_object_t::test<7>()
+ {
+ LLUnit<F32, Quatloos> quatloos;
+ LLUnitImplicit<F32, Quatloos> quatloos_implicit = quatloos + S32Quatloos(1);
+ ensure("can initialize implicit unit from explicit", quatloos_implicit == 1);
+
+ quatloos = quatloos_implicit;
+ ensure("can assign implicit unit to explicit unit", quatloos == S32Quatloos(1));
+ quatloos += quatloos_implicit;
+ ensure("can perform math operation using mixture of implicit and explicit units", quatloos == S32Quatloos(2));
+
+ // math operations on implicits
+ quatloos_implicit = 1;
+ ensure(quatloos_implicit == 1);
+
+ quatloos_implicit += 2;
+ ensure(quatloos_implicit == 3);
+
+ quatloos_implicit *= 2;
+ ensure(quatloos_implicit == 6);
+
+ quatloos_implicit -= 1;
+ ensure(quatloos_implicit == 5);
+
+ quatloos_implicit /= 5;
+ ensure(quatloos_implicit == 1);
+
+ quatloos_implicit = quatloos_implicit + 3 + quatloos_implicit;
+ ensure(quatloos_implicit == 5);
+
+ quatloos_implicit = 10 - quatloos_implicit - 1;
+ ensure(quatloos_implicit == 4);
+
+ quatloos_implicit = 2 * quatloos_implicit * 2;
+ ensure(quatloos_implicit == 16);
+
+ F32 one_half = quatloos_implicit / (quatloos_implicit * 2);
+ ensure(one_half == 0.5f);
+
+ // implicit conversion to POD
+ F32 float_val = quatloos_implicit;
+ ensure("implicit units convert implicitly to regular values", float_val == 16);
+
+ S32 int_val = quatloos_implicit;
+ ensure("implicit units convert implicitly to regular values", int_val == 16);
+
+ // conversion of implicits
+ LLUnitImplicit<F32, Latinum> latinum_implicit(2);
+ ensure("implicit units of different types are comparable", latinum_implicit * 2 == quatloos_implicit);
+
+ quatloos_implicit += F32Quatloos(10);
+ ensure("can add-assign explicit units", quatloos_implicit == 26);
+
+ quatloos_implicit -= F32Quatloos(10);
+ ensure("can subtract-assign explicit units", quatloos_implicit == 16);
+
+ // comparisons
+ ensure("can compare greater than implicit unit", quatloos_implicit > F32QuatloosImplicit(0.f));
+ ensure("can compare greater than non-implicit unit", quatloos_implicit > F32Quatloos(0.f));
+ ensure("can compare greater than or equal to implicit unit", quatloos_implicit >= F32QuatloosImplicit(0.f));
+ ensure("can compare greater than or equal to non-implicit unit", quatloos_implicit >= F32Quatloos(0.f));
+ ensure("can compare less than implicit unit", quatloos_implicit < F32QuatloosImplicit(20.f));
+ ensure("can compare less than non-implicit unit", quatloos_implicit < F32Quatloos(20.f));
+ ensure("can compare less than or equal to implicit unit", quatloos_implicit <= F32QuatloosImplicit(20.f));
+ ensure("can compare less than or equal to non-implicit unit", quatloos_implicit <= F32Quatloos(20.f));
+ }
+
+ // precision tests
+ template<> template<>
+ void units_object_t::test<8>()
+ {
+ U32Bytes max_bytes(U32_MAX);
+ S32Megabytes mega_bytes = max_bytes;
+ ensure("max available precision is used when converting units", mega_bytes == (S32Megabytes)4095);
+
+ mega_bytes = (S32Megabytes)-5 + (U32Megabytes)1;
+ ensure("can mix signed and unsigned in units addition", mega_bytes == (S32Megabytes)-4);
+
+ mega_bytes = (U32Megabytes)5 + (S32Megabytes)-1;
+ ensure("can mix unsigned and signed in units addition", mega_bytes == (S32Megabytes)4);
+ }
+
+ // default units
+ template<> template<>
+ void units_object_t::test<9>()
+ {
+ U32Gigabytes GB(1);
+ U32Megabytes MB(GB);
+ U32Kilobytes KB(GB);
+ U32Bytes B(GB);
+
+ ensure("GB -> MB conversion", MB.value() == 1024);
+ ensure("GB -> KB conversion", KB.value() == 1024 * 1024);
+ ensure("GB -> B conversion", B.value() == 1024 * 1024 * 1024);
+
+ KB = U32Kilobytes(1);
+ U32Kilobits Kb(KB);
+ U32Bits b(KB);
+ ensure("KB -> Kb conversion", Kb.value() == 8);
+ ensure("KB -> b conversion", b.value() == 8 * 1024);
+
+ U32Days days(1);
+ U32Hours hours(days);
+ U32Minutes minutes(days);
+ U32Seconds seconds(days);
+ U32Milliseconds ms(days);
+
+ ensure("days -> hours conversion", hours.value() == 24);
+ ensure("days -> minutes conversion", minutes.value() == 24 * 60);
+ ensure("days -> seconds conversion", seconds.value() == 24 * 60 * 60);
+ ensure("days -> ms conversion", ms.value() == 24 * 60 * 60 * 1000);
+
+ U32Kilometers km(1);
+ U32Meters m(km);
+ U32Centimeters cm(km);
+ U32Millimeters mm(km);
+
+ ensure("km -> m conversion", m.value() == 1000);
+ ensure("km -> cm conversion", cm.value() == 1000 * 100);
+ ensure("km -> mm conversion", mm.value() == 1000 * 1000);
+
+ U32Gigahertz GHz(1);
+ U32Megahertz MHz(GHz);
+ U32Kilohertz KHz(GHz);
+ U32Hertz Hz(GHz);
+
+ ensure("GHz -> MHz conversion", MHz.value() == 1000);
+ ensure("GHz -> KHz conversion", KHz.value() == 1000 * 1000);
+ ensure("GHz -> Hz conversion", Hz.value() == 1000 * 1000 * 1000);
+
+ F32Radians rad(6.2831853071795f);
+ S32Degrees deg(rad);
+ ensure("radians -> degrees conversion", deg.value() == 360);
+
+ F32Percent percent(50);
+ F32Ratio ratio(percent);
+ ensure("percent -> ratio conversion", ratio.value() == 0.5f);
+
+ U32Kilotriangles ktris(1);
+ U32Triangles tris(ktris);
+ ensure("kilotriangles -> triangles conversion", tris.value() == 1000);
+ }
+
+ bool value_near(F32 value, F32 target, F32 threshold)
+ {
+ return fabsf(value - target) < threshold;
+ }
+
+ // linear transforms
+ template<> template<>
+ void units_object_t::test<10>()
+ {
+ F32Celcius float_celcius(100);
+ F32Fahrenheit float_fahrenheit(float_celcius);
+ ensure("floating point celcius -> fahrenheit conversion using linear transform", value_near(float_fahrenheit.value(), 212, 0.1f) );
+
+ float_celcius = float_fahrenheit;
+ ensure("floating point fahrenheit -> celcius conversion using linear transform (round trip)", value_near(float_celcius.value(), 100.f, 0.1f) );
+
+ S32Celcius int_celcius(100);
+ S32Fahrenheit int_fahrenheit(int_celcius);
+ ensure("integer celcius -> fahrenheit conversion using linear transform", int_fahrenheit.value() == 212);
+
+ int_celcius = int_fahrenheit;
+ ensure("integer fahrenheit -> celcius conversion using linear transform (round trip)", int_celcius.value() == 100);
+ }
}