summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-06-17 01:20:27 -0700
committerRichard Linden <none@none>2013-06-17 01:20:27 -0700
commit1cb0c974ae410479a1f72dab556ef7c9371970ee (patch)
tree91a97b4b05e8085fdad17173b7ca874bb98a8805 /indra/llcommon
parentfc88265cffe3553803314c6e895a1e3a3c988171 (diff)
parent3f2de87340b1c831ea59e4a3ca960d49f343c9fd (diff)
Merge
Diffstat (limited to 'indra/llcommon')
-rwxr-xr-xindra/llcommon/llcriticaldamp.cpp2
-rwxr-xr-xindra/llcommon/llcriticaldamp.h4
-rwxr-xr-xindra/llcommon/lldate.cpp2
-rwxr-xr-xindra/llcommon/lldate.h2
-rwxr-xr-xindra/llcommon/llfasttimer.cpp18
-rwxr-xr-xindra/llcommon/llfasttimer.h2
-rwxr-xr-xindra/llcommon/llprocessor.cpp2
-rwxr-xr-xindra/llcommon/llprocessor.h2
-rwxr-xr-xindra/llcommon/lltimer.cpp14
-rwxr-xr-xindra/llcommon/lltimer.h16
-rw-r--r--indra/llcommon/lltrace.h86
-rw-r--r--indra/llcommon/lltracerecording.cpp200
-rw-r--r--indra/llcommon/lltracerecording.h58
-rw-r--r--indra/llcommon/llunit.h442
-rw-r--r--indra/llcommon/tests/llunits_test.cpp110
15 files changed, 530 insertions, 430 deletions
diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp
index 2f013fe255..575fc4149e 100755
--- a/indra/llcommon/llcriticaldamp.cpp
+++ b/indra/llcommon/llcriticaldamp.cpp
@@ -81,7 +81,7 @@ void LLSmoothInterpolation::updateInterpolants()
//-----------------------------------------------------------------------------
// getInterpolant()
//-----------------------------------------------------------------------------
-F32 LLSmoothInterpolation::getInterpolant(LLUnit<LLUnits::Seconds, F32> time_constant, bool use_cache)
+F32 LLSmoothInterpolation::getInterpolant(LLUnit<F32, LLUnits::Seconds> time_constant, bool use_cache)
{
if (time_constant == 0.f)
{
diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h
index ab5d4ba6e2..e174643cd0 100755
--- a/indra/llcommon/llcriticaldamp.h
+++ b/indra/llcommon/llcriticaldamp.h
@@ -42,10 +42,10 @@ public:
static void updateInterpolants();
// ACCESSORS
- static F32 getInterpolant(LLUnit<LLUnits::Seconds, F32> time_constant, bool use_cache = true);
+ static F32 getInterpolant(LLUnit<F32, LLUnits::Seconds> time_constant, bool use_cache = true);
template<typename T>
- static T lerp(T a, T b, LLUnit<LLUnits::Seconds, F32> time_constant, bool use_cache = true)
+ static T lerp(T a, T b, LLUnit<F32, LLUnits::Seconds> time_constant, bool use_cache = true)
{
F32 interpolant = getInterpolant(time_constant, use_cache);
return ((a * (1.f - interpolant))
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 2efe39e158..7892269e35 100755
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -55,7 +55,7 @@ LLDate::LLDate(const LLDate& date) :
mSecondsSinceEpoch(date.mSecondsSinceEpoch)
{}
-LLDate::LLDate(LLUnit<LLUnits::Seconds, F64> seconds_since_epoch) :
+LLDate::LLDate(LLUnit<F64, LLUnits::Seconds> seconds_since_epoch) :
mSecondsSinceEpoch(seconds_since_epoch.value())
{}
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index b62a846147..1067ac5280 100755
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -59,7 +59,7 @@ public:
*
* @param seconds_since_epoch The number of seconds since UTC epoch.
*/
- LLDate(LLUnit<LLUnits::Seconds, F64> seconds_since_epoch);
+ LLDate(LLUnit<F64, LLUnits::Seconds> seconds_since_epoch);
/**
* @brief Construct a date from a string representation
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index dfc72bd2ce..d9670891f8 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -146,8 +146,8 @@ U64 TimeBlock::countsPerSecond()
{
#if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS
//getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz
- static LLUnit<LLUnits::Hertz, U64> sCPUClockFrequency = LLProcessorInfo().getCPUFrequency();
-
+ static LLUnit<U64, LLUnits::Hertz> sCPUClockFrequency = LLProcessorInfo().getCPUFrequency();
+ return sCPUClockFrequency.value();
#else
// If we're not using RDTSC, each fasttimer tick is just a performance counter tick.
// Not redefining the clock frequency itself (in llprocessor.cpp/calculate_cpu_frequency())
@@ -159,8 +159,8 @@ U64 TimeBlock::countsPerSecond()
QueryPerformanceFrequency((LARGE_INTEGER*)&sCPUClockFrequency);
firstcall = false;
}
-#endif
return sCPUClockFrequency.value();
+#endif
}
#endif
@@ -318,11 +318,11 @@ void TimeBlock::logStats()
LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL;
LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL;
LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL;
- LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64()) / (LLUnit<LLUnits::Hertz, F64>(LLProcessorInfo().getCPUFrequency())) << LL_ENDL;
+ LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64()) / (LLUnit<F64, LLUnits::Hertz>(LLProcessorInfo().getCPUFrequency())) << LL_ENDL;
}
call_count++;
- LLUnit<LLUnits::Seconds, F64> total_time(0);
+ LLUnit<F64, LLUnits::Seconds> total_time(0);
LLSD sd;
{
@@ -365,11 +365,11 @@ void TimeBlock::dumpCurTimes()
++it)
{
TimeBlock* timerp = (*it);
- LLUnit<LLUnits::Seconds, F64> total_time_ms = last_frame_recording.getSum(*timerp);
+ LLUnit<F64, LLUnits::Seconds> total_time = last_frame_recording.getSum(*timerp);
U32 num_calls = last_frame_recording.getSum(timerp->callCount());
// Don't bother with really brief times, keep output concise
- if (total_time_ms < 0.1) continue;
+ if (total_time < LLUnit<F32, LLUnits::Milliseconds>(0.1)) continue;
std::ostringstream out_str;
TimeBlock* parent_timerp = timerp;
@@ -380,7 +380,7 @@ void TimeBlock::dumpCurTimes()
}
out_str << timerp->getName() << " "
- << std::setprecision(3) << total_time_ms.as<LLUnits::Milliseconds>().value() << " ms, "
+ << std::setprecision(3) << total_time.getAs<LLUnits::Milliseconds>() << " ms, "
<< num_calls << " calls";
llinfos << out_str.str() << llendl;
@@ -449,7 +449,7 @@ void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other )
}
}
-LLUnit<LLUnits::Seconds, F64> BlockTimer::getElapsedTime()
+LLUnit<F64, LLUnits::Seconds> BlockTimer::getElapsedTime()
{
U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime;
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 20514d1638..fdc6997d45 100755
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -71,7 +71,7 @@ public:
BlockTimer(TimeBlock& timer);
~BlockTimer();
- LLUnit<LLUnits::Seconds, F64> getElapsedTime();
+ LLUnit<F64, LLUnits::Seconds> getElapsedTime();
private:
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 5ddfa6fcef..b80e813d84 100755
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -875,7 +875,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL)
LLProcessorInfo::~LLProcessorInfo() {}
-LLUnitImplicit<LLUnits::Megahertz, F64> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
+LLUnitImplicit<F64, LLUnits::Megahertz> 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 fbd427f484..7f220467b0 100755
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -37,7 +37,7 @@ public:
LLProcessorInfo();
~LLProcessorInfo();
- LLUnitImplicit<LLUnits::Megahertz, F64> getCPUFrequency() const;
+ LLUnitImplicit<F64, LLUnits::Megahertz> getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
bool hasAltivec() const;
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 838155d54d..693809b622 100755
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -285,14 +285,14 @@ LLTimer::~LLTimer()
}
// static
-LLUnitImplicit<LLUnits::Microseconds, U64> LLTimer::getTotalTime()
+LLUnitImplicit<U64, LLUnits::Microseconds> LLTimer::getTotalTime()
{
// simply call into the implementation function.
return totalTime();
}
// static
-LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getTotalSeconds()
+LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getTotalSeconds()
{
return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;
}
@@ -341,23 +341,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)
}
-LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeF64() const
+LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getElapsedTimeF64() const
{
U64 last = mLastClockCount;
return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;
}
-LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeF32() const
+LLUnitImplicit<F32, LLUnits::Seconds> LLTimer::getElapsedTimeF32() const
{
return (F32)getElapsedTimeF64();
}
-LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeAndResetF64()
+LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getElapsedTimeAndResetF64()
{
return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;
}
-LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeAndResetF32()
+LLUnitImplicit<F32, LLUnits::Seconds> LLTimer::getElapsedTimeAndResetF32()
{
return (F32)getElapsedTimeAndResetF64();
}
@@ -370,7 +370,7 @@ void LLTimer::setTimerExpirySec(F32 expiration)
+ (U64)((F32)(expiration * gClockFrequency));
}
-LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getRemainingTimeF32() const
+LLUnitImplicit<F32, LLUnits::Seconds> 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 0ba87d1e15..9e464c4b1a 100755
--- 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 LLUnitImplicit<LLUnits::Seconds, F64> getElapsedSeconds()
+ static LLUnitImplicit<F64, LLUnits::Seconds> getElapsedSeconds()
{
return sTimer->getElapsedTimeF64();
}
// Return a high precision usec since epoch
- static LLUnitImplicit<LLUnits::Microseconds, U64> getTotalTime();
+ static LLUnitImplicit<U64, LLUnits::Microseconds> getTotalTime();
// Return a high precision seconds since epoch
- static LLUnitImplicit<LLUnits::Seconds, F64> getTotalSeconds();
+ static LLUnitImplicit<F64, LLUnits::Seconds> getTotalSeconds();
// MANIPULATORS
@@ -87,16 +87,16 @@ public:
void setTimerExpirySec(F32 expiration);
BOOL checkExpirationAndReset(F32 expiration);
BOOL hasExpired() const;
- LLUnitImplicit<LLUnits::Seconds, F32> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
- LLUnitImplicit<LLUnits::Seconds, F64> getElapsedTimeAndResetF64();
+ LLUnitImplicit<F32, LLUnits::Seconds> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
+ LLUnitImplicit<F64, LLUnits::Seconds> getElapsedTimeAndResetF64();
- LLUnitImplicit<LLUnits::Seconds, F32> getRemainingTimeF32() const;
+ LLUnitImplicit<F32, LLUnits::Seconds> getRemainingTimeF32() const;
static BOOL knownBadTimer();
// ACCESSORS
- LLUnitImplicit<LLUnits::Seconds, F32> getElapsedTimeF32() const; // Returns elapsed time in seconds
- LLUnitImplicit<LLUnits::Seconds, F64> getElapsedTimeF64() const; // Returns elapsed time in seconds
+ LLUnitImplicit<F32, LLUnits::Seconds> getElapsedTimeF32() const; // Returns elapsed time in seconds
+ LLUnitImplicit<F64, LLUnits::Seconds> 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 cfe1273b4b..cd377531e8 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -44,27 +44,37 @@ namespace LLTrace
{
class Recording;
-typedef LLUnit<LLUnits::Bytes, F64> Bytes;
-typedef LLUnit<LLUnits::Kibibytes, F64> Kibibytes;
-typedef LLUnit<LLUnits::Mibibytes, F64> Mibibytes;
-typedef LLUnit<LLUnits::Gibibytes, F64> Gibibytes;
-typedef LLUnit<LLUnits::Bits, F64> Bits;
-typedef LLUnit<LLUnits::Kibibits, F64> Kibibits;
-typedef LLUnit<LLUnits::Mibibits, F64> Mibibits;
-typedef LLUnit<LLUnits::Gibibits, F64> Gibibits;
-
-typedef LLUnit<LLUnits::Seconds, F64> Seconds;
-typedef LLUnit<LLUnits::Milliseconds, F64> Milliseconds;
-typedef LLUnit<LLUnits::Minutes, F64> Minutes;
-typedef LLUnit<LLUnits::Hours, F64> Hours;
-typedef LLUnit<LLUnits::Milliseconds, F64> Milliseconds;
-typedef LLUnit<LLUnits::Microseconds, F64> Microseconds;
-typedef LLUnit<LLUnits::Nanoseconds, F64> Nanoseconds;
-
-typedef LLUnit<LLUnits::Meters, F64> Meters;
-typedef LLUnit<LLUnits::Kilometers, F64> Kilometers;
-typedef LLUnit<LLUnits::Centimeters, F64> Centimeters;
-typedef LLUnit<LLUnits::Millimeters, F64> Millimeters;
+typedef LLUnit<F64, LLUnits::Bytes> Bytes;
+typedef LLUnit<F64, LLUnits::Kibibytes> Kibibytes;
+typedef LLUnit<F64, LLUnits::Mibibytes> Mibibytes;
+typedef LLUnit<F64, LLUnits::Gibibytes> Gibibytes;
+typedef LLUnit<F64, LLUnits::Bits> Bits;
+typedef LLUnit<F64, LLUnits::Kibibits> Kibibits;
+typedef LLUnit<F64, LLUnits::Mibibits> Mibibits;
+typedef LLUnit<F64, LLUnits::Gibibits> Gibibits;
+
+typedef LLUnit<F64, LLUnits::Seconds> Seconds;
+typedef LLUnit<F64, LLUnits::Milliseconds> Milliseconds;
+typedef LLUnit<F64, LLUnits::Minutes> Minutes;
+typedef LLUnit<F64, LLUnits::Hours> Hours;
+typedef LLUnit<F64, LLUnits::Milliseconds> Milliseconds;
+typedef LLUnit<F64, LLUnits::Microseconds> Microseconds;
+typedef LLUnit<F64, LLUnits::Nanoseconds> Nanoseconds;
+
+typedef LLUnit<F64, LLUnits::Meters> Meters;
+typedef LLUnit<F64, LLUnits::Kilometers> Kilometers;
+typedef LLUnit<F64, LLUnits::Centimeters> Centimeters;
+typedef LLUnit<F64, LLUnits::Millimeters> Millimeters;
+
+
+template<typename T>
+T storage_value(T val) { return val; }
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+STORAGE_TYPE storage_value(LLUnit<STORAGE_TYPE, UNIT_TYPE> val) { return val.value(); }
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+STORAGE_TYPE storage_value(LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> val) { return val.value(); }
void init();
void cleanup();
@@ -217,6 +227,11 @@ public:
size_t size() const
{
+ return getNumIndices();
+ }
+
+ static size_t getNumIndices()
+ {
return sNextStorageSlot;
}
@@ -263,6 +278,7 @@ public:
}
size_t getIndex() const { return mAccumulatorIndex; }
+ static size_t getNumIndices() { return AccumulatorBuffer<ACCUMULATOR>::getNumIndices(); }
virtual const char* getUnitLabel() { return ""; }
@@ -408,8 +424,8 @@ public:
void sample(F64 value)
{
- LLUnitImplicit<LLUnits::Seconds, F64> time_stamp = LLTimer::getTotalSeconds();
- LLUnitImplicit<LLUnits::Seconds, F64> delta_time = time_stamp - mLastSampleTimeStamp;
+ LLUnitImplicit<F64, LLUnits::Seconds> time_stamp = LLTimer::getTotalSeconds();
+ LLUnitImplicit<F64, LLUnits::Seconds> delta_time = time_stamp - mLastSampleTimeStamp;
mLastSampleTimeStamp = time_stamp;
if (mHasValue)
@@ -498,8 +514,8 @@ public:
void flush()
{
- LLUnitImplicit<LLUnits::Seconds, F64> time_stamp = LLTimer::getTotalSeconds();
- LLUnitImplicit<LLUnits::Seconds, F64> delta_time = time_stamp - mLastSampleTimeStamp;
+ LLUnitImplicit<F64, LLUnits::Seconds> time_stamp = LLTimer::getTotalSeconds();
+ LLUnitImplicit<F64, LLUnits::Seconds> delta_time = time_stamp - mLastSampleTimeStamp;
if (mHasValue)
{
@@ -528,7 +544,7 @@ private:
F64 mMean,
mVarianceSum;
- LLUnitImplicit<LLUnits::Seconds, F64> mLastSampleTimeStamp,
+ LLUnitImplicit<F64, LLUnits::Seconds> mLastSampleTimeStamp,
mTotalSamplingTime;
U32 mNumSamples;
@@ -578,8 +594,8 @@ private:
class TimeBlockAccumulator
{
public:
- typedef LLUnit<LLUnits::Seconds, F64> value_t;
- typedef LLUnit<LLUnits::Seconds, F64> mean_t;
+ typedef LLUnit<F64, LLUnits::Seconds> value_t;
+ typedef LLUnit<F64, LLUnits::Seconds> mean_t;
typedef TimeBlockAccumulator self_t;
// fake classes that allows us to view different facets of underlying statistic
@@ -591,8 +607,8 @@ public:
struct SelfTimeFacet
{
- typedef LLUnit<LLUnits::Seconds, F64> value_t;
- typedef LLUnit<LLUnits::Seconds, F64> mean_t;
+ typedef LLUnit<F64, LLUnits::Seconds> value_t;
+ typedef LLUnit<F64, LLUnits::Seconds> mean_t;
};
TimeBlockAccumulator();
@@ -672,7 +688,7 @@ template<typename T, typename VALUE_T>
void record(EventStatHandle<T>& measurement, VALUE_T value)
{
T converted_value(value);
- measurement.getPrimaryAccumulator()->record(LLUnits::rawValue(converted_value));
+ measurement.getPrimaryAccumulator()->record(storage_value(converted_value));
}
template <typename T = F64>
@@ -694,7 +710,7 @@ template<typename T, typename VALUE_T>
void sample(SampleStatHandle<T>& measurement, VALUE_T value)
{
T converted_value(value);
- measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value));
+ measurement.getPrimaryAccumulator()->sample(storage_value(converted_value));
}
template <typename T = F64>
@@ -716,7 +732,7 @@ template<typename T, typename VALUE_T>
void add(CountStatHandle<T>& count, VALUE_T value)
{
T converted_value(value);
- count.getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value));
+ count.getPrimaryAccumulator()->add(storage_value(converted_value));
}
@@ -739,8 +755,8 @@ struct MemStatAccumulator
struct ChildMemFacet
{
- typedef LLUnit<LLUnits::Bytes, F64> value_t;
- typedef LLUnit<LLUnits::Bytes, F64> mean_t;
+ typedef LLUnit<F64, LLUnits::Bytes> value_t;
+ typedef LLUnit<F64, LLUnits::Bytes> mean_t;
};
MemStatAccumulator()
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index d32504b014..f2c5941011 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -122,21 +122,26 @@ Recording::Recording()
Recording::Recording( const Recording& other )
{
+ *this = other;
+}
+
+Recording& Recording::operator = (const Recording& other)
+{
// this will allow us to seamlessly start without affecting any data we've acquired from other
setPlayState(PAUSED);
Recording& mutable_other = const_cast<Recording&>(other);
+ mutable_other.update();
EPlayState other_play_state = other.getPlayState();
- mutable_other.pause();
- mBuffers = other.mBuffers;
+ mBuffers = mutable_other.mBuffers;
LLStopWatchControlsMixin<Recording>::setPlayState(other_play_state);
- mutable_other.setPlayState(other_play_state);
// above call will clear mElapsedSeconds as a side effect, so copy it here
mElapsedSeconds = other.mElapsedSeconds;
mSamplingTimer = other.mSamplingTimer;
+ return *this;
}
@@ -186,26 +191,18 @@ void Recording::handleSplitTo(Recording& other)
void Recording::appendRecording( const Recording& other )
{
- EPlayState play_state = getPlayState();
- {
- pause();
- mBuffers.write()->append(*other.mBuffers);
- mElapsedSeconds += other.mElapsedSeconds;
- }
- setPlayState(play_state);
+ update();
+ mBuffers.write()->append(*other.mBuffers);
+ mElapsedSeconds += other.mElapsedSeconds;
}
void Recording::mergeRecording( const Recording& other)
{
- EPlayState play_state = getPlayState();
- {
- pause();
- mBuffers.write()->merge(*other.mBuffers);
- }
- setPlayState(play_state);
+ update();
+ mBuffers.write()->merge(*other.mBuffers);
}
-LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat)
+LLUnit<F64, LLUnits::Seconds> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat)
{
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
update();
@@ -213,7 +210,7 @@ LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumul
/ (F64)LLTrace::TimeBlock::countsPerSecond();
}
-LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
+LLUnit<F64, LLUnits::Seconds> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
{
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
update();
@@ -227,85 +224,85 @@ U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& sta
return mBuffers->mStackTimers[stat.getIndex()].mCalls;
}
-LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat)
+LLUnit<F64, LLUnits::Seconds> Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat)
{
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
update();
return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)
- / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);
+ / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value());
}
-LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
+LLUnit<F64, LLUnits::Seconds> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
{
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
update();
return (F64)(accumulator.mSelfTimeCounter)
- / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);
+ / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value());
}
F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat)
{
update();
- return (F32)mBuffers->mStackTimers[stat.getIndex()].mCalls / mElapsedSeconds;
+ return (F32)mBuffers->mStackTimers[stat.getIndex()].mCalls / mElapsedSeconds.value();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getMin(const TraceType<MemStatAccumulator>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getMin(const TraceType<MemStatAccumulator>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getMin();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getMean(const TraceType<MemStatAccumulator>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getMean(const TraceType<MemStatAccumulator>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getMean();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getMax(const TraceType<MemStatAccumulator>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getMax(const TraceType<MemStatAccumulator>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getMax();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getStandardDeviation(const TraceType<MemStatAccumulator>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getStandardDeviation(const TraceType<MemStatAccumulator>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getStandardDeviation();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getLastValue(const TraceType<MemStatAccumulator>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getLastValue(const TraceType<MemStatAccumulator>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mSize.getLastValue();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMin();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMean();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMax();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getStandardDeviation();
}
-LLUnit<LLUnits::Bytes, F64> Recording::getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+LLUnit<F64, LLUnits::Bytes> Recording::getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
{
update();
return mBuffers->mMemStats[stat.getIndex()].mChildSize.getLastValue();
@@ -341,7 +338,7 @@ F64 Recording::getPerSec( const TraceType<CountAccumulator>& stat )
update();
F64 sum = mBuffers->mCounts[stat.getIndex()].getSum();
return (sum != 0.0)
- ? (sum / mElapsedSeconds)
+ ? (sum / mElapsedSeconds.value())
: 0.0;
}
@@ -430,6 +427,7 @@ U32 Recording::getSampleCount( const TraceType<EventAccumulator>& stat )
PeriodicRecording::PeriodicRecording( U32 num_periods, EPlayState state)
: mAutoResize(num_periods == 0),
mCurPeriod(0),
+ mNumPeriods(0),
mRecordingPeriods(num_periods ? num_periods : 1)
{
setPlayState(state);
@@ -443,9 +441,16 @@ void PeriodicRecording::nextPeriod()
}
Recording& old_recording = getCurRecording();
-
mCurPeriod = (mCurPeriod + 1) % mRecordingPeriods.size();
old_recording.splitTo(getCurRecording());
+
+ mNumPeriods = llmin(mRecordingPeriods.size(), mNumPeriods + 1);
+}
+
+void PeriodicRecording::appendRecording(Recording& recording)
+{
+ getCurRecording().appendRecording(recording);
+ nextPeriod();
}
@@ -453,77 +458,71 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
{
if (other.mRecordingPeriods.empty()) return;
- EPlayState play_state = getPlayState();
- pause();
+ getCurRecording().update();
+ other.getCurRecording().update();
- EPlayState other_play_state = other.getPlayState();
- other.pause();
-
- U32 other_recording_count = other.mRecordingPeriods.size();
-
- Recording& other_oldest_recording = other.mRecordingPeriods[(other.mCurPeriod + 1) % other.mRecordingPeriods.size()];
-
- // if I have a recording of any length, then close it off and start a fresh one
- if (getCurRecording().getDuration().value())
+ if (mAutoResize)
{
- nextPeriod();
- }
- getCurRecording().appendRecording(other_oldest_recording);
+ S32 other_index = (other.mCurPeriod + 1) % other.mRecordingPeriods.size();
+ S32 end_index = (other.mCurPeriod) % other.mRecordingPeriods.size();
- if (other_recording_count > 1)
- {
- if (mAutoResize)
+ do
{
- for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count,
- end_index = (other.mCurPeriod + 1) % other_recording_count;
- other_index != end_index;
- other_index = (other_index + 1) % other_recording_count)
+ if (other.mRecordingPeriods[other_index].getDuration().value())
{
- llassert(other.mRecordingPeriods[other_index].getDuration() != 0.f
- && (mRecordingPeriods.empty()
- || other.mRecordingPeriods[other_index].getDuration() != mRecordingPeriods.back().getDuration()));
mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]);
}
-
- mCurPeriod = mRecordingPeriods.size() - 1;
+ other_index = (other_index + 1) % other.mRecordingPeriods.size();
}
- else
+ while(other_index != end_index);
+
+ mCurPeriod = mRecordingPeriods.size() - 1;
+ mNumPeriods = mRecordingPeriods.size();
+ }
+ else
+ {
+ //FIXME: get proper number of recordings from other...might not have used all its slots
+ size_t num_to_copy = llmin( mRecordingPeriods.size(), other.getNumRecordedPeriods());
+ std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin()
+ + ( (other.mCurPeriod + 1 // oldest period
+ + (other.mRecordingPeriods.size() - num_to_copy)) // minus room for copy
+ % other.mRecordingPeriods.size());
+ std::vector<Recording>::iterator dest_it = mRecordingPeriods.begin() + mCurPeriod;
+
+ for(size_t i = 0; i < num_to_copy; i++)
{
- size_t num_to_copy = llmin( mRecordingPeriods.size(), other.mRecordingPeriods.size() - 1);
- std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin()
- + ( (other.mCurPeriod + 1 // oldest period
- + (other.mRecordingPeriods.size() - num_to_copy)) // minus room for copy
- % other.mRecordingPeriods.size());
- std::vector<Recording>::iterator dest_it = mRecordingPeriods.begin() + ((mCurPeriod + 1) % mRecordingPeriods.size());
-
- for(S32 i = 0; i < num_to_copy; i++)
- {
- *dest_it = *src_it;
+ *dest_it = *src_it;
- if (++src_it == other.mRecordingPeriods.end())
- {
- src_it = other.mRecordingPeriods.begin();
- }
+ if (++src_it == other.mRecordingPeriods.end())
+ {
+ src_it = other.mRecordingPeriods.begin();
+ }
- if (++dest_it == mRecordingPeriods.end())
- {
- dest_it = mRecordingPeriods.begin();
- }
+ if (++dest_it == mRecordingPeriods.end())
+ {
+ dest_it = mRecordingPeriods.begin();
}
-
- mCurPeriod = (mCurPeriod + num_to_copy) % mRecordingPeriods.size();
}
+
+ // want argument to % to be positive, otherwise result could be negative and thus out of bounds
+ llassert(num_to_copy >= 1);
+ // advance to last recording period copied, so we can check if the last period had actually carried any data, in which case we'll advance below
+ // using nextPeriod() which retains continuity (mLastValue, etc)
+ mCurPeriod = (mCurPeriod + num_to_copy - 1) % mRecordingPeriods.size();
+ mNumPeriods = llmin(mRecordingPeriods.size(), mNumPeriods + num_to_copy);
}
- nextPeriod();
-
- setPlayState(play_state);
- other.setPlayState(other_play_state);
+ if (getCurRecording().getDuration().value())
+ {
+ //call this to chain last period copied to new active period
+ nextPeriod();
+ }
+ getCurRecording().setPlayState(getPlayState());
}
-LLUnit<LLUnits::Seconds, F64> PeriodicRecording::getDuration() const
+LLUnit<F64, LLUnits::Seconds> PeriodicRecording::getDuration() const
{
- LLUnit<LLUnits::Seconds, F64> duration;
+ LLUnit<F64, LLUnits::Seconds> duration;
size_t num_periods = mRecordingPeriods.size();
for (size_t i = 1; i <= num_periods; i++)
{
@@ -615,7 +614,7 @@ void PeriodicRecording::handleSplitTo(PeriodicRecording& other)
F64 PeriodicRecording::getPeriodMean( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
F64 mean = 0;
if (num_periods <= 0) { return mean; }
@@ -643,7 +642,7 @@ F64 PeriodicRecording::getPeriodMean( const TraceType<EventAccumulator>& stat, s
F64 PeriodicRecording::getPeriodMin( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
F64 min_val = std::numeric_limits<F64>::max();
for (S32 i = 1; i <= num_periods; i++)
@@ -657,7 +656,7 @@ F64 PeriodicRecording::getPeriodMin( const TraceType<EventAccumulator>& stat, si
F64 PeriodicRecording::getPeriodMax( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
F64 max_val = std::numeric_limits<F64>::min();
for (S32 i = 1; i <= num_periods; i++)
@@ -671,7 +670,7 @@ F64 PeriodicRecording::getPeriodMax( const TraceType<EventAccumulator>& stat, si
F64 PeriodicRecording::getPeriodMin( const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
F64 min_val = std::numeric_limits<F64>::max();
for (S32 i = 1; i <= num_periods; i++)
@@ -685,7 +684,7 @@ F64 PeriodicRecording::getPeriodMin( const TraceType<SampleAccumulator>& stat, s
F64 PeriodicRecording::getPeriodMax(const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/)
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
F64 max_val = std::numeric_limits<F64>::min();
for (S32 i = 1; i <= num_periods; i++)
@@ -700,9 +699,9 @@ F64 PeriodicRecording::getPeriodMax(const TraceType<SampleAccumulator>& stat, si
F64 PeriodicRecording::getPeriodMean( const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
- LLUnit<LLUnits::Seconds, F64> total_duration = 0.f;
+ LLUnit<F64, LLUnits::Seconds> total_duration = 0.f;
F64 mean = 0;
if (num_periods <= 0) { return mean; }
@@ -712,7 +711,7 @@ F64 PeriodicRecording::getPeriodMean( const TraceType<SampleAccumulator>& stat,
S32 index = (mCurPeriod + total_periods - i) % total_periods;
if (mRecordingPeriods[index].getDuration() > 0.f)
{
- LLUnit<LLUnits::Seconds, F64> recording_duration = mRecordingPeriods[index].getDuration();
+ LLUnit<F64, LLUnits::Seconds> recording_duration = mRecordingPeriods[index].getDuration();
mean += mRecordingPeriods[index].getMean(stat) * recording_duration.value();
total_duration += recording_duration;
}
@@ -734,13 +733,11 @@ F64 PeriodicRecording::getPeriodMean( const TraceType<SampleAccumulator>& stat,
void ExtendableRecording::extend()
{
// stop recording to get latest data
- mPotentialRecording.stop();
+ mPotentialRecording.update();
// push the data back to accepted recording
mAcceptedRecording.appendRecording(mPotentialRecording);
// flush data, so we can start from scratch
mPotentialRecording.reset();
- // go back to play state we were in initially
- mPotentialRecording.setPlayState(getPlayState());
}
void ExtendableRecording::handleStart()
@@ -777,15 +774,10 @@ ExtendablePeriodicRecording::ExtendablePeriodicRecording()
void ExtendablePeriodicRecording::extend()
{
- llassert(mPotentialRecording.getPlayState() == getPlayState());
- // stop recording to get latest data
- mPotentialRecording.pause();
// push the data back to accepted recording
mAcceptedRecording.appendPeriodicRecording(mPotentialRecording);
// flush data, so we can start from scratch
mPotentialRecording.reset();
- // go back to play state we were in initially
- mPotentialRecording.setPlayState(getPlayState());
}
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 4651bfcb61..b839e85de0 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -135,6 +135,8 @@ namespace LLTrace
Recording(const Recording& other);
~Recording();
+ Recording& operator = (const Recording& other);
+
// accumulate data from subsequent, non-overlapping recording
void appendRecording(const Recording& other);
@@ -148,26 +150,26 @@ namespace LLTrace
void makeUnique() { mBuffers.makeUnique(); }
// Timer accessors
- LLUnit<LLUnits::Seconds, F64> getSum(const TraceType<TimeBlockAccumulator>& stat);
- LLUnit<LLUnits::Seconds, F64> getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat);
+ LLUnit<F64, LLUnits::Seconds> getSum(const TraceType<TimeBlockAccumulator>& stat);
+ LLUnit<F64, LLUnits::Seconds> getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat);
U32 getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat);
- LLUnit<LLUnits::Seconds, F64> getPerSec(const TraceType<TimeBlockAccumulator>& stat);
- LLUnit<LLUnits::Seconds, F64> getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat);
+ LLUnit<F64, LLUnits::Seconds> getPerSec(const TraceType<TimeBlockAccumulator>& stat);
+ LLUnit<F64, LLUnits::Seconds> getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat);
F32 getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat);
// Memory accessors
- LLUnit<LLUnits::Bytes, F64> getMin(const TraceType<MemStatAccumulator>& stat);
- LLUnit<LLUnits::Bytes, F64> getMean(const TraceType<MemStatAccumulator>& stat);
- LLUnit<LLUnits::Bytes, F64> getMax(const TraceType<MemStatAccumulator>& stat);
- LLUnit<LLUnits::Bytes, F64> getStandardDeviation(const TraceType<MemStatAccumulator>& stat);
- LLUnit<LLUnits::Bytes, F64> getLastValue(const TraceType<MemStatAccumulator>& stat);
-
- LLUnit<LLUnits::Bytes, F64> getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
- LLUnit<LLUnits::Bytes, F64> getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
- LLUnit<LLUnits::Bytes, F64> getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
- LLUnit<LLUnits::Bytes, F64> getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
- LLUnit<LLUnits::Bytes, F64> getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMin(const TraceType<MemStatAccumulator>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMean(const TraceType<MemStatAccumulator>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMax(const TraceType<MemStatAccumulator>& stat);
+ LLUnit<F64, LLUnits::Bytes> getStandardDeviation(const TraceType<MemStatAccumulator>& stat);
+ LLUnit<F64, LLUnits::Bytes> getLastValue(const TraceType<MemStatAccumulator>& stat);
+
+ LLUnit<F64, LLUnits::Bytes> getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
U32 getSum(const TraceType<MemStatAccumulator::AllocationCountFacet>& stat);
U32 getSum(const TraceType<MemStatAccumulator::DeallocationCountFacet>& stat);
@@ -273,7 +275,7 @@ namespace LLTrace
U32 getSampleCount(const TraceType<EventAccumulator>& stat);
- LLUnit<LLUnits::Seconds, F64> getDuration() const { return LLUnit<LLUnits::Seconds, F64>(mElapsedSeconds); }
+ LLUnit<F64, LLUnits::Seconds> getDuration() const { return mElapsedSeconds; }
protected:
friend class ThreadRecorder;
@@ -288,7 +290,7 @@ namespace LLTrace
class ThreadRecorder* getThreadRecorder();
LLTimer mSamplingTimer;
- F64 mElapsedSeconds;
+ LLUnit<F64, LLUnits::Seconds> mElapsedSeconds;
LLCopyOnWritePointer<RecordingBuffers> mBuffers;
};
@@ -299,11 +301,12 @@ namespace LLTrace
PeriodicRecording(U32 num_periods, EPlayState state = STOPPED);
void nextPeriod();
- U32 getNumPeriods() { return mRecordingPeriods.size(); }
+ size_t getNumRecordedPeriods() { return mNumPeriods; }
- LLUnit<LLUnits::Seconds, F64> getDuration() const;
+ LLUnit<F64, LLUnits::Seconds> getDuration() const;
void appendPeriodicRecording(PeriodicRecording& other);
+ void appendRecording(Recording& recording);
Recording& getLastRecording();
const Recording& getLastRecording() const;
Recording& getCurRecording();
@@ -317,7 +320,7 @@ namespace LLTrace
typename T::value_t getPeriodMin(const TraceType<T>& stat, size_t num_periods = U32_MAX)
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
typename T::value_t min_val = std::numeric_limits<typename T::value_t>::max();
for (S32 i = 1; i <= num_periods; i++)
@@ -346,7 +349,7 @@ namespace LLTrace
F64 getPeriodMinPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX)
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
F64 min_val = std::numeric_limits<F64>::max();
for (S32 i = 1; i <= num_periods; i++)
@@ -362,7 +365,7 @@ namespace LLTrace
typename T::value_t getPeriodMax(const TraceType<T>& stat, size_t num_periods = U32_MAX)
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
typename T::value_t max_val = std::numeric_limits<typename T::value_t>::min();
for (S32 i = 1; i <= num_periods; i++)
@@ -391,7 +394,7 @@ namespace LLTrace
F64 getPeriodMaxPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX)
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
F64 max_val = std::numeric_limits<F64>::min();
for (S32 i = 1; i <= num_periods; i++)
@@ -407,7 +410,7 @@ namespace LLTrace
typename T::mean_t getPeriodMean(const TraceType<T >& stat, size_t num_periods = U32_MAX)
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
typename T::mean_t mean = 0;
if (num_periods <= 0) { return mean; }
@@ -442,7 +445,7 @@ namespace LLTrace
typename T::mean_t getPeriodMeanPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX)
{
size_t total_periods = mRecordingPeriods.size();
- num_periods = llmin(num_periods, total_periods);
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
typename T::mean_t mean = 0;
if (num_periods <= 0) { return mean; }
@@ -468,8 +471,9 @@ namespace LLTrace
private:
std::vector<Recording> mRecordingPeriods;
- const bool mAutoResize;
- S32 mCurPeriod;
+ const bool mAutoResize;
+ size_t mCurPeriod;
+ size_t mNumPeriods;
};
PeriodicRecording& get_frame_recording();
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index f48cbe0e11..5229fe69d7 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -30,36 +30,12 @@
#include "stdtypes.h"
#include "llpreprocessor.h"
#include "llerrorlegacy.h"
+#include <boost/type_traits/is_same.hpp>
-namespace LLUnits
-{
-
-template<typename DERIVED_UNITS_TAG, typename BASE_UNITS_TAG, typename VALUE_TYPE>
-struct ConversionFactor
-{
- static F64 get()
- {
- // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
- llstatic_assert_template(DERIVED_UNITS_TAG, false, "Cannot convert between types.");
- return 0;
- }
-};
-
-template<typename BASE_UNITS_TAG, typename VALUE_TYPE>
-struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG, VALUE_TYPE>
-{
- static F64 get()
- {
- return 1;
- }
-};
-
-}
-
-template<typename UNIT_TYPE, typename STORAGE_TYPE>
+template<typename STORAGE_TYPE, typename UNIT_TYPE>
struct LLUnit
{
- typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> self_t;
+ typedef LLUnit<STORAGE_TYPE, UNIT_TYPE> self_t;
typedef STORAGE_TYPE storage_t;
// value initialization
@@ -68,11 +44,16 @@ struct LLUnit
{}
// unit initialization and conversion
- template<typename OTHER_UNIT, typename OTHER_STORAGE>
- LLUnit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
- : mValue(convert(other))
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ LLUnit(LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
+ : mValue(convert(other).mValue)
{}
+ bool operator == (const self_t& other)
+ {
+ return mValue = other.mValue;
+ }
+
// value assignment
self_t& operator = (storage_t value)
{
@@ -81,10 +62,10 @@ struct LLUnit
}
// unit assignment
- template<typename OTHER_UNIT, typename OTHER_STORAGE>
- self_t& operator = (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ self_t& operator = (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
{
- mValue = convert(other);
+ mValue = convert(other).mValue;
return *this;
}
@@ -93,21 +74,27 @@ struct LLUnit
return mValue;
}
- template<typename NEW_UNIT_TYPE> LLUnit<NEW_UNIT_TYPE, STORAGE_TYPE> as()
+ template<typename NEW_UNIT_TYPE>
+ STORAGE_TYPE getAs()
{
- return LLUnit<NEW_UNIT_TYPE, STORAGE_TYPE>(*this);
+ return LLUnit<STORAGE_TYPE, NEW_UNIT_TYPE>(*this).value();
}
+ template<typename NEW_UNIT_TYPE>
+ STORAGE_TYPE setAs(STORAGE_TYPE val)
+ {
+ *this = LLUnit<STORAGE_TYPE, NEW_UNIT_TYPE>(val);
+ }
void operator += (storage_t value)
{
mValue += value;
}
- template<typename OTHER_UNIT, typename OTHER_STORAGE>
- void operator += (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ void operator += (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
{
- mValue += convert(other);
+ mValue += convert(other).mValue;
}
void operator -= (storage_t value)
@@ -115,10 +102,10 @@ struct LLUnit
mValue -= value;
}
- template<typename OTHER_UNIT, typename OTHER_STORAGE>
- void operator -= (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ void operator -= (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
{
- mValue -= convert(other);
+ mValue -= convert(other).mValue;
}
void operator *= (storage_t multiplicand)
@@ -127,7 +114,7 @@ struct LLUnit
}
template<typename OTHER_UNIT, typename OTHER_STORAGE>
- void operator *= (LLUnit<OTHER_UNIT, OTHER_STORAGE> multiplicand)
+ void operator *= (LLUnit<OTHER_STORAGE, OTHER_UNIT> multiplicand)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
llstatic_assert_template(OTHER_UNIT, false, "Multiplication of unit types not supported.");
@@ -139,37 +126,37 @@ struct LLUnit
}
template<typename OTHER_UNIT, typename OTHER_STORAGE>
- void operator /= (LLUnit<OTHER_UNIT, OTHER_STORAGE> divisor)
+ void operator /= (LLUnit<OTHER_STORAGE, OTHER_UNIT> divisor)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
llstatic_assert_template(OTHER_UNIT, false, "Illegal in-place division of unit types.");
}
- template<typename SOURCE_UNITS, typename SOURCE_STORAGE>
- static storage_t convert(LLUnit<SOURCE_UNITS, SOURCE_STORAGE> v)
+ template<typename SOURCE_STORAGE, typename SOURCE_UNITS>
+ static self_t convert(LLUnit<SOURCE_STORAGE, SOURCE_UNITS> v)
{
- return (storage_t)(v.value()
- * LLUnits::ConversionFactor<SOURCE_UNITS, typename UNIT_TYPE::base_unit_t, SOURCE_STORAGE>::get()
- * LLUnits::ConversionFactor<typename UNIT_TYPE::base_unit_t, UNIT_TYPE, STORAGE_TYPE>::get());
+ self_t result;
+ ll_convert_units(v, result);
+ return result;
}
protected:
storage_t mValue;
};
-template<typename UNIT_TYPE, typename STORAGE_TYPE>
-struct LLUnitImplicit : public LLUnit<UNIT_TYPE, STORAGE_TYPE>
+template<typename STORAGE_TYPE, typename UNIT_TYPE>
+struct LLUnitImplicit : public LLUnit<STORAGE_TYPE, UNIT_TYPE>
{
- 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;
+ typedef LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> self_t;
+ typedef typename LLUnit<STORAGE_TYPE, UNIT_TYPE>::storage_t storage_t;
+ typedef LLUnit<STORAGE_TYPE, UNIT_TYPE> base_t;
LLUnitImplicit(storage_t value = storage_t())
: base_t(value)
{}
- template<typename OTHER_UNIT, typename OTHER_STORAGE>
- LLUnitImplicit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ LLUnitImplicit(LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
: base_t(convert(other))
{}
@@ -181,53 +168,86 @@ struct LLUnitImplicit : public LLUnit<UNIT_TYPE, STORAGE_TYPE>
}
};
+
+template<typename S1, typename T1, typename S2, typename T2>
+LL_FORCE_INLINE void ll_convert_units(LLUnit<S1, T1> in, LLUnit<S2, T2>& out, ...)
+{
+ static_assert(boost::is_same<T1, T2>::value
+ || !boost::is_same<T1, typename T1::base_unit_t>::value
+ || !boost::is_same<T2, typename T2::base_unit_t>::value,
+ "invalid conversion");
+
+ if (boost::is_same<T1, typename T1::base_unit_t>::value)
+ {
+ if (boost::is_same<T2, typename T2::base_unit_t>::value)
+ {
+ // T1 and T2 fully reduced and equal...just copy
+ out = (S2)in.value();
+ }
+ else
+ {
+ // reduce T2
+ LLUnit<S2, typename T2::base_unit_t> new_out;
+ ll_convert_units(in, new_out);
+ ll_convert_units(new_out, out);
+ }
+ }
+ else
+ {
+ // reduce T1
+ LLUnit<S1, typename T1::base_unit_t> new_in;
+ ll_convert_units(in, new_in);
+ ll_convert_units(new_in, out);
+ }
+}
+
//
// operator +
//
-template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
-LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
result += second;
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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator + (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
{
- LLUnit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
result += second;
return result;
}
-template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
-LLUnit<UNIT_TYPE, STORAGE_TYPE> operator + (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator + (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
{
- LLUnit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ LLUnit<STORAGE_TYPE, UNIT_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, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ LLUnitImplicit<STORAGE_TYPE1, UNIT_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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator + (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
{
- LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ LLUnitImplicit<STORAGE_TYPE, UNIT_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)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
result += second;
return result;
}
@@ -235,50 +255,50 @@ LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnitImplicit<UNIT_TYPE1,
//
// operator -
//
-template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
-LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator - (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator - (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
result -= second;
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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator - (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
{
- LLUnit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
result -= second;
return result;
}
-template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
-LLUnit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator - (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
{
- LLUnit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ LLUnit<STORAGE_TYPE, UNIT_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)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator - (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ LLUnitImplicit<STORAGE_TYPE1, UNIT_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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator - (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
{
- LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ LLUnitImplicit<STORAGE_TYPE, UNIT_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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator - (SCALAR_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> second)
{
- LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> result(first);
result -= second;
return result;
}
@@ -286,102 +306,100 @@ LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnitImp
//
// operator *
//
-template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
-LLUnit<UNIT_TYPE, STORAGE_TYPE> operator * (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator * (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
{
- return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first * second.value()));
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first * second.value()));
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator * (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
{
- return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() * second));
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first.value() * second));
}
-template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
-LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnit<UNIT_TYPE1, STORAGE_TYPE1>, LLUnit<UNIT_TYPE2, STORAGE_TYPE2>)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator * (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported.");
- return LLUnit<UNIT_TYPE1, STORAGE_TYPE1>();
+ return LLUnit<STORAGE_TYPE1, UNIT_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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator * (SCALAR_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> second)
{
- return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first * second.value());
+ return LLUnitImplicit<STORAGE_TYPE, UNIT_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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator * (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
{
- return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first.value() * second);
+ return LLUnitImplicit<STORAGE_TYPE, UNIT_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>)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator * (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2>)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported.");
- return LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>();
+ return LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>();
}
//
// operator /
//
-template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
-SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
{
return SCALAR_TYPE(first / second.value());
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator / (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
{
- return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() / second));
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first.value() / second));
}
-template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
-STORAGE_TYPE1 operator / (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+STORAGE_TYPE1 operator / (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_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());
+ return STORAGE_TYPE1(first.value() / 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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator / (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
{
- return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() / second));
+ return LLUnitImplicit<STORAGE_TYPE, 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)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+STORAGE_TYPE1 operator / (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_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());
+ return STORAGE_TYPE1(first.value() / first.convert(second));
}
#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) \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE> \
+bool operator op (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_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) \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE> \
+bool operator op (LLUnit<STORAGE_TYPE, UNIT_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) \
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2> \
+bool operator op (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_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) \
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2> \
+ bool operator op (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second) \
{ \
return first.value() op first.convert(second); \
}
@@ -401,80 +419,142 @@ struct LLGetUnitLabel
};
template<typename T, typename STORAGE_T>
-struct LLGetUnitLabel<LLUnit<T, STORAGE_T> >
+struct LLGetUnitLabel<LLUnit<STORAGE_T, T> >
{
static const char* getUnitLabel() { return T::getUnitLabel(); }
};
-//
-// Unit declarations
-//
-namespace LLUnits
+template<typename VALUE_TYPE>
+struct LLUnitLinearOps
{
-template<typename T>
-T rawValue(T val) { return val; }
+ typedef LLUnitLinearOps<VALUE_TYPE> self_t;
+ LLUnitLinearOps(VALUE_TYPE val) : mValue (val) {}
-template<typename UNIT_TYPE, typename STORAGE_TYPE>
-STORAGE_TYPE rawValue(LLUnit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); }
+ operator VALUE_TYPE() const { return mValue; }
+ VALUE_TYPE mValue;
-template<typename UNIT_TYPE, typename STORAGE_TYPE>
-STORAGE_TYPE rawValue(LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); }
+ template<typename T>
+ self_t operator * (T other)
+ {
+ return mValue * other;
+ }
+
+ template<typename T>
+ self_t operator / (T other)
+ {
+ return mValue / other;
+ }
+
+ template<typename T>
+ self_t operator + (T other)
+ {
+ return mValue + other;
+ }
+
+ template<typename T>
+ self_t operator - (T other)
+ {
+ return mValue - other;
+ }
+};
-#define LL_DECLARE_DERIVED_UNIT(conversion_factor, base_unit_name, unit_name, unit_label) \
+template<typename VALUE_TYPE>
+struct LLUnitInverseLinearOps
+{
+ typedef LLUnitInverseLinearOps<VALUE_TYPE> self_t;
+
+ LLUnitInverseLinearOps(VALUE_TYPE val) : mValue (val) {}
+ operator VALUE_TYPE() const { return mValue; }
+ VALUE_TYPE mValue;
+
+ template<typename T>
+ self_t operator * (T other)
+ {
+ return mValue / other;
+ }
+
+ template<typename T>
+ self_t operator / (T other)
+ {
+ return mValue * other;
+ }
+
+ template<typename T>
+ self_t operator + (T other)
+ {
+ return mValue - other;
+ }
+
+ template<typename T>
+ self_t operator - (T other)
+ {
+ return mValue + other;
+ }
+};
+
+#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \
+struct base_unit_name { typedef base_unit_name base_unit_t; static const char* getUnitLabel() { return unit_label; }}
+
+#define LL_DECLARE_DERIVED_UNIT(unit_name, unit_label, base_unit_name, conversion_operation) \
struct unit_name \
{ \
typedef base_unit_name base_unit_t; \
static const char* getUnitLabel() { return unit_label; } \
}; \
-template<typename STORAGE_TYPE> \
-struct ConversionFactor<unit_name, base_unit_name, STORAGE_TYPE> \
-{ \
- static F64 get() \
- { \
- return (F64)conversion_factor; \
- } \
-}; \
\
-template<typename STORAGE_TYPE> \
-struct ConversionFactor<base_unit_name, unit_name, STORAGE_TYPE> \
+template<typename S1, typename S2> \
+void ll_convert_units(LLUnit<S1, unit_name> in, LLUnit<S2, base_unit_name>& out) \
{ \
- static F64 get() \
- { \
- return (F64)(1.0 / (conversion_factor)); \
- } \
-}
+ out = (S2)(LLUnitLinearOps<S1>(in.value()) conversion_operation).mValue; \
+} \
+ \
+template<typename S1, typename S2> \
+void ll_convert_units(LLUnit<S1, base_unit_name> in, LLUnit<S2, unit_name>& out) \
+{ \
+ out = (S2)(LLUnitInverseLinearOps<S1>(in.value()) conversion_operation).mValue; \
+}
-#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \
-struct base_unit_name { typedef base_unit_name base_unit_t; static const char* getUnitLabel() { return unit_label; }}
+//
+// Unit declarations
+//
+namespace LLUnits
+{
LL_DECLARE_BASE_UNIT(Bytes, "B");
-LL_DECLARE_DERIVED_UNIT(1024, Bytes, Kibibytes, "KiB");
-LL_DECLARE_DERIVED_UNIT(1024 * 1024, Bytes, Mibibytes, "MiB");
-LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024, Bytes, Gibibytes, "GiB");
-LL_DECLARE_DERIVED_UNIT(1.0 / 8.0, Bytes, Bits, "b");
-LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Kibibits, "Kib");
-LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Mibibits, "Mib");
-LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024 / 8, Bytes, Gibibits, "Gib");
+LL_DECLARE_DERIVED_UNIT(Kilobytes, "KB", Bytes, * 1000);
+LL_DECLARE_DERIVED_UNIT(Megabytes, "MB", Kilobytes, * 1000);
+LL_DECLARE_DERIVED_UNIT(Gigabytes, "GB", Megabytes, * 1000);
+LL_DECLARE_DERIVED_UNIT(Kibibytes, "KiB", Bytes, * 1024);
+LL_DECLARE_DERIVED_UNIT(Mibibytes, "MiB", Kibibytes, * 1024);
+LL_DECLARE_DERIVED_UNIT(Gibibytes, "GiB", Mibibytes, * 1024);
+
+LL_DECLARE_DERIVED_UNIT(Bits, "b", Bytes, / 8);
+LL_DECLARE_DERIVED_UNIT(Kilobits, "Kb", Bytes, * 1000 / 8);
+LL_DECLARE_DERIVED_UNIT(Megabits, "Mb", Kilobits, * 1000 / 8);
+LL_DECLARE_DERIVED_UNIT(Gigabits, "Gb", Megabits, * 1000 / 8);
+LL_DECLARE_DERIVED_UNIT(Kibibits, "Kib", Bytes, * 1024 / 8);
+LL_DECLARE_DERIVED_UNIT(Mibibits, "Mib", Kibibits, * 1024 / 8);
+LL_DECLARE_DERIVED_UNIT(Gibibits, "Gib", Mibibits, * 1024 / 8);
LL_DECLARE_BASE_UNIT(Seconds, "s");
-LL_DECLARE_DERIVED_UNIT(60, Seconds, Minutes, "min");
-LL_DECLARE_DERIVED_UNIT(60 * 60, Seconds, Hours, "h");
-LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Seconds, Milliseconds, "ms");
-LL_DECLARE_DERIVED_UNIT(1.0 / 1000000.0, Seconds, Microseconds, "\x09\x3cs");
-LL_DECLARE_DERIVED_UNIT(1.0 / 1000000000.0, Seconds, Nanoseconds, "ns");
+LL_DECLARE_DERIVED_UNIT(Minutes, "min", Seconds, * 60);
+LL_DECLARE_DERIVED_UNIT(Hours, "h", Seconds, * 60 * 60);
+LL_DECLARE_DERIVED_UNIT(Milliseconds, "ms", Seconds, / 1000);
+LL_DECLARE_DERIVED_UNIT(Microseconds, "\x09\x3cs", Milliseconds, / 1000);
+LL_DECLARE_DERIVED_UNIT(Nanoseconds, "ns", Microseconds, / 1000);
LL_DECLARE_BASE_UNIT(Meters, "m");
-LL_DECLARE_DERIVED_UNIT(1000, Meters, Kilometers, "km");
-LL_DECLARE_DERIVED_UNIT(1.0 / 100.0, Meters, Centimeters, "cm");
-LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Meters, Millimeters, "mm");
+LL_DECLARE_DERIVED_UNIT(Kilometers, "km", Meters, * 1000);
+LL_DECLARE_DERIVED_UNIT(Centimeters, "cm", Meters, / 100);
+LL_DECLARE_DERIVED_UNIT(Millimeters, "mm", Meters, / 1000);
LL_DECLARE_BASE_UNIT(Hertz, "Hz");
-LL_DECLARE_DERIVED_UNIT(1000, Hertz, Kilohertz, "KHz");
-LL_DECLARE_DERIVED_UNIT(1000 * 1000, Hertz, Megahertz, "MHz");
-LL_DECLARE_DERIVED_UNIT(1000 * 1000 * 1000, Hertz, Gigahertz, "GHz");
+LL_DECLARE_DERIVED_UNIT(Kilohertz, "KHz", Hertz, * 1000);
+LL_DECLARE_DERIVED_UNIT(Megahertz, "MHz", Kilohertz, * 1000);
+LL_DECLARE_DERIVED_UNIT(Gigahertz, "GHz", Megahertz, * 1000);
LL_DECLARE_BASE_UNIT(Radians, "rad");
-LL_DECLARE_DERIVED_UNIT(0.01745329251994, Radians, Degrees, "deg");
+LL_DECLARE_DERIVED_UNIT(Degrees, "deg", Radians, * 0.01745329251994);
} // namespace LLUnits
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index 33e30f9688..04764f6c2f 100644
--- a/indra/llcommon/tests/llunits_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -34,8 +34,8 @@ namespace LLUnits
{
// using powers of 2 to allow strict floating point equality
LL_DECLARE_BASE_UNIT(Quatloos, "Quat");
- LL_DECLARE_DERIVED_UNIT(4, Quatloos, Latinum, "Lat");
- LL_DECLARE_DERIVED_UNIT((1.0 / 4.0), Quatloos, Solari, "Sol");
+ LL_DECLARE_DERIVED_UNIT(Latinum, "Lat", Quatloos, * 4);
+ LL_DECLARE_DERIVED_UNIT(Solari, "Sol", Latinum, / 16);
}
namespace tut
@@ -53,105 +53,107 @@ namespace tut
template<> template<>
void units_object_t::test<1>()
{
- LLUnit<Quatloos, F32> float_quatloos;
- ensure(float_quatloos.value() == 0.f);
+ LLUnit<F32, Quatloos> float_quatloos;
+ ensure(float_quatloos == 0.f);
- LLUnit<Quatloos, S32> int_quatloos;
- ensure(int_quatloos.value() == 0);
+ LLUnit<S32, Quatloos> int_quatloos;
+ ensure(int_quatloos == 0);
int_quatloos = 42;
- ensure(int_quatloos.value() == 42);
+ ensure(int_quatloos == 42);
float_quatloos = int_quatloos;
- ensure(float_quatloos.value() == 42.f);
+ ensure(float_quatloos == 42.f);
int_quatloos = float_quatloos;
- ensure(int_quatloos.value() == 42);
+ ensure(int_quatloos == 42);
float_quatloos = 42.1f;
- ensure(float_quatloos.value() == 42.1f);
+ ensure(float_quatloos == 42.1f);
int_quatloos = float_quatloos;
- ensure(int_quatloos.value() == 42);
- LLUnit<Quatloos, U32> unsigned_int_quatloos(float_quatloos);
- ensure(unsigned_int_quatloos.value() == 42);
+ ensure(int_quatloos == 42);
+ LLUnit<U32, Quatloos> unsigned_int_quatloos(float_quatloos);
+ ensure(unsigned_int_quatloos == 42);
}
// conversions to/from base unit
template<> template<>
void units_object_t::test<2>()
{
- LLUnit<Quatloos, F32> quatloos(1.f);
- ensure(quatloos.value() == 1.f);
- LLUnit<Latinum, F32> latinum_bars(quatloos);
- ensure(latinum_bars.value() == 1.f / 4.f);
+ LLUnit<F32, Quatloos> quatloos(1.f);
+ ensure(quatloos == 1.f);
+ LLUnit<F32, Latinum> latinum_bars(quatloos);
+ ensure(latinum_bars == 1.f / 4.f);
latinum_bars = 256;
quatloos = latinum_bars;
- ensure(quatloos.value() == 1024);
+ ensure(quatloos == 1024);
- LLUnit<Solari, F32> solari(quatloos);
- ensure(solari.value() == 4096);
+ LLUnit<F32, Solari> solari(quatloos);
+ ensure(solari == 4096);
}
// conversions across non-base units
template<> template<>
void units_object_t::test<3>()
{
- LLUnit<Solari, F32> solari = 4.f;
- LLUnit<Latinum, F32> latinum_bars = solari;
- ensure(latinum_bars.value() == 0.25f);
+ LLUnit<F32, Solari> solari = 4.f;
+ LLUnit<F32, Latinum> latinum_bars = solari;
+ ensure(latinum_bars == 0.25f);
}
// math operations
template<> template<>
void units_object_t::test<4>()
{
- LLUnit<Quatloos, F32> quatloos = 1.f;
+ LLUnit<F32, Quatloos> quatloos = 1.f;
quatloos *= 4.f;
- ensure(quatloos.value() == 4);
+ ensure(quatloos == 4);
quatloos = quatloos * 2;
- ensure(quatloos.value() == 8);
+ ensure(quatloos == 8);
quatloos = 2.f * quatloos;
- ensure(quatloos.value() == 16);
+ ensure(quatloos == 16);
quatloos += 4.f;
- ensure(quatloos.value() == 20);
+ ensure(quatloos == 20);
quatloos += 4;
- ensure(quatloos.value() == 24);
+ ensure(quatloos == 24);
quatloos = quatloos + 4;
- ensure(quatloos.value() == 28);
+ ensure(quatloos == 28);
quatloos = 4 + quatloos;
- ensure(quatloos.value() == 32);
+ ensure(quatloos == 32);
quatloos += quatloos * 3;
- ensure(quatloos.value() == 128);
+ ensure(quatloos == 128);
quatloos -= quatloos / 4 * 3;
- ensure(quatloos.value() == 32);
+ ensure(quatloos == 32);
quatloos = quatloos - 8;
- ensure(quatloos.value() == 24);
+ ensure(quatloos == 24);
quatloos -= 4;
- ensure(quatloos.value() == 20);
+ ensure(quatloos == 20);
quatloos -= 4.f;
- ensure(quatloos.value() == 16);
+ ensure(quatloos == 16);
quatloos *= 2.f;
- ensure(quatloos.value() == 32);
+ ensure(quatloos == 32);
quatloos = quatloos * 2.f;
- ensure(quatloos.value() == 64);
+ ensure(quatloos == 64);
quatloos = 0.5f * quatloos;
- ensure(quatloos.value() == 32);
+ ensure(quatloos == 32);
quatloos /= 2.f;
- ensure(quatloos.value() == 16);
+ ensure(quatloos == 16);
quatloos = quatloos / 4;
- ensure(quatloos.value() == 4);
+ ensure(quatloos == 4);
- F32 ratio = quatloos / LLUnit<Quatloos, F32>(4.f);
+ F32 ratio = quatloos / LLUnit<F32, Quatloos>(4.f);
+ ensure(ratio == 1);
+ ratio = quatloos / LLUnit<F32, Solari>(16.f);
ensure(ratio == 1);
- quatloos += LLUnit<Solari, F32>(4.f);
- ensure(quatloos.value() == 5);
- quatloos -= LLUnit<Latinum, F32>(1.f);
- ensure(quatloos.value() == 1);
+ quatloos += LLUnit<F32, Solari>(4.f);
+ ensure(quatloos == 5);
+ quatloos -= LLUnit<F32, Latinum>(1.f);
+ ensure(quatloos == 1);
}
// implicit units
@@ -159,16 +161,16 @@ namespace tut
void units_object_t::test<5>()
{
// 0-initialized
- LLUnit<Quatloos, F32> quatloos(0);
+ LLUnit<F32, Quatloos> quatloos(0);
// initialize implicit unit from explicit
- LLUnitImplicit<Quatloos, F32> quatloos_implicit = quatloos + 1;
- ensure(quatloos_implicit.value() == 1);
+ LLUnitImplicit<F32, Quatloos> quatloos_implicit = quatloos + 1;
+ ensure(quatloos_implicit == 1);
// assign implicit to explicit, or perform math operations
quatloos = quatloos_implicit;
- ensure(quatloos.value() == 1);
+ ensure(quatloos == 1);
quatloos += quatloos_implicit;
- ensure(quatloos.value() == 2);
+ ensure(quatloos == 2);
// math operations on implicits
quatloos_implicit = 1;
@@ -204,5 +206,11 @@ namespace tut
S32 int_val = quatloos_implicit;
ensure(int_val == 16);
+
+ // conversion of implicits
+ LLUnitImplicit<F32, Latinum> latinum_implicit(2);
+ ensure(latinum_implicit == 2);
+
+ ensure(latinum_implicit * 2 == quatloos_implicit);
}
}