summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-12-07 15:20:12 -0800
committerRichard Linden <none@none>2012-12-07 15:20:12 -0800
commitc99886d94389babc78e92bbfa5084fdd785915af (patch)
tree839ffe3031ca296182743cf7af4d7375e2fb3c78 /indra/llcommon
parent3745d1254acc386acaadd20016123c9a47b8d10c (diff)
SH-3406 WIP convert fast timers to lltrace system
improved unit tests for LLUnit renamed LLUnit to LLUnitImplicit with LLUnit being reserved for explicit units
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/llfasttimer.cpp6
-rw-r--r--indra/llcommon/llleap.cpp2
-rw-r--r--indra/llcommon/llprocessor.cpp2
-rw-r--r--indra/llcommon/llprocessor.h2
-rw-r--r--indra/llcommon/lltimer.cpp14
-rw-r--r--indra/llcommon/lltimer.h16
-rw-r--r--indra/llcommon/lltrace.h7
-rw-r--r--indra/llcommon/lltracerecording.h2
-rw-r--r--indra/llcommon/llunit.h193
-rw-r--r--indra/llcommon/tests/llunits_test.cpp (renamed from indra/llcommon/tests/llunit_test.cpp)54
11 files changed, 221 insertions, 79 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index e1f2eb44fd..5b76703af7 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -342,7 +342,7 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(llunit "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index cf7655acf7..37e0fbac0a 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -166,7 +166,7 @@ U64 TimeBlock::countsPerSecond() // counts per second for the *64-bit* timer
firstcall = false;
}
#endif
- return sCPUClockFrequency;
+ return sCPUClockFrequency.value();
}
#endif
@@ -408,7 +408,7 @@ void TimeBlock::nextFrame()
}
call_count++;
- LLUnit<LLUnits::Seconds, F64> total_time = 0;
+ LLUnit<LLUnits::Seconds, F64> total_time(0);
LLSD sd;
{
@@ -479,7 +479,7 @@ void TimeBlock::dumpCurTimes()
}
out_str << timerp->getName() << " "
- << std::setprecision(3) << total_time_ms.as<LLUnits::Milliseconds, F32>() << " ms, "
+ << std::setprecision(3) << total_time_ms.as<LLUnits::Milliseconds, F32>().value() << " ms, "
<< num_calls << " calls";
llinfos << out_str.str() << llendl;
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index 0a57ef1c48..84d2a12f65 100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -394,7 +394,7 @@ public:
LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD nop;
- F64 until(LLTimer::getElapsedSeconds() + 2);
+ F64 until = (LLTimer::getElapsedSeconds() + 2).value();
while (childin.size() && LLTimer::getElapsedSeconds() < until)
{
mainloop.post(nop);
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 6fe53396ca..5ddfa6fcef 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -875,7 +875,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL)
LLProcessorInfo::~LLProcessorInfo() {}
-LLUnit<LLUnits::Megahertz, F64> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
+LLUnitImplicit<LLUnits::Megahertz, F64> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index 2a21a5c115..fbd427f484 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -37,7 +37,7 @@ public:
LLProcessorInfo();
~LLProcessorInfo();
- LLUnit<LLUnits::Megahertz, F64> getCPUFrequency() const;
+ LLUnitImplicit<LLUnits::Megahertz, F64> getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
bool hasAltivec() const;
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 26063beff0..838155d54d 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -285,14 +285,14 @@ LLTimer::~LLTimer()
}
// static
-LLUnit<LLUnits::Microseconds, U64> LLTimer::getTotalTime()
+LLUnitImplicit<LLUnits::Microseconds, U64> LLTimer::getTotalTime()
{
// simply call into the implementation function.
return totalTime();
}
// static
-LLUnit<LLUnits::Seconds, F64> LLTimer::getTotalSeconds()
+LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getTotalSeconds()
{
return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;
}
@@ -341,23 +341,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)
}
-LLUnit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeF64() const
+LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeF64() const
{
U64 last = mLastClockCount;
return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;
}
-LLUnit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeF32() const
+LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeF32() const
{
return (F32)getElapsedTimeF64();
}
-LLUnit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeAndResetF64()
+LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeAndResetF64()
{
return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;
}
-LLUnit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeAndResetF32()
+LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeAndResetF32()
{
return (F32)getElapsedTimeAndResetF64();
}
@@ -370,7 +370,7 @@ void LLTimer::setTimerExpirySec(F32 expiration)
+ (U64)((F32)(expiration * gClockFrequency));
}
-LLUnit<LLUnits::Seconds, F32> LLTimer::getRemainingTimeF32() const
+LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getRemainingTimeF32() const
{
U64 cur_ticks = get_clock_count();
if (cur_ticks > mExpirationTicks)
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index 5cb2b18111..0ba87d1e15 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -67,16 +67,16 @@ public:
// Return a high precision number of seconds since the start of
// this application instance.
- static LLUnit<LLUnits::Seconds, F64> getElapsedSeconds()
+ static LLUnitImplicit<LLUnits::Seconds, F64> getElapsedSeconds()
{
return sTimer->getElapsedTimeF64();
}
// Return a high precision usec since epoch
- static LLUnit<LLUnits::Microseconds, U64> getTotalTime();
+ static LLUnitImplicit<LLUnits::Microseconds, U64> getTotalTime();
// Return a high precision seconds since epoch
- static LLUnit<LLUnits::Seconds, F64> getTotalSeconds();
+ static LLUnitImplicit<LLUnits::Seconds, F64> getTotalSeconds();
// MANIPULATORS
@@ -87,16 +87,16 @@ public:
void setTimerExpirySec(F32 expiration);
BOOL checkExpirationAndReset(F32 expiration);
BOOL hasExpired() const;
- LLUnit<LLUnits::Seconds, F32> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
- LLUnit<LLUnits::Seconds, F64> getElapsedTimeAndResetF64();
+ LLUnitImplicit<LLUnits::Seconds, F32> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
+ LLUnitImplicit<LLUnits::Seconds, F64> getElapsedTimeAndResetF64();
- LLUnit<LLUnits::Seconds, F32> getRemainingTimeF32() const;
+ LLUnitImplicit<LLUnits::Seconds, F32> getRemainingTimeF32() const;
static BOOL knownBadTimer();
// ACCESSORS
- LLUnit<LLUnits::Seconds, F32> getElapsedTimeF32() const; // Returns elapsed time in seconds
- LLUnit<LLUnits::Seconds, F64> getElapsedTimeF64() const; // Returns elapsed time in seconds
+ LLUnitImplicit<LLUnits::Seconds, F32> getElapsedTimeF32() const; // Returns elapsed time in seconds
+ LLUnitImplicit<LLUnits::Seconds, F64> getElapsedTimeF64() const; // Returns elapsed time in seconds
bool getStarted() const { return mStarted; }
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 6e6bb51e47..25d95d9670 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -435,6 +435,9 @@ namespace LLTrace
class TraceType<TimeBlockAccumulator::CallCountAspect>
: public TraceType<TimeBlockAccumulator>
{
+ public:
+ typedef F32 mean_t;
+
TraceType(const char* name, const char* description = "")
: TraceType<TimeBlockAccumulator>(name, description)
{}
@@ -465,7 +468,7 @@ namespace LLTrace
void sample(UNIT_T value)
{
T converted_value(value);
- getPrimaryAccumulator().sample((storage_t)converted_value);
+ getPrimaryAccumulator().sample(LLUnits::rawValue(converted_value));
}
};
@@ -484,7 +487,7 @@ namespace LLTrace
void add(UNIT_T value)
{
T converted_value(value);
- getPrimaryAccumulator().add((storage_t)converted_value);
+ getPrimaryAccumulator().add(LLUnits::rawValue(converted_value));
}
};
}
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 6fd1a105d3..f92281cea8 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -205,7 +205,7 @@ namespace LLTrace
U32 getSampleCount(const TraceType<MeasurementAccumulator<F64> >& stat) const;
U32 getSampleCount(const TraceType<MeasurementAccumulator<S64> >& stat) const;
- LLUnit<LLUnits::Seconds, F64> getDuration() const { return mElapsedSeconds; }
+ LLUnit<LLUnits::Seconds, F64> getDuration() const { return LLUnit<LLUnits::Seconds, F64>(mElapsedSeconds); }
private:
friend class ThreadRecorder;
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index 1f3ed0237c..6b023f8287 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -65,6 +65,7 @@ struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG, VALUE_TYPE>
return 1;
}
};
+
}
template<typename UNIT_TYPE, typename STORAGE_TYPE>
@@ -73,25 +74,25 @@ struct LLUnit
typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> self_t;
typedef STORAGE_TYPE storage_t;
+ // value initialization
LLUnit(storage_t value = storage_t())
: mValue(value)
{}
+ // unit initialization and conversion
template<typename OTHER_UNIT, typename OTHER_STORAGE>
LLUnit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
: mValue(convert(other))
{}
-
- LLUnit(self_t& other)
- : mValue(other.mValue)
- {}
-
+
+ // value assignment
self_t& operator = (storage_t value)
{
mValue = value;
return *this;
}
+ // unit assignment
template<typename OTHER_UNIT, typename OTHER_STORAGE>
self_t& operator = (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
{
@@ -99,11 +100,6 @@ struct LLUnit
return *this;
}
- operator storage_t() const
- {
- return value();
- }
-
storage_t value() const
{
return mValue;
@@ -157,7 +153,7 @@ struct LLUnit
void operator /= (LLUnit<OTHER_UNIT, OTHER_STORAGE> divisor)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
- llstatic_assert(sizeof(OTHER_UNIT) == 0, "Division of unit types not supported.");
+ llstatic_assert(sizeof(OTHER_UNIT) == 0, "Illegal in-place division of unit types.");
}
template<typename SOURCE_UNITS, typename SOURCE_STORAGE>
@@ -169,34 +165,30 @@ struct LLUnit
}
protected:
-
storage_t mValue;
};
template<typename UNIT_TYPE, typename STORAGE_TYPE>
-struct LLUnitStrict : public LLUnit<UNIT_TYPE, STORAGE_TYPE>
+struct LLUnitImplicit : public LLUnit<UNIT_TYPE, STORAGE_TYPE>
{
- typedef LLUnitStrict<UNIT_TYPE, STORAGE_TYPE> self_t;
+ typedef LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> self_t;
typedef typename LLUnit<UNIT_TYPE, STORAGE_TYPE>::storage_t storage_t;
+ typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> base_t;
- explicit LLUnitStrict(storage_t value = storage_t())
- : LLUnit<UNIT_TYPE, STORAGE_TYPE>(value)
+ LLUnitImplicit(storage_t value = storage_t())
+ : base_t(value)
{}
template<typename OTHER_UNIT, typename OTHER_STORAGE>
- LLUnitStrict(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
- : LLUnit<UNIT_TYPE, STORAGE_TYPE>(convert(other))
+ LLUnitImplicit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
+ : base_t(convert(other))
{}
- LLUnitStrict(self_t& other)
- : LLUnit<UNIT_TYPE, STORAGE_TYPE>(other)
- {}
-
-
-private:
+ // unlike LLUnit, LLUnitImplicit is *implicitly* convertable to a POD scalar (F32, S32, etc)
+ // this allows for interoperability with legacy code
operator storage_t() const
{
- return LLUnit<UNIT_TYPE, STORAGE_TYPE>::value();
+ return value();
}
};
@@ -204,7 +196,7 @@ private:
// operator +
//
template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
-LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
+LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
{
LLUnit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
result += second;
@@ -227,6 +219,30 @@ LLUnit<UNIT_TYPE, STORAGE_TYPE> operator + (SCALAR_TYPE first, LLUnit<UNIT_TYPE,
return result;
}
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
+{
+ LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ result += second;
+ return result;
+}
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator + (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
+{
+ LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ result += second;
+ return result;
+}
+
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second)
+{
+ LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ result += second;
+ return result;
+}
+
//
// operator -
//
@@ -238,7 +254,6 @@ LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator - (LLUnit<UNIT_TYPE1, STORAGE_TYPE1>
return result;
}
-
template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
LLUnit<UNIT_TYPE, STORAGE_TYPE> operator - (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
{
@@ -255,6 +270,30 @@ LLUnit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnit<UNIT_TYPE,
return result;
}
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator - (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second)
+{
+ LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator - (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
+{
+ LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> second)
+{
+ LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ result -= second;
+ return result;
+}
+
//
// operator *
//
@@ -278,6 +317,26 @@ LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnit<UNIT_TYPE1, STORAGE_TYPE1>,
return LLUnit<UNIT_TYPE1, STORAGE_TYPE1>();
}
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator * (SCALAR_TYPE first, LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> second)
+{
+ return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first * second.value());
+}
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator * (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
+{
+ return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first.value() * second);
+}
+
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2>)
+{
+ // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
+ llstatic_assert(sizeof(STORAGE_TYPE1) == 0, "Multiplication of unit types results in new unit type - not supported.");
+ return LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>();
+}
+
//
// operator /
//
@@ -300,23 +359,42 @@ STORAGE_TYPE1 operator / (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_T
return STORAGE_TYPE1(first.value() / second.value());
}
-#define COMPARISON_OPERATORS(op) \
-template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> \
-bool operator op (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) \
-{ \
- return first op second.value(); \
-} \
- \
-template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> \
-bool operator op (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) \
-{ \
- return first.value() op second; \
-} \
- \
-template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> \
-bool operator op (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second) \
-{ \
- return first.value() op first.convert(second); \
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator / (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
+{
+ return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first.value() / second);
+}
+
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+STORAGE_TYPE1 operator / (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second)
+{
+ // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
+ return STORAGE_TYPE1(first.value() / second.value());
+}
+
+#define COMPARISON_OPERATORS(op) \
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> \
+bool operator op (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) \
+{ \
+ return first op second.value(); \
+} \
+ \
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> \
+bool operator op (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) \
+{ \
+ return first.value() op second; \
+} \
+ \
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> \
+bool operator op (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second); \
+} \
+ \
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> \
+ bool operator op (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second); \
}
COMPARISON_OPERATORS(<)
@@ -328,6 +406,15 @@ COMPARISON_OPERATORS(!=)
namespace LLUnits
{
+template<typename T>
+T rawValue(T val) { return val; }
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+STORAGE_TYPE rawValue(LLUnit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); }
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+STORAGE_TYPE rawValue(LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); }
+
template<typename UNIT_TYPE, typename STORAGE_TYPE>
struct HighestPrecisionType<LLUnit<UNIT_TYPE, STORAGE_TYPE> >
{
@@ -361,22 +448,22 @@ struct Bytes { typedef Bytes base_unit_t; };
LL_DECLARE_DERIVED_UNIT(1024, Bytes, Kilobytes);
LL_DECLARE_DERIVED_UNIT(1024 * 1024, Bytes, Megabytes);
LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024, Bytes, Gigabytes);
-LL_DECLARE_DERIVED_UNIT((1.0 / 8.0), Bytes, Bits);
-LL_DECLARE_DERIVED_UNIT((1024 / 8), Bytes, Kilobits);
-LL_DECLARE_DERIVED_UNIT((1024 / 8), Bytes, Megabits);
-LL_DECLARE_DERIVED_UNIT((1024 * 1024 * 1024 / 8), Bytes, Gigabits);
+LL_DECLARE_DERIVED_UNIT(1.0 / 8.0, Bytes, Bits);
+LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Kilobits);
+LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Megabits);
+LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024 / 8, Bytes, Gigabits);
struct Seconds { typedef Seconds base_unit_t; };
LL_DECLARE_DERIVED_UNIT(60, Seconds, Minutes);
LL_DECLARE_DERIVED_UNIT(60 * 60, Seconds, Hours);
-LL_DECLARE_DERIVED_UNIT((1.0 / 1000.0), Seconds, Milliseconds);
-LL_DECLARE_DERIVED_UNIT((1.0 / (1000000.0)), Seconds, Microseconds);
-LL_DECLARE_DERIVED_UNIT((1.0 / (1000000000.0)), Seconds, Nanoseconds);
+LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Seconds, Milliseconds);
+LL_DECLARE_DERIVED_UNIT(1.0 / 1000000.0, Seconds, Microseconds);
+LL_DECLARE_DERIVED_UNIT(1.0 / 1000000000.0, Seconds, Nanoseconds);
struct Meters { typedef Meters base_unit_t; };
LL_DECLARE_DERIVED_UNIT(1000, Meters, Kilometers);
-LL_DECLARE_DERIVED_UNIT((1.0 / 100.0), Meters, Centimeters);
-LL_DECLARE_DERIVED_UNIT((1.0 / 1000.0), Meters, Millimeters);
+LL_DECLARE_DERIVED_UNIT(1.0 / 100.0, Meters, Centimeters);
+LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Meters, Millimeters);
struct Hertz { typedef Hertz base_unit_t; };
LL_DECLARE_DERIVED_UNIT(1000, Hertz, Kilohertz);
diff --git a/indra/llcommon/tests/llunit_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index a7e9c00740..2a941e8229 100644
--- a/indra/llcommon/tests/llunit_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -68,7 +68,7 @@ namespace tut
ensure(int_quatloos.value() == 42);
float_quatloos = 42.1f;
- ensure(float_quatloos == 42.1f);
+ ensure(float_quatloos.value() == 42.1f);
int_quatloos = float_quatloos;
ensure(int_quatloos.value() == 42);
LLUnit<Quatloos, U32> unsigned_int_quatloos(float_quatloos);
@@ -153,4 +153,56 @@ namespace tut
quatloos -= LLUnit<Latinum, F32>(1.f);
ensure(quatloos.value() == 1);
}
+
+ // implicit units
+ template<> template<>
+ void units_object_t::test<5>()
+ {
+ // 0-initialized
+ LLUnit<Quatloos, F32> quatloos(0);
+ // initialize implicit unit from explicit
+ LLUnitImplicit<Quatloos, F32> quatloos_implicit = quatloos + 1;
+ ensure(quatloos_implicit.value() == 1);
+
+ // assign implicit to explicit, or perform math operations
+ quatloos = quatloos_implicit;
+ ensure(quatloos.value() == 1);
+ quatloos += quatloos_implicit;
+ ensure(quatloos.value() == 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(float_val == 16);
+
+ S32 int_val = quatloos_implicit;
+ ensure(int_val == 16);
+ }
}