summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-08-27 16:36:36 -0700
committerRichard Linden <none@none>2013-08-27 16:36:36 -0700
commit00bd492b30f0dcb49d354be74e6e9a312a84863f (patch)
tree4d0e24dc57090948d7c03d5550a9cf54a00f0bbb
parent014969690bed06d77cc2e08efbd2dc9b71fb0cd2 (diff)
got linear unit conversions (like fahrenheit <-> celsius) working correctly
further optimizations for codegen
-rw-r--r--indra/llcommon/llunittype.h74
-rw-r--r--indra/llcommon/tests/llunits_test.cpp40
2 files changed, 79 insertions, 35 deletions
diff --git a/indra/llcommon/llunittype.h b/indra/llcommon/llunittype.h
index a5e99070b6..50037ccade 100644
--- a/indra/llcommon/llunittype.h
+++ b/indra/llcommon/llunittype.h
@@ -147,35 +147,35 @@ struct LLUnit
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator == (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator == (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue == convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator != (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator != (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue != convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator < (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator < (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue < convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator <= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator <= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue <= convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator > (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator > (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue > convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator >= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator >= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue >= convert(other).value();
}
@@ -193,6 +193,15 @@ struct LLUnit
return result;
}
+ template<typename FROM_UNITS>
+ LL_FORCE_INLINE static self_t convert(LLUnit<STORAGE_TYPE, FROM_UNITS> v)
+ {
+ self_t result;
+ STORAGE_TYPE divisor = ll_convert_units(v, result);
+ result.mValue /= divisor;
+ return result;
+ }
+
template<typename FROM_STORAGE_TYPE, typename FROM_UNITS>
LL_FORCE_INLINE static self_t convert(LLUnit<FROM_STORAGE_TYPE, FROM_UNITS> v)
{
@@ -276,78 +285,78 @@ struct LLUnitImplicit : public LLUnit<STORAGE_TYPE, UNITS>
using base_t::operator ==;
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator == (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator == (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue == convert(other).value();
}
template<typename STORAGE_T>
- LL_FORCE_INLINE bool operator == (STORAGE_T other)
+ LL_FORCE_INLINE bool operator == (STORAGE_T other) const
{
return mValue == other;
}
using base_t::operator !=;
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator != (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator != (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue != convert(other).value();
}
template<typename STORAGE_T>
- LL_FORCE_INLINE bool operator != (STORAGE_T other)
+ LL_FORCE_INLINE bool operator != (STORAGE_T other) const
{
return mValue != other;
}
using base_t::operator <;
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator < (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator < (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue < convert(other).value();
}
template<typename STORAGE_T>
- LL_FORCE_INLINE bool operator < (STORAGE_T other)
+ LL_FORCE_INLINE bool operator < (STORAGE_T other) const
{
return mValue < other;
}
using base_t::operator <=;
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator <= (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator <= (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue <= convert(other).value();
}
template<typename STORAGE_T>
- LL_FORCE_INLINE bool operator <= (STORAGE_T other)
+ LL_FORCE_INLINE bool operator <= (STORAGE_T other) const
{
return mValue <= other;
}
using base_t::operator >;
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator > (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator > (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue > convert(other).value();
}
template<typename STORAGE_T>
- LL_FORCE_INLINE bool operator > (STORAGE_T other)
+ LL_FORCE_INLINE bool operator > (STORAGE_T other) const
{
return mValue > other;
}
using base_t::operator >=;
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
- LL_FORCE_INLINE bool operator >= (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
+ LL_FORCE_INLINE bool operator >= (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue >= convert(other).value();
}
template<typename STORAGE_T>
- LL_FORCE_INLINE bool operator >= (STORAGE_T other)
+ LL_FORCE_INLINE bool operator >= (STORAGE_T other) const
{
return mValue >= other;
}
@@ -670,16 +679,14 @@ struct LLUnitLinearOps
template<typename OTHER_T>
self_t operator + (OTHER_T other)
{
- mValue /= mDivisor;
- mValue += other;
+ mValue += other * mDivisor;
return *this;
}
template<typename OTHER_T>
self_t operator - (OTHER_T other)
{
- mValue /= mDivisor;
- mValue -= other;
+ mValue -= other * mDivisor;
return *this;
}
@@ -694,7 +701,8 @@ struct LLUnitInverseLinearOps
LLUnitInverseLinearOps(T val)
: mValue(val),
- mDivisor(1)
+ mDivisor(1),
+ mMultiplicand(1)
{}
template<typename OTHER_T>
@@ -708,27 +716,27 @@ struct LLUnitInverseLinearOps
self_t operator / (OTHER_T other)
{
mValue *= other;
+ mMultiplicand *= other;
return *this;
}
template<typename OTHER_T>
self_t operator + (OTHER_T other)
{
- mValue /= mDivisor;
- mValue -= other;
+ mValue -= other * mMultiplicand;
return *this;
}
template<typename OTHER_T>
self_t operator - (OTHER_T other)
{
- mValue /= mDivisor;
- mValue += other;
+ mValue += other * mMultiplicand;
return *this;
}
T mValue;
T mDivisor;
+ T mMultiplicand;
};
#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \
@@ -762,20 +770,20 @@ template<typename S1, typename S2>
LL_FORCE_INLINE S2 ll_convert_units(LLUnit<S1, unit_name> in, LLUnit<S2, base_unit_name>& out) \
{ \
typedef typename LLResultTypePromote<S1, S2>::type_t result_storage_t; \
- LLUnitInverseLinearOps<result_storage_t> op = \
+ LLUnitInverseLinearOps<result_storage_t> result = \
LLUnitInverseLinearOps<result_storage_t>(in.value()) conversion_operation; \
- out = LLUnit<S2, base_unit_name>((S2)op.mValue); \
- return op.mDivisor; \
+ out = LLUnit<S2, base_unit_name>((S2)result.mValue); \
+ return result.mDivisor; \
} \
\
template<typename S1, typename S2> \
LL_FORCE_INLINE S2 ll_convert_units(LLUnit<S1, base_unit_name> in, LLUnit<S2, unit_name>& out) \
{ \
typedef typename LLResultTypePromote<S1, S2>::type_t result_storage_t; \
- LLUnitLinearOps<result_storage_t> op = \
+ LLUnitLinearOps<result_storage_t> result = \
LLUnitLinearOps<result_storage_t>(in.value()) conversion_operation; \
- out = LLUnit<S2, unit_name>((S2)op.mValue); \
- return op.mDivisor; \
+ out = LLUnit<S2, unit_name>((S2)result.mValue); \
+ return result.mDivisor; \
}
#define LL_DECLARE_UNIT_TYPEDEFS(ns, unit_name) \
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index 5a18603e4e..59876ce3b4 100644
--- a/indra/llcommon/tests/llunits_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -42,6 +42,18 @@ LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Quatloos);
LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Latinum);
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_UNIT_TYPEDEFS(LLUnits, Celcius);
+LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Fahrenheit);
+LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Kelvin);
+
+
namespace tut
{
using namespace LLUnits;
@@ -328,8 +340,8 @@ namespace tut
ensure("GHz -> Hz conversion", Hz.value() == 1000 * 1000 * 1000);
F32Radians rad(6.2831853071795f);
- F32Degrees deg(rad);
- ensure("radians -> degrees conversion", deg.value() > 359 && deg.value() < 361);
+ S32Degrees deg(rad);
+ ensure("radians -> degrees conversion", deg.value() == 360);
F32Percent percent(50);
F32Ratio ratio(percent);
@@ -339,4 +351,28 @@ namespace tut
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);
+ }
}