summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/lltraceaccumulators.cpp1
-rw-r--r--indra/llcommon/llunit.h23
-rw-r--r--indra/llcommon/tests/llunits_test.cpp16
3 files changed, 33 insertions, 7 deletions
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index c79c102afd..5e25ad6b26 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -147,7 +147,6 @@ void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppen
if (other.mTotalSamplingTime > epsilon)
{
- llassert(mTotalSamplingTime > 0);
// combine variance (and hence standard deviation) of 2 different sized sample groups using
// the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
F64 n_1 = mTotalSamplingTime,
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index f42456fe72..bfc011bb55 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -69,6 +69,12 @@ struct LLResultTypeDivide
typedef LL_TYPEOF(S() / T(1)) type_t;
};
+template<typename S, typename T>
+struct LLResultTypePromote
+{
+ typedef LL_TYPEOF((true) ? S() : T()) type_t;
+};
+
template<typename STORAGE_TYPE, typename UNIT_TYPE>
struct LLUnit
{
@@ -155,10 +161,11 @@ struct LLUnit
template<typename SOURCE_STORAGE, typename SOURCE_UNITS>
static self_t convert(LLUnit<SOURCE_STORAGE, SOURCE_UNITS> v)
{
- self_t result;
- STORAGE_TYPE divisor = ll_convert_units(v, result);
- result.mValue /= divisor;
- return result;
+ typedef typename LLResultTypePromote<STORAGE_TYPE, SOURCE_STORAGE>::type_t result_storage_t;
+ LLUnit<result_storage_t, UNIT_TYPE> result;
+ result_storage_t divisor = ll_convert_units(v, result);
+ result.value(result.value() / divisor);
+ return self_t(result.value());
}
protected:
@@ -695,7 +702,9 @@ struct unit_name
template<typename S1, typename S2> \
S2 ll_convert_units(LLUnit<S1, unit_name> in, LLUnit<S2, base_unit_name>& out) \
{ \
- LLUnitLinearOps<S2> op = LLUnitLinearOps<S2>(in.value()) conversion_operation; \
+ typedef typename LLResultTypePromote<S1, S2>::type_t result_storage_t; \
+ LLUnitLinearOps<result_storage_t> op = \
+ LLUnitLinearOps<result_storage_t>(in.value()) conversion_operation; \
out = LLUnit<S2, base_unit_name>((S2)op.mValue); \
return op.mDivisor; \
} \
@@ -703,7 +712,9 @@ S2 ll_convert_units(LLUnit<S1, unit_name> in, LLUnit<S2, base_unit_name>& out)
template<typename S1, typename S2> \
S2 ll_convert_units(LLUnit<S1, base_unit_name> in, LLUnit<S2, unit_name>& out) \
{ \
- LLUnitInverseLinearOps<S2> op = LLUnitInverseLinearOps<S2>(in.value()) conversion_operation; \
+ typedef typename LLResultTypePromote<S1, S2>::type_t result_storage_t; \
+ LLUnitInverseLinearOps<result_storage_t> op = \
+ LLUnitInverseLinearOps<result_storage_t>(in.value()) conversion_operation; \
out = LLUnit<S2, unit_name>((S2)op.mValue); \
return op.mDivisor; \
}
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index b8aef9d15e..292c6122af 100644
--- a/indra/llcommon/tests/llunits_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -257,4 +257,20 @@ namespace tut
LLUnitImplicit<F32, Latinum> latinum_implicit(2);
ensure("implicit units of different types are comparable", latinum_implicit * 2 == quatloos_implicit);
}
+
+ // 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);
+
+ }
}