summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
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/llframetimer.h4
-rwxr-xr-xindra/llcommon/llmemory.cpp46
-rwxr-xr-xindra/llcommon/llmemory.h18
-rwxr-xr-xindra/llcommon/llprocessor.cpp2
-rwxr-xr-xindra/llcommon/llprocessor.h2
-rwxr-xr-xindra/llcommon/llsys.cpp18
-rwxr-xr-xindra/llcommon/llsys.h4
-rwxr-xr-xindra/llcommon/lltimer.cpp18
-rwxr-xr-xindra/llcommon/lltimer.h20
-rw-r--r--indra/llcommon/lltraceaccumulators.cpp2
-rw-r--r--indra/llcommon/lltraceaccumulators.h20
-rw-r--r--indra/llcommon/lltracerecording.h4
-rw-r--r--indra/llcommon/llunit.h727
-rw-r--r--indra/llcommon/tests/llunits_test.cpp126
18 files changed, 659 insertions, 362 deletions
diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp
index 5ffad88973..9f4cb09000 100755
--- a/indra/llcommon/llcriticaldamp.cpp
+++ b/indra/llcommon/llcriticaldamp.cpp
@@ -81,7 +81,7 @@ void LLSmoothInterpolation::updateInterpolants()
//-----------------------------------------------------------------------------
// getInterpolant()
//-----------------------------------------------------------------------------
-F32 LLSmoothInterpolation::getInterpolant(LLUnitImplicit<F32, LLUnits::Seconds> time_constant, bool use_cache)
+F32 LLSmoothInterpolation::getInterpolant(F32SecondsImplicit time_constant, bool use_cache)
{
if (time_constant == 0.f)
{
diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h
index 7b2a414459..a02a2a0dcf 100755
--- a/indra/llcommon/llcriticaldamp.h
+++ b/indra/llcommon/llcriticaldamp.h
@@ -42,10 +42,10 @@ public:
static void updateInterpolants();
// ACCESSORS
- static F32 getInterpolant(LLUnitImplicit<F32, LLUnits::Seconds> time_constant, bool use_cache = true);
+ static F32 getInterpolant(F32SecondsImplicit time_constant, bool use_cache = true);
template<typename T>
- static T lerp(T a, T b, LLUnitImplicit<F32, LLUnits::Seconds> time_constant, bool use_cache = true)
+ static T lerp(T a, T b, F32SecondsImplicit 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 cb6f239396..4f2e1304b2 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(LLUnitImplicit<F64, LLUnits::Seconds> seconds_since_epoch) :
+LLDate::LLDate(F64SecondsImplicit seconds_since_epoch) :
mSecondsSinceEpoch(seconds_since_epoch.value())
{}
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 816bc62b14..aecf3b765e 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(LLUnitImplicit<F64, LLUnits::Seconds> seconds_since_epoch);
+ LLDate(F64SecondsImplicit seconds_since_epoch);
/**
* @brief Construct a date from a string representation
diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h
index d64009440c..81bd5da8a3 100755
--- a/indra/llcommon/llframetimer.h
+++ b/indra/llcommon/llframetimer.h
@@ -43,7 +43,7 @@ public:
// Return the number of seconds since the start of this
// application instance.
- static F64 getElapsedSeconds()
+ static F64SecondsImplicit getElapsedSeconds()
{
// Loses msec precision after ~4.5 hours...
return sFrameTime;
@@ -52,7 +52,7 @@ public:
// Return a low precision usec since epoch
static U64 getTotalTime()
{
- return sTotalTime ? LLUnitImplicit<U64, LLUnits::Microseconds>(sTotalTime) : totalTime();
+ return sTotalTime ? U64MicrosecondsImplicit(sTotalTime) : totalTime();
}
// Return a low precision seconds since epoch
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index c59b61471a..d46e205500 100755
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -47,11 +47,11 @@
//static
char* LLMemory::reserveMem = 0;
-U32Kibibytes LLMemory::sAvailPhysicalMemInKB(U32_MAX);
-U32Kibibytes LLMemory::sMaxPhysicalMemInKB(0);
-U32Kibibytes LLMemory::sAllocatedMemInKB(0);
-U32Kibibytes LLMemory::sAllocatedPageSizeInKB(0);
-U32Kibibytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
+U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX);
+U32Kilobytes LLMemory::sMaxPhysicalMemInKB(0);
+U32Kilobytes LLMemory::sAllocatedMemInKB(0);
+U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
+U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE;
#if __DEBUG_PRIVATE_MEM__
@@ -94,9 +94,9 @@ void LLMemory::freeReserve()
}
//static
-void LLMemory::initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure)
+void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure)
{
- sMaxHeapSizeInKB = (U32)(max_heap_size_gb * 1024 * 1024) ;
+ sMaxHeapSizeInKB = max_heap_size;
sEnableMemoryFailurePrevention = prevent_heap_failure ;
}
@@ -113,10 +113,10 @@ void LLMemory::updateMemoryInfo()
return ;
}
- sAllocatedMemInKB = (U32)(counters.WorkingSetSize / 1024) ;
- sAllocatedPageSizeInKB = (U32)(counters.PagefileUsage / 1024) ;
+ sAllocatedMemInKB = (U32Bytes)(counters.WorkingSetSize) ;
+ sAllocatedPageSizeInKB = (U32Bytes)(counters.PagefileUsage) ;
- U32Kibibytes avail_phys, avail_virtual;
+ U32Kilobytes avail_phys, avail_virtual;
LLMemoryInfo::getAvailableMemoryKB(avail_phys, avail_virtual) ;
sMaxPhysicalMemInKB = llmin(avail_phys + sAllocatedMemInKB, sMaxHeapSizeInKB);
@@ -126,7 +126,7 @@ void LLMemory::updateMemoryInfo()
}
else
{
- sAvailPhysicalMemInKB = 0 ;
+ sAvailPhysicalMemInKB = U32Kilobytes(0);
}
#else
//not valid for other systems for now.
@@ -187,8 +187,8 @@ void LLMemory::logMemoryInfo(BOOL update)
//static
bool LLMemory::isMemoryPoolLow()
{
- static const U32 LOW_MEMEOY_POOL_THRESHOLD_KB = 64 * 1024 ; //64 MB for emergency use
- const static U32 MAX_SIZE_CHECKED_MEMORY_BLOCK = 64 * 1024 * 1024 ; //64 MB
+ static const U32Megabytes LOW_MEMORY_POOL_THRESHOLD(64);
+ const static U32Megabytes MAX_SIZE_CHECKED_MEMORY_BLOCK(64);
static void* last_reserved_address = NULL ;
if(!sEnableMemoryFailurePrevention)
@@ -196,32 +196,32 @@ bool LLMemory::isMemoryPoolLow()
return false ; //no memory failure prevention.
}
- if(sAvailPhysicalMemInKB < (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2)) //out of physical memory
+ if(sAvailPhysicalMemInKB < (LOW_MEMORY_POOL_THRESHOLD / 4)) //out of physical memory
{
return true ;
}
- if(sAllocatedPageSizeInKB + (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2) > sMaxHeapSizeInKB) //out of virtual address space.
+ if(sAllocatedPageSizeInKB + (LOW_MEMORY_POOL_THRESHOLD / 4) > sMaxHeapSizeInKB) //out of virtual address space.
{
return true ;
}
- bool is_low = (S32)(sAvailPhysicalMemInKB < LOW_MEMEOY_POOL_THRESHOLD_KB ||
- sAllocatedPageSizeInKB + LOW_MEMEOY_POOL_THRESHOLD_KB > sMaxHeapSizeInKB) ;
+ bool is_low = (S32)(sAvailPhysicalMemInKB < LOW_MEMORY_POOL_THRESHOLD ||
+ sAllocatedPageSizeInKB + LOW_MEMORY_POOL_THRESHOLD > sMaxHeapSizeInKB) ;
//check the virtual address space fragmentation
if(!is_low)
{
if(!last_reserved_address)
{
- last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ;
+ last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ;
}
else
{
- last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ;
+ last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ;
if(!last_reserved_address) //failed, try once more
{
- last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ;
+ last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ;
}
}
@@ -232,19 +232,19 @@ bool LLMemory::isMemoryPoolLow()
}
//static
-U32Kibibytes LLMemory::getAvailableMemKB()
+U32Kilobytes LLMemory::getAvailableMemKB()
{
return sAvailPhysicalMemInKB ;
}
//static
-U32Kibibytes LLMemory::getMaxMemKB()
+U32Kilobytes LLMemory::getMaxMemKB()
{
return sMaxPhysicalMemInKB ;
}
//static
-U32Kibibytes LLMemory::getAllocatedMemKB()
+U32Kilobytes LLMemory::getAllocatedMemKB()
{
return sAllocatedMemInKB ;
}
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index c45c7ed213..23be1e5b2d 100755
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -166,22 +166,22 @@ public:
static U64 getCurrentRSS();
static U32 getWorkingSetSize();
static void* tryToAlloc(void* address, U32 size);
- static void initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure);
+ static void initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure);
static void updateMemoryInfo() ;
static void logMemoryInfo(BOOL update = FALSE);
static bool isMemoryPoolLow();
- static U32Kibibytes getAvailableMemKB() ;
- static U32Kibibytes getMaxMemKB() ;
- static U32Kibibytes getAllocatedMemKB() ;
+ static U32Kilobytes getAvailableMemKB() ;
+ static U32Kilobytes getMaxMemKB() ;
+ static U32Kilobytes getAllocatedMemKB() ;
private:
static char* reserveMem;
- static U32Kibibytes sAvailPhysicalMemInKB ;
- static U32Kibibytes sMaxPhysicalMemInKB ;
- static U32Kibibytes sAllocatedMemInKB;
- static U32Kibibytes sAllocatedPageSizeInKB ;
+ static U32Kilobytes sAvailPhysicalMemInKB ;
+ static U32Kilobytes sMaxPhysicalMemInKB ;
+ static U32Kilobytes sAllocatedMemInKB;
+ static U32Kilobytes sAllocatedPageSizeInKB ;
- static U32Kibibytes sMaxHeapSizeInKB;
+ static U32Kilobytes sMaxHeapSizeInKB;
static BOOL sEnableMemoryFailurePrevention;
};
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 80b86153e4..69043dc173 100755
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -875,7 +875,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL)
LLProcessorInfo::~LLProcessorInfo() {}
-LLUnitImplicit<F64, LLUnits::Megahertz> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
+F64MegahertzImplicit 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 7f220467b0..4956a39700 100755
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -37,7 +37,7 @@ public:
LLProcessorInfo();
~LLProcessorInfo();
- LLUnitImplicit<F64, LLUnits::Megahertz> getCPUFrequency() const;
+ F64MegahertzImplicit getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
bool hasAltivec() const;
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 8f7e60fb68..1ff45d3d90 100755
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -832,7 +832,7 @@ LLMemoryInfo::LLMemoryInfo()
}
#if LL_WINDOWS
-static U32Kibibytes LLMemoryAdjustKBResult(U32Kibibytes inKB)
+static U32Kilobytes LLMemoryAdjustKBResult(U32Kilobytes inKB)
{
// Moved this here from llfloaterabout.cpp
@@ -843,16 +843,16 @@ static U32Kibibytes LLMemoryAdjustKBResult(U32Kibibytes inKB)
// returned from the GetMemoryStatusEx function. Here we keep the
// original adjustment from llfoaterabout.cpp until this can be
// fixed somehow.
- inKB += U32Mibibytes(1);
+ inKB += U32Megabytes(1);
return inKB;
}
#endif
-U32Kibibytes LLMemoryInfo::getPhysicalMemoryKB() const
+U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
{
#if LL_WINDOWS
- return LLMemoryAdjustKBResult(U32Kibibytes(mStatsMap["Total Physical KB"].asInteger()));
+ return LLMemoryAdjustKBResult(U32Kilobytes(mStatsMap["Total Physical KB"].asInteger()));
#elif LL_DARWIN
// This might work on Linux as well. Someone check...
@@ -885,8 +885,8 @@ U32Bytes LLMemoryInfo::getPhysicalMemoryClamped() const
// Return the total physical memory in bytes, but clamp it
// to no more than U32_MAX
- U32Bytes phys_kb = getPhysicalMemoryKB();
- if (phys_kb >= 4194304 /* 4GB in KB */)
+ U32Kilobytes phys_kb = getPhysicalMemoryKB();
+ if (phys_kb >= U32Gigabytes(4))
{
return U32Bytes(U32_MAX);
}
@@ -897,15 +897,15 @@ U32Bytes LLMemoryInfo::getPhysicalMemoryClamped() const
}
//static
-void LLMemoryInfo::getAvailableMemoryKB(U32Kibibytes& avail_physical_mem_kb, U32Kibibytes& avail_virtual_mem_kb)
+void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb)
{
#if LL_WINDOWS
// Sigh, this shouldn't be a static method, then we wouldn't have to
// reload this data separately from refresh()
LLSD statsMap(loadStatsMap());
- avail_physical_mem_kb = statsMap["Avail Physical KB"].asInteger();
- avail_virtual_mem_kb = statsMap["Avail Virtual KB"].asInteger();
+ avail_physical_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
+ avail_virtual_mem_kb = (U32Kilobytes)statsMap["Avail Virtual KB"].asInteger();
#elif LL_DARWIN
// mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index ad4f243d05..962367f69f 100755
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -112,7 +112,7 @@ public:
LLMemoryInfo(); ///< Default constructor
void stream(std::ostream& s) const; ///< output text info to s
- U32Kibibytes getPhysicalMemoryKB() const;
+ U32Kilobytes getPhysicalMemoryKB() const;
/*! Memory size in bytes, if total memory is >= 4GB then U32_MAX will
** be returned.
@@ -120,7 +120,7 @@ public:
U32Bytes getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes
//get the available memory infomation in KiloBytes.
- static void getAvailableMemoryKB(U32Kibibytes& avail_physical_mem_kb, U32Kibibytes& avail_virtual_mem_kb);
+ static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb);
// Retrieve a map of memory statistics. The keys of the map are platform-
// dependent. The values are in kilobytes to try to avoid integer overflow.
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 74f3a7f587..da9d2b646c 100755
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -225,7 +225,7 @@ void update_clock_frequencies()
// returns a U64 number that represents the number of
// microseconds since the unix epoch - Jan 1, 1970
-LLUnitImplicit<U64, LLUnits::Microseconds> totalTime()
+U64MicrosecondsImplicit totalTime()
{
U64 current_clock_count = get_clock_count();
if (!gTotalTimeClockCount)
@@ -295,14 +295,14 @@ void LLTimer::cleanupClass()
}
// static
-LLUnitImplicit<U64, LLUnits::Microseconds> LLTimer::getTotalTime()
+U64MicrosecondsImplicit LLTimer::getTotalTime()
{
// simply call into the implementation function.
return totalTime();
}
// static
-LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getTotalSeconds()
+F64SecondsImplicit LLTimer::getTotalSeconds()
{
return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;
}
@@ -351,36 +351,36 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)
}
-LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getElapsedTimeF64() const
+F64SecondsImplicit LLTimer::getElapsedTimeF64() const
{
U64 last = mLastClockCount;
return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;
}
-LLUnitImplicit<F32, LLUnits::Seconds> LLTimer::getElapsedTimeF32() const
+F32SecondsImplicit LLTimer::getElapsedTimeF32() const
{
return (F32)getElapsedTimeF64();
}
-LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getElapsedTimeAndResetF64()
+F64SecondsImplicit LLTimer::getElapsedTimeAndResetF64()
{
return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;
}
-LLUnitImplicit<F32, LLUnits::Seconds> LLTimer::getElapsedTimeAndResetF32()
+F32SecondsImplicit LLTimer::getElapsedTimeAndResetF32()
{
return (F32)getElapsedTimeAndResetF64();
}
///////////////////////////////////////////////////////////////////////////////
-void LLTimer::setTimerExpirySec(LLUnitImplicit<F32, LLUnits::Seconds> expiration)
+void LLTimer::setTimerExpirySec(F32SecondsImplicit expiration)
{
mExpirationTicks = get_clock_count()
+ (U64)((F32)(expiration * gClockFrequency));
}
-LLUnitImplicit<F32, LLUnits::Seconds> LLTimer::getRemainingTimeF32() const
+F32SecondsImplicit 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 1f2c56432b..12a453e897 100755
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -67,7 +67,7 @@ public:
// Return a high precision number of seconds since the start of
// this application instance.
- static LLUnitImplicit<F64, LLUnits::Seconds> getElapsedSeconds()
+ static F64SecondsImplicit getElapsedSeconds()
{
if (sTimer)
{
@@ -80,10 +80,10 @@ public:
}
// Return a high precision usec since epoch
- static LLUnitImplicit<U64, LLUnits::Microseconds> getTotalTime();
+ static U64MicrosecondsImplicit getTotalTime();
// Return a high precision seconds since epoch
- static LLUnitImplicit<F64, LLUnits::Seconds> getTotalSeconds();
+ static F64SecondsImplicit getTotalSeconds();
// MANIPULATORS
@@ -91,19 +91,19 @@ public:
void stop() { mStarted = FALSE; }
void reset(); // Resets the timer
void setLastClockCount(U64 current_count); // Sets the timer so that the next elapsed call will be relative to this time
- void setTimerExpirySec(LLUnitImplicit<F32, LLUnits::Seconds> expiration);
+ void setTimerExpirySec(F32SecondsImplicit expiration);
BOOL checkExpirationAndReset(F32 expiration);
BOOL hasExpired() const;
- LLUnitImplicit<F32, LLUnits::Seconds> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
- LLUnitImplicit<F64, LLUnits::Seconds> getElapsedTimeAndResetF64();
+ F32SecondsImplicit getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
+ F64SecondsImplicit getElapsedTimeAndResetF64();
- LLUnitImplicit<F32, LLUnits::Seconds> getRemainingTimeF32() const;
+ F32SecondsImplicit getRemainingTimeF32() const;
static BOOL knownBadTimer();
// ACCESSORS
- LLUnitImplicit<F32, LLUnits::Seconds> getElapsedTimeF32() const; // Returns elapsed time in seconds
- LLUnitImplicit<F64, LLUnits::Seconds> getElapsedTimeF64() const; // Returns elapsed time in seconds
+ F32SecondsImplicit getElapsedTimeF32() const; // Returns elapsed time in seconds
+ F64SecondsImplicit getElapsedTimeF64() const; // Returns elapsed time in seconds
bool getStarted() const { return mStarted; }
@@ -171,6 +171,6 @@ LL_COMMON_API struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_dayli
LL_COMMON_API void microsecondsToTimecodeString(U64 current_time, std::string& tcstring);
LL_COMMON_API void secondsToTimecodeString(F32 current_time, std::string& tcstring);
-LLUnitImplicit<U64, LLUnits::Microseconds> LL_COMMON_API totalTime(); // Returns current system time in microseconds
+U64MicrosecondsImplicit LL_COMMON_API totalTime(); // Returns current system time in microseconds
#endif
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index a632f5634c..1fb68c8158 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -114,7 +114,7 @@ void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other)
void AccumulatorBufferGroup::sync()
{
- LLUnitImplicit<F64, LLUnits::Seconds> time_stamp = LLTimer::getTotalSeconds();
+ F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
mSamples.sync(time_stamp);
mMemStats.sync(time_stamp);
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index 73da6bd2d8..f9d223066d 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -118,7 +118,7 @@ namespace LLTrace
}
}
- void sync(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
+ void sync(F64SecondsImplicit time_stamp)
{
llassert(mStorageSize >= sNextStorageSlot);
for (size_t i = 0; i < sNextStorageSlot; i++)
@@ -260,7 +260,7 @@ namespace LLTrace
void addSamples(const EventAccumulator& other, EBufferAppendType append_type);
void reset(const EventAccumulator* other);
- void sync(LLUnitImplicit<F64, LLUnits::Seconds>) {}
+ void sync(F64SecondsImplicit) {}
F64 getSum() const { return mSum; }
F64 getMin() const { return mMin; }
@@ -305,7 +305,7 @@ namespace LLTrace
void sample(F64 value)
{
- LLUnitImplicit<F64, LLUnits::Seconds> time_stamp = LLTimer::getTotalSeconds();
+ F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
// store effect of last value
sync(time_stamp);
@@ -332,11 +332,11 @@ namespace LLTrace
void addSamples(const SampleAccumulator& other, EBufferAppendType append_type);
void reset(const SampleAccumulator* other);
- void sync(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
+ void sync(F64SecondsImplicit time_stamp)
{
if (mHasValue)
{
- LLUnitImplicit<F64, LLUnits::Seconds> delta_time = time_stamp - mLastSampleTimeStamp;
+ F64SecondsImplicit delta_time = time_stamp - mLastSampleTimeStamp;
mSum += mLastValue * delta_time;
mTotalSamplingTime += delta_time;
F64 old_mean = mMean;
@@ -353,7 +353,7 @@ namespace LLTrace
F64 getMean() const { return mMean; }
F64 getStandardDeviation() const { return sqrtf(mSumOfSquares / mTotalSamplingTime); }
F64 getSumOfSquares() const { return mSumOfSquares; }
- LLUnitImplicit<F64, LLUnits::Seconds> getSamplingTime() { return mTotalSamplingTime; }
+ F64SecondsImplicit getSamplingTime() { return mTotalSamplingTime; }
U32 getSampleCount() const { return mNumSamples; }
bool hasValue() const { return mHasValue; }
@@ -368,7 +368,7 @@ namespace LLTrace
F64 mMean,
mSumOfSquares;
- LLUnitImplicit<F64, LLUnits::Seconds>
+ F64SecondsImplicit
mLastSampleTimeStamp,
mTotalSamplingTime;
@@ -403,7 +403,7 @@ namespace LLTrace
mSum = 0;
}
- void sync(LLUnitImplicit<F64, LLUnits::Seconds>) {}
+ void sync(F64SecondsImplicit) {}
F64 getSum() const { return mSum; }
@@ -435,7 +435,7 @@ namespace LLTrace
TimeBlockAccumulator();
void addSamples(const self_t& other, EBufferAppendType append_type);
void reset(const self_t* other);
- void sync(LLUnitImplicit<F64, LLUnits::Seconds>) {}
+ void sync(F64SecondsImplicit) {}
//
// members
@@ -516,7 +516,7 @@ namespace LLTrace
mDeallocatedCount = 0;
}
- void sync(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
+ void sync(F64SecondsImplicit time_stamp)
{
mSize.sync(time_stamp);
mChildSize.sync(time_stamp);
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index f5fb2bf561..ea090e6ee1 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -490,7 +490,7 @@ namespace LLTrace
for (S32 i = 1; i <= num_periods; i++)
{
Recording& recording = getPrevRecording(i);
- if (recording.getDuration() > 0.f)
+ if (recording.getDuration() > (F32Seconds)0.f)
{
mean += recording.getSum(stat);
}
@@ -530,7 +530,7 @@ namespace LLTrace
for (S32 i = 1; i <= num_periods; i++)
{
Recording& recording = getPrevRecording(i);
- if (recording.getDuration() > 0.f)
+ if (recording.getDuration() > (F32Seconds)0.f)
{
mean += recording.getPerSec(stat);
}
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index b62bebc440..c49c882f23 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -31,11 +31,29 @@
#include "llpreprocessor.h"
#include "llerror.h"
+//lightweight replacement of type traits for simple type equality check
+template<typename S, typename T>
+struct LLIsSameType
+{
+ static const bool value = false;
+};
+
+template<typename T>
+struct LLIsSameType<T, T>
+{
+ static const bool value = true;
+};
+
+template<typename S, typename T>
+struct LLPromotedType
+{
+ typedef decltype(S() + T()) type_t;
+};
+
template<typename STORAGE_TYPE, typename UNIT_TYPE>
struct LLUnit
{
typedef LLUnit<STORAGE_TYPE, UNIT_TYPE> self_t;
-
typedef STORAGE_TYPE storage_t;
// value initialization
@@ -49,18 +67,6 @@ struct LLUnit
: mValue(convert(other).mValue)
{}
- bool operator == (const self_t& other)
- {
- return mValue = other.mValue;
- }
-
- // value assignment
- self_t& operator = (storage_t value)
- {
- mValue = value;
- return *this;
- }
-
// unit assignment
template<typename OTHER_STORAGE, typename OTHER_UNIT>
self_t& operator = (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
@@ -91,22 +97,12 @@ struct LLUnit
*this = LLUnit<storage_t, NEW_UNIT_TYPE>(value);
}
- void operator += (storage_t value)
- {
- mValue += value;
- }
-
template<typename OTHER_STORAGE, typename OTHER_UNIT>
void operator += (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
{
mValue += convert(other).mValue;
}
- void operator -= (storage_t value)
- {
- mValue -= value;
- }
-
template<typename OTHER_STORAGE, typename OTHER_UNIT>
void operator -= (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
{
@@ -161,7 +157,7 @@ std::istream& operator >>(std::istream& s, LLUnit<STORAGE_TYPE, UNIT_TYPE>& unit
{
STORAGE_TYPE val;
s >> val;
- unit = val;
+ unit.value(val);
return s;
}
@@ -181,12 +177,37 @@ struct LLUnitImplicit : public LLUnit<STORAGE_TYPE, UNIT_TYPE>
: base_t(convert(other))
{}
- // unlike LLUnit, LLUnitImplicit is *implicitly* convertable to a POD scalar (F32, S32, etc)
+ // unlike LLUnit, LLUnitImplicit is *implicitly* convertable to a POD value (F32, S32, etc)
// this allows for interoperability with legacy code
operator storage_t() const
{
return base_t::value();
}
+
+ using base_t::operator +=;
+ void operator += (storage_t value)
+ {
+ mValue += value;
+ }
+
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ void operator += (LLUnitImplicit<OTHER_STORAGE, OTHER_UNIT> other)
+ {
+ mValue += convert(other).value();
+ }
+
+ using base_t::operator -=;
+ void operator -= (storage_t value)
+ {
+ mValue -= value;
+ }
+
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ void operator -= (LLUnitImplicit<OTHER_STORAGE, OTHER_UNIT> other)
+ {
+ mValue -= convert(other).value();
+ }
+
};
template<typename STORAGE_TYPE, typename UNIT_TYPE>
@@ -205,24 +226,12 @@ std::istream& operator >>(std::istream& s, LLUnitImplicit<STORAGE_TYPE, UNIT_TYP
return s;
}
-template<typename S, typename T>
-struct LLIsSameType
-{
- static const bool value = false;
-};
-
-template<typename T>
-struct LLIsSameType<T, T>
-{
- static const bool value = true;
-};
-
template<typename S1, typename T1, typename S2, typename T2>
LL_FORCE_INLINE void ll_convert_units(LLUnit<S1, T1> in, LLUnit<S2, T2>& out, ...)
{
LL_STATIC_ASSERT((LLIsSameType<T1, T2>::value
|| !LLIsSameType<T1, typename T1::base_unit_t>::value
- || !LLIsSameType<T2, typename T2::base_unit_t>::value), "invalid conversion");
+ || !LLIsSameType<T2, typename T2::base_unit_t>::value), "invalid conversion: incompatible units");
if (LLIsSameType<T1, typename T1::base_unit_t>::value)
{
@@ -253,65 +262,63 @@ LL_FORCE_INLINE void ll_convert_units(LLUnit<S1, T1> in, LLUnit<S2, T2>& out, ..
// operator +
//
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<decltype(STORAGE_TYPE1() + STORAGE_TYPE2()), UNIT_TYPE1> operator + (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ LLUnit<decltype(STORAGE_TYPE1() + STORAGE_TYPE2()), UNIT_TYPE1> result(first);
result += second;
return result;
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator + (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS second)
{
- LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
- result += second;
- return result;
+ LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "operator + requires compatible unit types");
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>(0);
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator + (UNITLESS first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
{
- LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
- result += second;
- return result;
+ LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "operator + requires compatible unit types");
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>(0);
}
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<decltype(STORAGE_TYPE1() + STORAGE_TYPE2()), UNIT_TYPE1> operator + (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ LLUnitImplicit<decltype(STORAGE_TYPE1() + STORAGE_TYPE2()), UNIT_TYPE1> result(first);
result += second;
return result;
}
template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
-LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
+LLUnitImplicit<decltype(STORAGE_TYPE1() + STORAGE_TYPE2()), UNIT_TYPE1> operator + (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ LLUnitImplicit<decltype(STORAGE_TYPE1() + STORAGE_TYPE2()), UNIT_TYPE1> result(first);
result += second;
return result;
}
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<decltype(STORAGE_TYPE1() + STORAGE_TYPE2()), UNIT_TYPE1> operator + (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ LLUnitImplicit<decltype(STORAGE_TYPE1() + STORAGE_TYPE2()), UNIT_TYPE1> result(first);
result += LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>(second);
return result;
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnitImplicit<decltype(STORAGE_TYPE() + UNITLESS_TYPE()), UNIT_TYPE> operator + (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS_TYPE second)
{
- LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ LLUnitImplicit<decltype(STORAGE_TYPE() + UNITLESS_TYPE()), UNIT_TYPE> result(first);
result += second;
return result;
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnitImplicit<decltype(UNITLESS_TYPE() + STORAGE_TYPE()), UNIT_TYPE> operator + (UNITLESS_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> second)
{
- LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ LLUnitImplicit<decltype(UNITLESS_TYPE() + STORAGE_TYPE()), UNIT_TYPE> result(first);
result += second;
return result;
}
@@ -320,65 +327,63 @@ LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator + (SCALAR_TYPE first, LLUnitImp
// operator -
//
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<decltype(STORAGE_TYPE1() - STORAGE_TYPE2()), UNIT_TYPE1> operator - (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ LLUnit<decltype(STORAGE_TYPE1() - STORAGE_TYPE2()), UNIT_TYPE1> result(first);
result -= second;
return result;
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator - (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS second)
{
- LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
- result -= second;
- return result;
+ LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "operator - requires compatible unit types");
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>(0);
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator - (UNITLESS first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
{
- LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
- result -= second;
- return result;
+ LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "operator - requires compatible unit types");
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>(0);
}
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<decltype(STORAGE_TYPE1() - STORAGE_TYPE2()), UNIT_TYPE1> operator - (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ LLUnitImplicit<decltype(STORAGE_TYPE1() - STORAGE_TYPE2()), UNIT_TYPE1> result(first);
result -= second;
return result;
}
template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
-LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator - (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
+LLUnitImplicit<decltype(STORAGE_TYPE1() - STORAGE_TYPE2()), UNIT_TYPE1> operator - (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ LLUnitImplicit<decltype(STORAGE_TYPE1() - STORAGE_TYPE2()), UNIT_TYPE1> result(first);
result -= second;
return result;
}
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<decltype(STORAGE_TYPE1() - STORAGE_TYPE2()), UNIT_TYPE1> operator - (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ LLUnitImplicit<decltype(STORAGE_TYPE1() - STORAGE_TYPE2()), UNIT_TYPE1> result(first);
result -= LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>(second);
return result;
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnitImplicit<decltype(STORAGE_TYPE() - UNITLESS_TYPE()), UNIT_TYPE> operator - (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS_TYPE second)
{
- LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ LLUnitImplicit<decltype(STORAGE_TYPE() - UNITLESS_TYPE()), UNIT_TYPE> result(first);
result -= second;
return result;
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnitImplicit<decltype(UNITLESS_TYPE() - STORAGE_TYPE()), UNIT_TYPE> operator - (UNITLESS_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> second)
{
- LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ LLUnitImplicit<decltype(UNITLESS_TYPE() - STORAGE_TYPE()), UNIT_TYPE> result(first);
result -= second;
return result;
}
@@ -390,119 +395,144 @@ template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, ty
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
- LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "Multiplication of unit types results in new unit type - not supported.");
+ LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "multiplication of unit types results in new unit type - not supported.");
return LLUnit<STORAGE_TYPE1, UNIT_TYPE1>();
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnit<decltype(STORAGE_TYPE() * UNITLESS_TYPE()), UNIT_TYPE> operator * (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS_TYPE second)
{
- return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first.value() * second));
+ return LLUnit<decltype(STORAGE_TYPE() * UNITLESS_TYPE()), UNIT_TYPE>(first.value() * 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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnit<decltype(UNITLESS_TYPE() * STORAGE_TYPE()), UNIT_TYPE> operator * (UNITLESS_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
{
- return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first * second.value()));
+ return LLUnit<decltype(UNITLESS_TYPE() * STORAGE_TYPE()), UNIT_TYPE>(first * second.value());
}
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
- LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "Multiplication of unit types results in new unit type - not supported.");
+ LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "multiplication of unit types results in new unit type - not supported.");
return LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>();
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnitImplicit<decltype(STORAGE_TYPE() * UNITLESS_TYPE()), UNIT_TYPE> operator * (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS_TYPE second)
{
- return LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE>(first.value() * second);
+ return LLUnitImplicit<decltype(STORAGE_TYPE() * UNITLESS_TYPE()), UNIT_TYPE>(first.value() * 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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnitImplicit<decltype(UNITLESS_TYPE() * STORAGE_TYPE()), UNIT_TYPE> operator * (UNITLESS_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> second)
{
- return LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE>(first * second.value());
+ return LLUnitImplicit<decltype(UNITLESS_TYPE() * STORAGE_TYPE()), UNIT_TYPE>(first * second.value());
}
//
// operator /
//
-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 STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
-LLUnit<STORAGE_TYPE, UNIT_TYPE> operator / (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnit<decltype(STORAGE_TYPE() / UNITLESS_TYPE()), UNIT_TYPE> operator / (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS_TYPE second)
{
- return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first.value() / second));
+ return LLUnit<decltype(STORAGE_TYPE() / UNITLESS_TYPE()), UNIT_TYPE>(first.value() / 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)
+decltype(STORAGE_TYPE1() / STORAGE_TYPE2()) operator / (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- return STORAGE_TYPE1(first.value() / first.convert(second));
+ return first.value() / first.convert(second).value();
}
-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)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE>
+LLUnitImplicit<decltype(STORAGE_TYPE() / UNITLESS_TYPE()), UNIT_TYPE> operator / (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS_TYPE second)
{
- return LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first.value() / second));
+ return LLUnitImplicit<decltype(STORAGE_TYPE() / UNITLESS_TYPE()), UNIT_TYPE>(first.value() / 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)
+decltype(STORAGE_TYPE1() / STORAGE_TYPE2()) operator / (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- return STORAGE_TYPE1(first.value() / first.convert(second));
+ return (decltype(STORAGE_TYPE1() / STORAGE_TYPE2()))(first.value() / first.convert(second).value());
}
template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
-STORAGE_TYPE1 operator / (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
+decltype(STORAGE_TYPE1() / STORAGE_TYPE2()) operator / (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
{
- return STORAGE_TYPE1(first.value() / first.convert(second));
+ return (decltype(STORAGE_TYPE1() / STORAGE_TYPE2()))(first.value() / first.convert(second).value());
}
template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
-STORAGE_TYPE1 operator / (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
-{
- return STORAGE_TYPE1(first.value() / first.convert(second));
-}
-
-#define COMPARISON_OPERATORS(op) \
-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 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 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 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); \
-}
-
-COMPARISON_OPERATORS(<)
-COMPARISON_OPERATORS(<=)
-COMPARISON_OPERATORS(>)
-COMPARISON_OPERATORS(>=)
-COMPARISON_OPERATORS(==)
-COMPARISON_OPERATORS(!=)
+decltype(STORAGE_TYPE1() / STORAGE_TYPE2()) operator / (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
+{
+ return (decltype(STORAGE_TYPE1() / STORAGE_TYPE2()))(first.value() / first.convert(second).value());
+}
+
+//
+// comparison operators
+//
+
+#define LL_UNIT_DECLARE_COMPARISON_OPERATOR(op) \
+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).value(); \
+} \
+ \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE> \
+bool operator op (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS_TYPE second) \
+{ \
+ return first.value() op second; \
+} \
+ \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE> \
+bool operator op (UNITLESS_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> second) \
+{ \
+ return first op second.value(); \
+} \
+ \
+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).value(); \
+} \
+ \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE> \
+bool operator op (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, UNITLESS_TYPE second) \
+{ \
+ LL_BAD_TEMPLATE_INSTANTIATION(UNITLESS_TYPE, "operator " #op " requires compatible unit types"); \
+ return false; \
+} \
+ \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename UNITLESS_TYPE> \
+bool operator op (UNITLESS_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second) \
+{ \
+ LL_BAD_TEMPLATE_INSTANTIATION(UNITLESS_TYPE, "operator " #op " requires compatible unit types"); \
+ return false; \
+} \
+ \
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2> \
+bool operator op (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second).value(); \
+} \
+ \
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2> \
+bool operator op (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second).value(); \
+}
+
+LL_UNIT_DECLARE_COMPARISON_OPERATOR(<);
+LL_UNIT_DECLARE_COMPARISON_OPERATOR(<=);
+LL_UNIT_DECLARE_COMPARISON_OPERATOR(>);
+LL_UNIT_DECLARE_COMPARISON_OPERATOR(>=);
+LL_UNIT_DECLARE_COMPARISON_OPERATOR(==);
+LL_UNIT_DECLARE_COMPARISON_OPERATOR(!=);
template<typename T>
@@ -517,8 +547,6 @@ struct LLGetUnitLabel<LLUnit<STORAGE_T, T> >
static const char* getUnitLabel() { return T::getUnitLabel(); }
};
-#define LL_UNIT_PROMOTE_VALUE(output_type, value) ((true ? (output_type)(1) : (value/value)) * value)
-
template<typename INPUT_TYPE, typename OUTPUT_TYPE>
struct LLUnitLinearOps
{
@@ -534,25 +562,25 @@ struct LLUnitLinearOps
template<typename T>
output_t operator * (T other)
{
- return mInput * other;
+ return typename LLPromotedType<INPUT_TYPE, OUTPUT_TYPE>::type_t(mInput) * other;
}
template<typename T>
output_t operator / (T other)
{
- return LL_UNIT_PROMOTE_VALUE(OUTPUT_TYPE, mInput) / other;
+ return typename LLPromotedType<INPUT_TYPE, OUTPUT_TYPE>::type_t(mInput) / other;
}
template<typename T>
output_t operator + (T other)
{
- return mInput + other;
+ return typename LLPromotedType<INPUT_TYPE, OUTPUT_TYPE>::type_t(mInput) + other;
}
template<typename T>
output_t operator - (T other)
{
- return mInput - other;
+ return typename LLPromotedType<INPUT_TYPE, OUTPUT_TYPE>::type_t(mInput) - other;
}
};
@@ -571,25 +599,25 @@ struct LLUnitInverseLinearOps
template<typename T>
output_t operator * (T other)
{
- return LL_UNIT_PROMOTE_VALUE(OUTPUT_TYPE, mInput) / other;
+ return typename LLPromotedType<INPUT_TYPE, OUTPUT_TYPE>::type_t(mInput) / other;
}
template<typename T>
output_t operator / (T other)
{
- return mInput * other;
+ return typename LLPromotedType<INPUT_TYPE, OUTPUT_TYPE>::type_t(mInput) * other;
}
template<typename T>
output_t operator + (T other)
{
- return mInput - other;
+ return typename LLPromotedType<INPUT_TYPE, OUTPUT_TYPE>::type_t(mInput) - other;
}
template<typename T>
output_t operator - (T other)
{
- return mInput + other;
+ return typename LLPromotedType<INPUT_TYPE, OUTPUT_TYPE>::type_t(mInput) + other;
}
};
@@ -621,13 +649,13 @@ struct unit_name
template<typename S1, typename S2> \
void ll_convert_units(LLUnit<S1, unit_name> in, LLUnit<S2, base_unit_name>& out) \
{ \
- out = LLUnit<S2, base_unit_name>((S2)(LLUnitLinearOps<S1, S2>(in.value()) conversion_operation)); \
+ out = LLUnit<S2, base_unit_name>((S2)(LLUnitLinearOps<S1, S2>(in.value()) conversion_operation)); \
} \
\
template<typename S1, typename S2> \
void ll_convert_units(LLUnit<S1, base_unit_name> in, LLUnit<S2, unit_name>& out) \
{ \
- out = LLUnit<S2, unit_name>((S2)(LLUnitInverseLinearOps<S1, S2>(in.value()) conversion_operation)); \
+ out = LLUnit<S2, unit_name>((S2)(LLUnitInverseLinearOps<S1, S2>(in.value()) conversion_operation)); \
}
//
@@ -637,120 +665,140 @@ void ll_convert_units(LLUnit<S1, base_unit_name> in, LLUnit<S2, unit_name>& out)
namespace LLUnits
{
LL_DECLARE_BASE_UNIT(Bytes, "B");
-LL_DECLARE_DERIVED_UNIT(Bytes, * 1000, Kilobytes, "KB");
-LL_DECLARE_DERIVED_UNIT(Kilobytes, * 1000, Megabytes, "MB");
-LL_DECLARE_DERIVED_UNIT(Megabytes, * 1000, Gigabytes, "GB");
-LL_DECLARE_DERIVED_UNIT(Bytes, * 1024, Kibibytes, "KiB");
-LL_DECLARE_DERIVED_UNIT(Kibibytes, * 1024, Mibibytes, "MiB");
-LL_DECLARE_DERIVED_UNIT(Mibibytes, * 1024, Gibibytes, "GiB");
+// technically, these are kibibytes, mibibytes, etc. but we should stick with commonly accepted terminology
+LL_DECLARE_DERIVED_UNIT(Bytes, * 1024, Kilobytes, "KB");
+LL_DECLARE_DERIVED_UNIT(Kilobytes, * 1024, Megabytes, "MB");
+LL_DECLARE_DERIVED_UNIT(Megabytes, * 1024, Gigabytes, "GB");
}
typedef LLUnit<F32, LLUnits::Bytes> F32Bytes;
typedef LLUnit<F32, LLUnits::Kilobytes> F32Kilobytes;
typedef LLUnit<F32, LLUnits::Megabytes> F32Megabytes;
typedef LLUnit<F32, LLUnits::Gigabytes> F32Gigabytes;
-typedef LLUnit<F32, LLUnits::Kibibytes> F32Kibibytes;
-typedef LLUnit<F32, LLUnits::Mibibytes> F32Mibibytes;
-typedef LLUnit<F32, LLUnits::Gibibytes> F32Gibibytes;
+
+typedef LLUnitImplicit<F32, LLUnits::Bytes> F32BytesImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Kilobytes> F32KilobytesImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Megabytes> F32MegabytesImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Gigabytes> F32GigabytesImplicit;
typedef LLUnit<F64, LLUnits::Bytes> F64Bytes;
typedef LLUnit<F64, LLUnits::Kilobytes> F64Kilobytes;
typedef LLUnit<F64, LLUnits::Megabytes> F64Megabytes;
typedef LLUnit<F64, LLUnits::Gigabytes> F64Gigabytes;
-typedef LLUnit<F64, LLUnits::Kibibytes> F64Kibibytes;
-typedef LLUnit<F64, LLUnits::Mibibytes> F64Mibibytes;
-typedef LLUnit<F64, LLUnits::Gibibytes> F64Gibibytes;
+
+typedef LLUnitImplicit<F64, LLUnits::Bytes> F64BytesImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Kilobytes> F64KilobytesImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Megabytes> F64MegabytesImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Gigabytes> F64GigabytesImplicit;
typedef LLUnit<S32, LLUnits::Bytes> S32Bytes;
typedef LLUnit<S32, LLUnits::Kilobytes> S32Kilobytes;
typedef LLUnit<S32, LLUnits::Megabytes> S32Megabytes;
typedef LLUnit<S32, LLUnits::Gigabytes> S32Gigabytes;
-typedef LLUnit<S32, LLUnits::Kibibytes> S32Kibibytes;
-typedef LLUnit<S32, LLUnits::Mibibytes> S32Mibibytes;
-typedef LLUnit<S32, LLUnits::Gibibytes> S32Gibibytes;
-typedef LLUnit<U32, LLUnits::Bytes> U32Bytes;
-typedef LLUnit<U32, LLUnits::Kilobytes> U32Kilobytes;
-typedef LLUnit<U32, LLUnits::Megabytes> U32Megabytes;
-typedef LLUnit<U32, LLUnits::Gigabytes> U32Gigabytes;
-typedef LLUnit<U32, LLUnits::Kibibytes> U32Kibibytes;
-typedef LLUnit<U32, LLUnits::Mibibytes> U32Mibibytes;
-typedef LLUnit<U32, LLUnits::Gibibytes> U32Gibibytes;
+typedef LLUnitImplicit<S32, LLUnits::Bytes> S32BytesImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Kilobytes> S32KilobytesImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Megabytes> S32MegabytesImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Gigabytes> S32GigabytesImplicit;
typedef LLUnit<S64, LLUnits::Bytes> S64Bytes;
typedef LLUnit<S64, LLUnits::Kilobytes> S64Kilobytes;
typedef LLUnit<S64, LLUnits::Megabytes> S64Megabytes;
typedef LLUnit<S64, LLUnits::Gigabytes> S64Gigabytes;
-typedef LLUnit<S64, LLUnits::Kibibytes> S64Kibibytes;
-typedef LLUnit<S64, LLUnits::Mibibytes> S64Mibibytes;
-typedef LLUnit<S64, LLUnits::Gibibytes> S64Gibibytes;
+
+typedef LLUnitImplicit<S64, LLUnits::Bytes> S64BytesImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Kilobytes> S64KilobytesImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Megabytes> S64MegabytesImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Gigabytes> S64GigabytesImplicit;
+
+typedef LLUnit<U32, LLUnits::Bytes> U32Bytes;
+typedef LLUnit<U32, LLUnits::Kilobytes> U32Kilobytes;
+typedef LLUnit<U32, LLUnits::Megabytes> U32Megabytes;
+typedef LLUnit<U32, LLUnits::Gigabytes> U32Gigabytes;
+
+typedef LLUnitImplicit<U32, LLUnits::Bytes> U32BytesImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Kilobytes> U32KilobytesImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Megabytes> U32MegabytesImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Gigabytes> U32GigabytesImplicit;
typedef LLUnit<U64, LLUnits::Bytes> U64Bytes;
typedef LLUnit<U64, LLUnits::Kilobytes> U64Kilobytes;
typedef LLUnit<U64, LLUnits::Megabytes> U64Megabytes;
typedef LLUnit<U64, LLUnits::Gigabytes> U64Gigabytes;
-typedef LLUnit<U64, LLUnits::Kibibytes> U64Kibibytes;
-typedef LLUnit<U64, LLUnits::Mibibytes> U64Mibibytes;
-typedef LLUnit<U64, LLUnits::Gibibytes> U64Gibibytes;
+
+typedef LLUnitImplicit<U64, LLUnits::Bytes> U64BytesImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Kilobytes> U64KilobytesImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Megabytes> U64MegabytesImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Gigabytes> U64GigabytesImplicit;
namespace LLUnits
{
+// technically, these are kibibits, mibibits, etc. but we should stick with commonly accepted terminology
LL_DECLARE_DERIVED_UNIT(Bytes, / 8, Bits, "b");
-LL_DECLARE_DERIVED_UNIT(Bits, * 1000, Kilobits, "Kb");
-LL_DECLARE_DERIVED_UNIT(Kilobits, * 1000, Megabits, "Mb");
-LL_DECLARE_DERIVED_UNIT(Megabits, * 1000, Gigabits, "Gb");
-LL_DECLARE_DERIVED_UNIT(Bits, * 1024, Kibibits, "Kib");
-LL_DECLARE_DERIVED_UNIT(Kibibits, * 1024, Mibibits, "Mib");
-LL_DECLARE_DERIVED_UNIT(Mibibits, * 1024, Gibibits, "Gib");
+LL_DECLARE_DERIVED_UNIT(Bits, * 1024, Kilobits, "Kb");
+LL_DECLARE_DERIVED_UNIT(Kilobits, * 1024, Megabits, "Mb");
+LL_DECLARE_DERIVED_UNIT(Megabits, * 1024, Gigabits, "Gb");
}
typedef LLUnit<F32, LLUnits::Bits> F32Bits;
typedef LLUnit<F32, LLUnits::Kilobits> F32Kilobits;
typedef LLUnit<F32, LLUnits::Megabits> F32Megabits;
typedef LLUnit<F32, LLUnits::Gigabits> F32Gigabits;
-typedef LLUnit<F32, LLUnits::Kibibits> F32Kibibits;
-typedef LLUnit<F32, LLUnits::Mibibits> F32Mibibits;
-typedef LLUnit<F32, LLUnits::Gibibits> F32Gibibits;
-
+
+typedef LLUnitImplicit<F32, LLUnits::Bits> F32BitsImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Kilobits> F32KilobitsImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Megabits> F32MegabitsImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Gigabits> F32GigabitsImplicit;
+
typedef LLUnit<F64, LLUnits::Bits> F64Bits;
typedef LLUnit<F64, LLUnits::Kilobits> F64Kilobits;
typedef LLUnit<F64, LLUnits::Megabits> F64Megabits;
typedef LLUnit<F64, LLUnits::Gigabits> F64Gigabits;
-typedef LLUnit<F64, LLUnits::Kibibits> F64Kibibits;
-typedef LLUnit<F64, LLUnits::Mibibits> F64Mibibits;
-typedef LLUnit<F64, LLUnits::Gibibits> F64Gibibits;
+
+typedef LLUnitImplicit<F64, LLUnits::Bits> F64BitsImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Kilobits> F64KilobitsImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Megabits> F64MegabitsImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Gigabits> F64GigabitsImplicit;
typedef LLUnit<S32, LLUnits::Bits> S32Bits;
typedef LLUnit<S32, LLUnits::Kilobits> S32Kilobits;
typedef LLUnit<S32, LLUnits::Megabits> S32Megabits;
typedef LLUnit<S32, LLUnits::Gigabits> S32Gigabits;
-typedef LLUnit<S32, LLUnits::Kibibits> S32Kibibits;
-typedef LLUnit<S32, LLUnits::Mibibits> S32Mibibits;
-typedef LLUnit<S32, LLUnits::Gibibits> S32Gibibits;
-typedef LLUnit<U32, LLUnits::Bits> U32Bits;
-typedef LLUnit<U32, LLUnits::Kilobits> U32Kilobits;
-typedef LLUnit<U32, LLUnits::Megabits> U32Megabits;
-typedef LLUnit<U32, LLUnits::Gigabits> U32Gigabits;
-typedef LLUnit<U32, LLUnits::Kibibits> U32Kibibits;
-typedef LLUnit<U32, LLUnits::Mibibits> U32Mibibits;
-typedef LLUnit<U32, LLUnits::Gibibits> U32Gibibits;
+typedef LLUnitImplicit<S32, LLUnits::Bits> S32BitsImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Kilobits> S32KilobitsImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Megabits> S32MegabitsImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Gigabits> S32GigabitsImplicit;
typedef LLUnit<S64, LLUnits::Bits> S64Bits;
typedef LLUnit<S64, LLUnits::Kilobits> S64Kilobits;
typedef LLUnit<S64, LLUnits::Megabits> S64Megabits;
typedef LLUnit<S64, LLUnits::Gigabits> S64Gigabits;
-typedef LLUnit<S64, LLUnits::Kibibits> S64Kibibits;
-typedef LLUnit<S64, LLUnits::Mibibits> S64Mibibits;
-typedef LLUnit<S64, LLUnits::Gibibits> S64Gibibits;
+
+typedef LLUnitImplicit<S64, LLUnits::Bits> S64BitsImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Kilobits> S64KilobitsImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Megabits> S64MegabitsImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Gigabits> S64GigabitsImplicit;
+
+typedef LLUnit<U32, LLUnits::Bits> U32Bits;
+typedef LLUnit<U32, LLUnits::Kilobits> U32Kilobits;
+typedef LLUnit<U32, LLUnits::Megabits> U32Megabits;
+typedef LLUnit<U32, LLUnits::Gigabits> U32Gigabits;
+
+typedef LLUnitImplicit<U32, LLUnits::Bits> U32BitsImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Kilobits> U32KilobitsImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Megabits> U32MegabitsImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Gigabits> U32GigabitsImplicit;
typedef LLUnit<U64, LLUnits::Bits> U64Bits;
typedef LLUnit<U64, LLUnits::Kilobits> U64Kilobits;
typedef LLUnit<U64, LLUnits::Megabits> U64Megabits;
typedef LLUnit<U64, LLUnits::Gigabits> U64Gigabits;
-typedef LLUnit<U64, LLUnits::Kibibits> U64Kibibits;
-typedef LLUnit<U64, LLUnits::Mibibits> U64Mibibits;
-typedef LLUnit<U64, LLUnits::Gibibits> U64Gibibits;
+
+typedef LLUnitImplicit<U64, LLUnits::Bits> U64BitsImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Kilobits> U64KilobitsImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Megabits> U64MegabitsImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Gigabits> U64GigabitsImplicit;
namespace LLUnits
{
@@ -771,6 +819,14 @@ typedef LLUnit<F32, LLUnits::Milliseconds> F32Milliseconds;
typedef LLUnit<F32, LLUnits::Microseconds> F32Microseconds;
typedef LLUnit<F32, LLUnits::Nanoseconds> F32Nanoseconds;
+typedef LLUnitImplicit<F32, LLUnits::Seconds> F32SecondsImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Minutes> F32MinutesImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Hours> F32HoursImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Days> F32DaysImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Milliseconds> F32MillisecondsImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Microseconds> F32MicrosecondsImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Nanoseconds> F32NanosecondsImplicit;
+
typedef LLUnit<F64, LLUnits::Seconds> F64Seconds;
typedef LLUnit<F64, LLUnits::Minutes> F64Minutes;
typedef LLUnit<F64, LLUnits::Hours> F64Hours;
@@ -779,6 +835,14 @@ typedef LLUnit<F64, LLUnits::Milliseconds> F64Milliseconds;
typedef LLUnit<F64, LLUnits::Microseconds> F64Microseconds;
typedef LLUnit<F64, LLUnits::Nanoseconds> F64Nanoseconds;
+typedef LLUnitImplicit<F64, LLUnits::Seconds> F64SecondsImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Minutes> F64MinutesImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Hours> F64HoursImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Days> F64DaysImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Milliseconds> F64MillisecondsImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Microseconds> F64MicrosecondsImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Nanoseconds> F64NanosecondsImplicit;
+
typedef LLUnit<S32, LLUnits::Seconds> S32Seconds;
typedef LLUnit<S32, LLUnits::Minutes> S32Minutes;
typedef LLUnit<S32, LLUnits::Hours> S32Hours;
@@ -787,13 +851,13 @@ typedef LLUnit<S32, LLUnits::Milliseconds> S32Milliseconds;
typedef LLUnit<S32, LLUnits::Microseconds> S32Microseconds;
typedef LLUnit<S32, LLUnits::Nanoseconds> S32Nanoseconds;
-typedef LLUnit<U32, LLUnits::Seconds> U32Seconds;
-typedef LLUnit<U32, LLUnits::Minutes> U32Minutes;
-typedef LLUnit<U32, LLUnits::Hours> U32Hours;
-typedef LLUnit<U32, LLUnits::Days> U32Days;
-typedef LLUnit<U32, LLUnits::Milliseconds> U32Milliseconds;
-typedef LLUnit<U32, LLUnits::Microseconds> U32Microseconds;
-typedef LLUnit<U32, LLUnits::Nanoseconds> U32Nanoseconds;
+typedef LLUnitImplicit<S32, LLUnits::Seconds> S32SecondsImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Minutes> S32MinutesImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Hours> S32HoursImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Days> S32DaysImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Milliseconds> S32MillisecondsImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Microseconds> S32MicrosecondsImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Nanoseconds> S32NanosecondsImplicit;
typedef LLUnit<S64, LLUnits::Seconds> S64Seconds;
typedef LLUnit<S64, LLUnits::Minutes> S64Minutes;
@@ -802,7 +866,31 @@ typedef LLUnit<S64, LLUnits::Days> S64Days;
typedef LLUnit<S64, LLUnits::Milliseconds> S64Milliseconds;
typedef LLUnit<S64, LLUnits::Microseconds> S64Microseconds;
typedef LLUnit<S64, LLUnits::Nanoseconds> S64Nanoseconds;
-
+
+typedef LLUnitImplicit<S64, LLUnits::Seconds> S64SecondsImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Minutes> S64MinutesImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Hours> S64HoursImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Days> S64DaysImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Milliseconds> S64MillisecondsImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Microseconds> S64MicrosecondsImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Nanoseconds> S64NanosecondsImplicit;
+
+typedef LLUnit<U32, LLUnits::Seconds> U32Seconds;
+typedef LLUnit<U32, LLUnits::Minutes> U32Minutes;
+typedef LLUnit<U32, LLUnits::Hours> U32Hours;
+typedef LLUnit<U32, LLUnits::Days> U32Days;
+typedef LLUnit<U32, LLUnits::Milliseconds> U32Milliseconds;
+typedef LLUnit<U32, LLUnits::Microseconds> U32Microseconds;
+typedef LLUnit<U32, LLUnits::Nanoseconds> U32Nanoseconds;
+
+typedef LLUnitImplicit<U32, LLUnits::Seconds> U32SecondsImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Minutes> U32MinutesImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Hours> U32HoursImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Days> U32DaysImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Milliseconds> U32MillisecondsImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Microseconds> U32MicrosecondsImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Nanoseconds> U32NanosecondsImplicit;
+
typedef LLUnit<U64, LLUnits::Seconds> U64Seconds;
typedef LLUnit<U64, LLUnits::Minutes> U64Minutes;
typedef LLUnit<U64, LLUnits::Hours> U64Hours;
@@ -811,6 +899,14 @@ typedef LLUnit<U64, LLUnits::Milliseconds> U64Milliseconds;
typedef LLUnit<U64, LLUnits::Microseconds> U64Microseconds;
typedef LLUnit<U64, LLUnits::Nanoseconds> U64Nanoseconds;
+typedef LLUnitImplicit<U64, LLUnits::Seconds> U64SecondsImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Minutes> U64MinutesImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Hours> U64HoursImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Days> U64DaysImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Milliseconds> U64MillisecondsImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Microseconds> U64MicrosecondsImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Nanoseconds> U64NanosecondsImplicit;
+
namespace LLUnits
{
LL_DECLARE_BASE_UNIT(Meters, "m");
@@ -824,31 +920,61 @@ typedef LLUnit<F32, LLUnits::Kilometers> F32Kilometers;
typedef LLUnit<F32, LLUnits::Centimeters> F32Centimeters;
typedef LLUnit<F32, LLUnits::Millimeters> F32Millimeters;
+typedef LLUnitImplicit<F32, LLUnits::Meters> F32MetersImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Kilometers> F32KilometersImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Centimeters> F32CentimetersImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Millimeters> F32MillimetersImplicit;
+
typedef LLUnit<F64, LLUnits::Meters> F64Meters;
typedef LLUnit<F64, LLUnits::Kilometers> F64Kilometers;
typedef LLUnit<F64, LLUnits::Centimeters> F64Centimeters;
typedef LLUnit<F64, LLUnits::Millimeters> F64Millimeters;
+typedef LLUnitImplicit<F64, LLUnits::Meters> F64MetersImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Kilometers> F64KilometersImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Centimeters> F64CentimetersImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Millimeters> F64MillimetersImplicit;
+
typedef LLUnit<S32, LLUnits::Meters> S32Meters;
typedef LLUnit<S32, LLUnits::Kilometers> S32Kilometers;
typedef LLUnit<S32, LLUnits::Centimeters> S32Centimeters;
typedef LLUnit<S32, LLUnits::Millimeters> S32Millimeters;
-typedef LLUnit<U32, LLUnits::Meters> U32Meters;
-typedef LLUnit<U32, LLUnits::Kilometers> U32Kilometers;
-typedef LLUnit<U32, LLUnits::Centimeters> U32Centimeters;
-typedef LLUnit<U32, LLUnits::Millimeters> U32Millimeters;
+typedef LLUnitImplicit<S32, LLUnits::Meters> S32MetersImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Kilometers> S32KilometersImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Centimeters> S32CentimetersImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Millimeters> S32MillimetersImplicit;
typedef LLUnit<S64, LLUnits::Meters> S64Meters;
typedef LLUnit<S64, LLUnits::Kilometers> S64Kilometers;
typedef LLUnit<S64, LLUnits::Centimeters> S64Centimeters;
typedef LLUnit<S64, LLUnits::Millimeters> S64Millimeters;
+typedef LLUnitImplicit<S64, LLUnits::Meters> S64MetersImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Kilometers> S64KilometersImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Centimeters> S64CentimetersImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Millimeters> S64MillimetersImplicit;
+
+typedef LLUnit<U32, LLUnits::Meters> U32Meters;
+typedef LLUnit<U32, LLUnits::Kilometers> U32Kilometers;
+typedef LLUnit<U32, LLUnits::Centimeters> U32Centimeters;
+typedef LLUnit<U32, LLUnits::Millimeters> U32Millimeters;
+
+typedef LLUnitImplicit<U32, LLUnits::Meters> U32MetersImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Kilometers> U32KilometersImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Centimeters> U32CentimetersImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Millimeters> U32MillimetersImplicit;
+
typedef LLUnit<U64, LLUnits::Meters> U64Meters;
typedef LLUnit<U64, LLUnits::Kilometers> U64Kilometers;
typedef LLUnit<U64, LLUnits::Centimeters> U64Centimeters;
typedef LLUnit<U64, LLUnits::Millimeters> U64Millimeters;
+typedef LLUnitImplicit<U64, LLUnits::Meters> U64MetersImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Kilometers> U64KilometersImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Centimeters> U64CentimetersImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Millimeters> U64MillimetersImplicit;
+
namespace LLUnits
{
// rare units
@@ -868,4 +994,137 @@ LL_DECLARE_DERIVED_UNIT(Triangles, * 1000, Kilotriangles, "ktris");
} // namespace LLUnits
+// rare units
+typedef LLUnit<F32, LLUnits::Hertz> F32Hertz;
+typedef LLUnit<F32, LLUnits::Kilohertz> F32Kilohertz;
+typedef LLUnit<F32, LLUnits::Megahertz> F32Megahertz;
+typedef LLUnit<F32, LLUnits::Gigahertz> F32Gigahertz;
+typedef LLUnit<F32, LLUnits::Radians> F32Radians;
+typedef LLUnit<F32, LLUnits::Degrees> F32Degrees;
+typedef LLUnit<F32, LLUnits::Percent> F32Percent;
+typedef LLUnit<F32, LLUnits::Ratio> F32Ratio;
+typedef LLUnit<F32, LLUnits::Triangles> F32Triangles;
+typedef LLUnit<F32, LLUnits::Kilotriangles> F32KiloTriangles;
+
+typedef LLUnitImplicit<F32, LLUnits::Hertz> F32HertzImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Kilohertz> F32KilohertzImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Megahertz> F32MegahertzImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Gigahertz> F32GigahertzImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Radians> F32RadiansImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Degrees> F32DegreesImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Percent> F32PercentImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Ratio> F32RatioImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Triangles> F32TrianglesImplicit;
+typedef LLUnitImplicit<F32, LLUnits::Kilotriangles> F32KiloTrianglesImplicit;
+
+typedef LLUnit<F64, LLUnits::Hertz> F64Hertz;
+typedef LLUnit<F64, LLUnits::Kilohertz> F64Kilohertz;
+typedef LLUnit<F64, LLUnits::Megahertz> F64Megahertz;
+typedef LLUnit<F64, LLUnits::Gigahertz> F64Gigahertz;
+typedef LLUnit<F64, LLUnits::Radians> F64Radians;
+typedef LLUnit<F64, LLUnits::Degrees> F64Degrees;
+typedef LLUnit<F64, LLUnits::Percent> F64Percent;
+typedef LLUnit<F64, LLUnits::Ratio> F64Ratio;
+typedef LLUnit<F64, LLUnits::Triangles> F64Triangles;
+typedef LLUnit<F64, LLUnits::Kilotriangles> F64KiloTriangles;
+
+typedef LLUnitImplicit<F64, LLUnits::Hertz> F64HertzImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Kilohertz> F64KilohertzImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Megahertz> F64MegahertzImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Gigahertz> F64GigahertzImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Radians> F64RadiansImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Degrees> F64DegreesImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Percent> F64PercentImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Ratio> F64RatioImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Triangles> F64TrianglesImplicit;
+typedef LLUnitImplicit<F64, LLUnits::Kilotriangles> F64KiloTrianglesImplicit;
+
+typedef LLUnit<S32, LLUnits::Hertz> S32Hertz;
+typedef LLUnit<S32, LLUnits::Kilohertz> S32Kilohertz;
+typedef LLUnit<S32, LLUnits::Megahertz> S32Megahertz;
+typedef LLUnit<S32, LLUnits::Gigahertz> S32Gigahertz;
+typedef LLUnit<S32, LLUnits::Radians> S32Radians;
+typedef LLUnit<S32, LLUnits::Degrees> S32Degrees;
+typedef LLUnit<S32, LLUnits::Percent> S32Percent;
+typedef LLUnit<S32, LLUnits::Ratio> S32Ratio;
+typedef LLUnit<S32, LLUnits::Triangles> S32Triangles;
+typedef LLUnit<S32, LLUnits::Kilotriangles> S32KiloTriangles;
+
+typedef LLUnitImplicit<S32, LLUnits::Hertz> S32HertzImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Kilohertz> S32KilohertzImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Megahertz> S32MegahertzImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Gigahertz> S32GigahertzImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Radians> S32RadiansImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Degrees> S32DegreesImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Percent> S32PercentImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Ratio> S32RatioImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Triangles> S32TrianglesImplicit;
+typedef LLUnitImplicit<S32, LLUnits::Kilotriangles> S32KiloTrianglesImplicit;
+
+typedef LLUnit<S64, LLUnits::Hertz> S64Hertz;
+typedef LLUnit<S64, LLUnits::Kilohertz> S64Kilohertz;
+typedef LLUnit<S64, LLUnits::Megahertz> S64Megahertz;
+typedef LLUnit<S64, LLUnits::Gigahertz> S64Gigahertz;
+typedef LLUnit<S64, LLUnits::Radians> S64Radians;
+typedef LLUnit<S64, LLUnits::Degrees> S64Degrees;
+typedef LLUnit<S64, LLUnits::Percent> S64Percent;
+typedef LLUnit<S64, LLUnits::Ratio> S64Ratio;
+typedef LLUnit<S64, LLUnits::Triangles> S64Triangles;
+typedef LLUnit<S64, LLUnits::Kilotriangles> S64KiloTriangles;
+
+typedef LLUnitImplicit<S64, LLUnits::Hertz> S64HertzImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Kilohertz> S64KilohertzImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Megahertz> S64MegahertzImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Gigahertz> S64GigahertzImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Radians> S64RadiansImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Degrees> S64DegreesImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Percent> S64PercentImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Ratio> S64RatioImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Triangles> S64TrianglesImplicit;
+typedef LLUnitImplicit<S64, LLUnits::Kilotriangles> S64KiloTrianglesImplicit;
+
+typedef LLUnit<U32, LLUnits::Hertz> U32Hertz;
+typedef LLUnit<U32, LLUnits::Kilohertz> U32Kilohertz;
+typedef LLUnit<U32, LLUnits::Megahertz> U32Megahertz;
+typedef LLUnit<U32, LLUnits::Gigahertz> U32Gigahertz;
+typedef LLUnit<U32, LLUnits::Radians> U32Radians;
+typedef LLUnit<U32, LLUnits::Degrees> U32Degrees;
+typedef LLUnit<U32, LLUnits::Percent> U32Percent;
+typedef LLUnit<U32, LLUnits::Ratio> U32Ratio;
+typedef LLUnit<U32, LLUnits::Triangles> U32Triangles;
+typedef LLUnit<U32, LLUnits::Kilotriangles> U32KiloTriangles;
+
+typedef LLUnitImplicit<U32, LLUnits::Hertz> U32HertzImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Kilohertz> U32KilohertzImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Megahertz> U32MegahertzImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Gigahertz> U32GigahertzImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Radians> U32RadiansImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Degrees> U32DegreesImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Percent> U32PercentImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Ratio> U32RatioImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Triangles> U32TrianglesImplicit;
+typedef LLUnitImplicit<U32, LLUnits::Kilotriangles> U32KiloTrianglesImplicit;
+
+typedef LLUnit<U64, LLUnits::Hertz> U64Hertz;
+typedef LLUnit<U64, LLUnits::Kilohertz> U64Kilohertz;
+typedef LLUnit<U64, LLUnits::Megahertz> U64Megahertz;
+typedef LLUnit<U64, LLUnits::Gigahertz> U64Gigahertz;
+typedef LLUnit<U64, LLUnits::Radians> U64Radians;
+typedef LLUnit<U64, LLUnits::Degrees> U64Degrees;
+typedef LLUnit<U64, LLUnits::Percent> U64Percent;
+typedef LLUnit<U64, LLUnits::Ratio> U64Ratio;
+typedef LLUnit<U64, LLUnits::Triangles> U64Triangles;
+typedef LLUnit<U64, LLUnits::Kilotriangles> U64KiloTriangles;
+
+typedef LLUnitImplicit<U64, LLUnits::Hertz> U64HertzImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Kilohertz> U64KilohertzImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Megahertz> U64MegahertzImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Gigahertz> U64GigahertzImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Radians> U64RadiansImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Degrees> U64DegreesImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Percent> U64PercentImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Ratio> U64RatioImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Triangles> U64TrianglesImplicit;
+typedef LLUnitImplicit<U64, LLUnits::Kilotriangles> U64KiloTrianglesImplicit;
+
#endif // LL_LLUNIT_H
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index 8546bcbc54..a8e9be86ca 100644
--- a/indra/llcommon/tests/llunits_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -38,6 +38,13 @@ namespace LLUnits
LL_DECLARE_DERIVED_UNIT(Latinum, / 16, Solari, "Sol");
}
+typedef LLUnit<F32, LLUnits::Quatloos> F32Quatloos;
+typedef LLUnit<S32, LLUnits::Quatloos> S32Quatloos;
+typedef LLUnit<F32, LLUnits::Latinum> F32Latinum;
+typedef LLUnit<S32, LLUnits::Latinum> S32Latinum;
+typedef LLUnit<F32, LLUnits::Solari> F32Solari;
+typedef LLUnit<S32, LLUnits::Solari> S32Solari;
+
namespace tut
{
using namespace LLUnits;
@@ -54,28 +61,28 @@ namespace tut
void units_object_t::test<1>()
{
LLUnit<F32, Quatloos> float_quatloos;
- ensure("default float unit is zero", float_quatloos == 0.f);
+ ensure("default float unit is zero", float_quatloos == F32Quatloos(0.f));
LLUnit<F32, Quatloos> float_initialize_quatloos(1);
- ensure("non-zero initialized unit", float_initialize_quatloos == 1.f);
+ ensure("non-zero initialized unit", float_initialize_quatloos == F32Quatloos(1.f));
LLUnit<S32, Quatloos> int_quatloos;
- ensure("default int unit is zero", int_quatloos == 0);
+ ensure("default int unit is zero", int_quatloos == S32Quatloos(0));
- int_quatloos = 42;
- ensure("int assignment is preserved", int_quatloos == 42);
+ int_quatloos = S32Quatloos(42);
+ ensure("int assignment is preserved", int_quatloos == S32Quatloos(42));
float_quatloos = int_quatloos;
- ensure("float assignment from int preserves value", float_quatloos == 42.f);
+ ensure("float assignment from int preserves value", float_quatloos == F32Quatloos(42.f));
int_quatloos = float_quatloos;
- ensure("int assignment from float preserves value", int_quatloos == 42);
+ ensure("int assignment from float preserves value", int_quatloos == S32Quatloos(42));
- float_quatloos = 42.1f;
+ float_quatloos = F32Quatloos(42.1f);
int_quatloos = float_quatloos;
- ensure("int units truncate float units on assignment", int_quatloos == 42);
+ ensure("int units truncate float units on assignment", int_quatloos == S32Quatloos(42));
LLUnit<U32, Quatloos> unsigned_int_quatloos(float_quatloos);
- ensure("unsigned int can be initialized from signed int", unsigned_int_quatloos == 42);
+ ensure("unsigned int can be initialized from signed int", unsigned_int_quatloos == S32Quatloos(42));
}
// conversions to/from base unit
@@ -84,15 +91,15 @@ namespace tut
{
LLUnit<F32, Quatloos> quatloos(1.f);
LLUnit<F32, Latinum> latinum_bars(quatloos);
- ensure("conversion between units is automatic via initialization", latinum_bars == 1.f / 4.f);
+ ensure("conversion between units is automatic via initialization", latinum_bars == F32Latinum(1.f / 4.f));
- latinum_bars = 256;
+ latinum_bars = S32Latinum(256);
quatloos = latinum_bars;
- ensure("conversion between units is automatic via assignment, and bidirectional", quatloos == 1024);
+ ensure("conversion between units is automatic via assignment, and bidirectional", quatloos == S32Quatloos(1024));
LLUnit<S32, Quatloos> single_quatloo(1);
LLUnit<F32, Latinum> quarter_latinum = single_quatloo;
- ensure("division of integer unit preserves fractional values when converted to float unit", quarter_latinum == 0.25f);
+ ensure("division of integer unit preserves fractional values when converted to float unit", quarter_latinum == F32Latinum(0.25f));
}
// conversions across non-base units
@@ -101,10 +108,10 @@ namespace tut
{
LLUnit<F32, Quatloos> quatloos(1024);
LLUnit<F32, Solari> solari(quatloos);
- ensure("conversions can work between indirectly related units: Quatloos -> Latinum -> Solari", solari == 4096);
+ ensure("conversions can work between indirectly related units: Quatloos -> Latinum -> Solari", solari == S32Solari(4096));
LLUnit<F32, Latinum> latinum_bars = solari;
- ensure("Non base units can be converted between each other", latinum_bars == 256);
+ ensure("Non base units can be converted between each other", latinum_bars == S32Latinum(256));
}
// math operations
@@ -114,36 +121,36 @@ namespace tut
// exercise math operations
LLUnit<F32, Quatloos> quatloos(1.f);
quatloos *= 4.f;
- ensure(quatloos == 4);
+ ensure(quatloos == S32Quatloos(4));
quatloos = quatloos * 2;
- ensure(quatloos == 8);
+ ensure(quatloos == S32Quatloos(8));
quatloos = 2.f * quatloos;
- ensure(quatloos == 16);
-
- quatloos += 4.f;
- ensure(quatloos == 20);
- quatloos += 4;
- ensure(quatloos == 24);
- quatloos = quatloos + 4;
- ensure(quatloos == 28);
- quatloos = 4 + quatloos;
- ensure(quatloos == 32);
+ ensure(quatloos == S32Quatloos(16));
+
+ quatloos += F32Quatloos(4.f);
+ ensure(quatloos == S32Quatloos(20));
+ quatloos += S32Quatloos(4);
+ ensure(quatloos == S32Quatloos(24));
+ quatloos = quatloos + S32Quatloos(4);
+ ensure(quatloos == S32Quatloos(28));
+ quatloos = S32Quatloos(4) + quatloos;
+ ensure(quatloos == S32Quatloos(32));
quatloos += quatloos * 3;
- ensure(quatloos == 128);
+ ensure(quatloos == S32Quatloos(128));
quatloos -= quatloos / 4 * 3;
- ensure(quatloos == 32);
- quatloos = quatloos - 8;
- ensure(quatloos == 24);
- quatloos -= 4;
- ensure(quatloos == 20);
- quatloos -= 4.f;
- ensure(quatloos == 16);
+ ensure(quatloos == S32Quatloos(32));
+ quatloos = quatloos - S32Quatloos(8);
+ ensure(quatloos == S32Quatloos(24));
+ quatloos -= S32Quatloos(4);
+ ensure(quatloos == S32Quatloos(20));
+ quatloos -= F32Quatloos(4.f);
+ ensure(quatloos == S32Quatloos(16));
quatloos /= 2.f;
- ensure(quatloos == 8);
+ ensure(quatloos == S32Quatloos(8));
quatloos = quatloos / 4;
- ensure(quatloos == 2);
+ ensure(quatloos == S32Quatloos(2));
F32 ratio = quatloos / LLUnit<F32, Quatloos>(2.f);
ensure(ratio == 1);
@@ -151,23 +158,54 @@ namespace tut
ensure(ratio == 1);
quatloos += LLUnit<F32, Solari>(8.f);
- ensure(quatloos == 4);
+ ensure(quatloos == S32Quatloos(4));
quatloos -= LLUnit<F32, Latinum>(1.f);
- ensure(quatloos == 0);
+ ensure(quatloos == S32Quatloos(0));
}
- // implicit units
+ // comparison operators
template<> template<>
void units_object_t::test<5>()
{
+ LLUnit<S32, Quatloos> quatloos(1);
+ ensure("can perform less than comparison against same type", quatloos < S32Quatloos(2));
+ ensure("can perform less than comparison against different storage type", quatloos < F32Quatloos(2.f));
+ ensure("can perform less than comparison against different units", quatloos < S32Latinum(5));
+ ensure("can perform less than comparison against different storage type and units", quatloos < F32Latinum(5.f));
+
+ ensure("can perform greater than comparison against same type", quatloos > S32Quatloos(0));
+ ensure("can perform greater than comparison against different storage type", quatloos > F32Quatloos(0.f));
+ ensure("can perform greater than comparison against different units", quatloos > S32Latinum(0));
+ ensure("can perform greater than comparison against different storage type and units", quatloos > F32Latinum(0.f));
+
+ }
+
+ bool accept_explicit_quatloos(S32Quatloos q)
+ {
+ return true;
+ }
+
+ // signature compatibility
+ template<> template<>
+ void units_object_t::test<6>()
+ {
+ S32Quatloos quatloos(1);
+ ensure("can pass unit values as argument", accept_explicit_quatloos(S32Quatloos(1)));
+ ensure("can pass unit values as argument", accept_explicit_quatloos(quatloos));
+ }
+
+ // implicit units
+ template<> template<>
+ void units_object_t::test<7>()
+ {
LLUnit<F32, Quatloos> quatloos;
- LLUnitImplicit<F32, Quatloos> quatloos_implicit = quatloos + 1;
+ LLUnitImplicit<F32, Quatloos> quatloos_implicit = quatloos + S32Quatloos(1);
ensure("can initialize implicit unit from explicit", quatloos_implicit == 1);
quatloos = quatloos_implicit;
- ensure("can assign implicit unit to explicit unit", quatloos == 1);
+ ensure("can assign implicit unit to explicit unit", quatloos == S32Quatloos(1));
quatloos += quatloos_implicit;
- ensure("can perform math operation using mixture of implicit and explicit units", quatloos == 2);
+ ensure("can perform math operation using mixture of implicit and explicit units", quatloos == S32Quatloos(2));
// math operations on implicits
quatloos_implicit = 1;