summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-11-08 23:42:18 -0800
committerRichard Linden <none@none>2012-11-08 23:42:18 -0800
commit0bb0bd514b235948c1a21c81ab0e8ab6223b1990 (patch)
treee0d49acc9074d0a5ed30c9c53fde908e5305b10f /indra/llcommon
parented17c181dd37f56b808838748d289ee7bb5567ec (diff)
SH-3499 WIP Ensure asset stats output is correct
Finished making LLUnit implicitly convertible to/from scalar integer values cleaned up test code
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/lldate.cpp4
-rw-r--r--indra/llcommon/lldate.h4
-rw-r--r--indra/llcommon/lldefs.h3
-rw-r--r--indra/llcommon/llerrorlegacy.h7
-rw-r--r--indra/llcommon/lltimer.cpp15
-rw-r--r--indra/llcommon/lltimer.h16
-rw-r--r--indra/llcommon/lltrace.h54
-rw-r--r--indra/llcommon/lltracerecording.h2
-rw-r--r--indra/llcommon/llunit.h404
9 files changed, 239 insertions, 270 deletions
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index d8b3dfe6c6..5569b4102d 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -54,8 +54,8 @@ LLDate::LLDate(const LLDate& date) :
mSecondsSinceEpoch(date.mSecondsSinceEpoch)
{}
-LLDate::LLDate(LLUnit::Seconds<F64> seconds_since_epoch) :
- mSecondsSinceEpoch(seconds_since_epoch)
+LLDate::LLDate(LLUnit<LLUnits::Seconds, F64> seconds_since_epoch) :
+ mSecondsSinceEpoch(seconds_since_epoch.value())
{}
LLDate::LLDate(const std::string& iso8601_date)
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 0500b1dcd8..b62a846147 100644
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -57,9 +57,9 @@ public:
/**
* @brief Construct a date from a seconds since epoch value.
*
- * @pararm seconds_since_epoch The number of seconds since UTC epoch.
+ * @param seconds_since_epoch The number of seconds since UTC epoch.
*/
- LLDate(LLUnit::Seconds<F64> seconds_since_epoch);
+ LLDate(LLUnit<LLUnits::Seconds, F64> seconds_since_epoch);
/**
* @brief Construct a date from a string representation
diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h
index 5a4b8325f4..d57b9dccff 100644
--- a/indra/llcommon/lldefs.h
+++ b/indra/llcommon/lldefs.h
@@ -244,5 +244,8 @@ inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs)
rhs = tmp;
}
+#define LL_GLUE_IMPL(x, y) x##y
+#define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y)
+
#endif // LL_LLDEFS_H
diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h
index 37cee579cd..58cc2899af 100644
--- a/indra/llcommon/llerrorlegacy.h
+++ b/indra/llcommon/llerrorlegacy.h
@@ -29,6 +29,7 @@
#define LL_LLERRORLEGACY_H
#include "llpreprocessor.h"
+#include <boost/static_assert.hpp>
/*
LEGACY -- DO NOT USE THIS STUFF ANYMORE
@@ -111,6 +112,12 @@ const int LL_ERR_PRICE_MISMATCH = -23018;
#define llverify(func) do {if (func) {}} while(0)
#endif
+#ifdef LL_WINDOWS
+#define llstatic_assert(func, msg) static_assert(func, msg)
+#else
+#define llstatic_assert(func, msg) BOOST_STATIC_ASSERT(func)
+#endif
+
// handy compile-time assert - enforce those template parameters!
#define cassert(expn) typedef char __C_ASSERT__[(expn)?1:-1] /* Flawfinder: ignore */
//XXX: used in two places in llcommon/llskipmap.h
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 05f6b789e4..23cebf4336 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -287,15 +287,14 @@ LLTimer::~LLTimer()
}
// static
-LLUnit::Microseconds<U64> LLTimer::getTotalTime()
+LLUnit<LLUnits::Microseconds, U64> LLTimer::getTotalTime()
{
- LLUnit::Seconds<F64> sec = LLUnit::Milliseconds<U32>(2000) + LLUnit::Hours<F32>(1.f / 360.f);
// simply call into the implementation function.
return totalTime();
}
// static
-LLUnit::Seconds<F64> LLTimer::getTotalSeconds()
+LLUnit<LLUnits::Seconds, F64> LLTimer::getTotalSeconds()
{
return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;
}
@@ -344,23 +343,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)
}
-LLUnit::Seconds<F64> LLTimer::getElapsedTimeF64() const
+LLUnit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeF64() const
{
U64 last = mLastClockCount;
return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;
}
-LLUnit::Seconds<F32> LLTimer::getElapsedTimeF32() const
+LLUnit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeF32() const
{
return (F32)getElapsedTimeF64();
}
-LLUnit::Seconds<F64> LLTimer::getElapsedTimeAndResetF64()
+LLUnit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeAndResetF64()
{
return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;
}
-LLUnit::Seconds<F32> LLTimer::getElapsedTimeAndResetF32()
+LLUnit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeAndResetF32()
{
return (F32)getElapsedTimeAndResetF64();
}
@@ -373,7 +372,7 @@ void LLTimer::setTimerExpirySec(F32 expiration)
+ (U64)((F32)(expiration * gClockFrequency));
}
-LLUnit::Seconds<F32> LLTimer::getRemainingTimeF32() const
+LLUnit<LLUnits::Seconds, F32> LLTimer::getRemainingTimeF32() const
{
U64 cur_ticks = get_clock_count();
if (cur_ticks > mExpirationTicks)
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index e0a880a346..5cb2b18111 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -67,16 +67,16 @@ public:
// Return a high precision number of seconds since the start of
// this application instance.
- static LLUnit::Seconds<F64> getElapsedSeconds()
+ static LLUnit<LLUnits::Seconds, F64> getElapsedSeconds()
{
return sTimer->getElapsedTimeF64();
}
// Return a high precision usec since epoch
- static LLUnit::Microseconds<U64> getTotalTime();
+ static LLUnit<LLUnits::Microseconds, U64> getTotalTime();
// Return a high precision seconds since epoch
- static LLUnit::Seconds<F64> getTotalSeconds();
+ static LLUnit<LLUnits::Seconds, F64> getTotalSeconds();
// MANIPULATORS
@@ -87,16 +87,16 @@ public:
void setTimerExpirySec(F32 expiration);
BOOL checkExpirationAndReset(F32 expiration);
BOOL hasExpired() const;
- LLUnit::Seconds<F32> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
- LLUnit::Seconds<F64> getElapsedTimeAndResetF64();
+ LLUnit<LLUnits::Seconds, F32> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
+ LLUnit<LLUnits::Seconds, F64> getElapsedTimeAndResetF64();
- LLUnit::Seconds<F32> getRemainingTimeF32() const;
+ LLUnit<LLUnits::Seconds, F32> getRemainingTimeF32() const;
static BOOL knownBadTimer();
// ACCESSORS
- LLUnit::Seconds<F32> getElapsedTimeF32() const; // Returns elapsed time in seconds
- LLUnit::Seconds<F64> getElapsedTimeF64() const; // Returns elapsed time in seconds
+ LLUnit<LLUnits::Seconds, F32> getElapsedTimeF32() const; // Returns elapsed time in seconds
+ LLUnit<LLUnits::Seconds, F64> getElapsedTimeF64() const; // Returns elapsed time in seconds
bool getStarted() const { return mStarted; }
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index e2530a8a24..d289ea9a88 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -38,37 +38,35 @@
#include <list>
-#define LL_TOKEN_PASTE_ACTUAL(x, y) x##y
-#define LL_TOKEN_PASTE(x, y) LL_TOKEN_PASTE_ACTUAL(x, y)
-#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer);
+#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_GLUE_TOKENS(block_time_recorder, __COUNTER__)(block_timer);
namespace LLTrace
{
class Recording;
- typedef LLUnit::Bytes<F64> Bytes;
- typedef LLUnit::Kilobytes<F64> Kilobytes;
- typedef LLUnit::Megabytes<F64> Megabytes;
- typedef LLUnit::Gigabytes<F64> Gigabytes;
- typedef LLUnit::Bits<F64> Bits;
- typedef LLUnit::Kilobits<F64> Kilobits;
- typedef LLUnit::Megabits<F64> Megabits;
- typedef LLUnit::Gigabits<F64> Gigabits;
-
- typedef LLUnit::Seconds<F64> Seconds;
- typedef LLUnit::Milliseconds<F64> Milliseconds;
- typedef LLUnit::Minutes<F64> Minutes;
- typedef LLUnit::Hours<F64> Hours;
- typedef LLUnit::Days<F64> Days;
- typedef LLUnit::Weeks<F64> Weeks;
- typedef LLUnit::Milliseconds<F64> Milliseconds;
- typedef LLUnit::Microseconds<F64> Microseconds;
- typedef LLUnit::Nanoseconds<F64> Nanoseconds;
-
- typedef LLUnit::Meters<F64> Meters;
- typedef LLUnit::Kilometers<F64> Kilometers;
- typedef LLUnit::Centimeters<F64> Centimeters;
- typedef LLUnit::Millimeters<F64> Millimeters;
+ typedef LLUnit<LLUnits::Bytes, F64> Bytes;
+ typedef LLUnit<LLUnits::Kilobytes, F64> Kilobytes;
+ typedef LLUnit<LLUnits::Megabytes, F64> Megabytes;
+ typedef LLUnit<LLUnits::Gigabytes, F64> Gigabytes;
+ typedef LLUnit<LLUnits::Bits, F64> Bits;
+ typedef LLUnit<LLUnits::Kilobits, F64> Kilobits;
+ typedef LLUnit<LLUnits::Megabits, F64> Megabits;
+ typedef LLUnit<LLUnits::Gigabits, F64> Gigabits;
+
+ 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::Days, F64> Days;
+ typedef LLUnit<LLUnits::Weeks, F64> Weeks;
+ 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;
void init();
void cleanup();
@@ -438,7 +436,7 @@ namespace LLTrace
void sample(UNIT_T value)
{
T converted_value;
- converted_value.assignFrom(value);
+ converted_value = value;
getPrimaryAccumulator().sample((storage_t)converted_value.value());
}
};
@@ -478,7 +476,7 @@ namespace LLTrace
void add(UNIT_T value)
{
T converted_value;
- converted_value.assignFrom(value);
+ converted_value = value;
getPrimaryAccumulator().add((storage_t)converted_value.value());
}
};
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index fc96631ce0..ca9950b78d 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -197,7 +197,7 @@ namespace LLTrace
U32 getSampleCount(const TraceType<MeasurementAccumulator<F64> >& stat) const;
U32 getSampleCount(const TraceType<MeasurementAccumulator<S64> >& stat) const;
- LLUnit::Seconds<F64> getDuration() const { return mElapsedSeconds; }
+ LLUnit<LLUnits::Seconds, F64> getDuration() const { return mElapsedSeconds; }
private:
friend class ThreadRecorder;
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index 4519905707..0dcafbe26e 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -30,326 +30,288 @@
#include "stdtypes.h"
#include "llpreprocessor.h"
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT = BASE_UNIT>
-struct LLUnitType : public BASE_UNIT
+namespace LLUnits
{
- typedef DERIVED_UNIT unit_t;
-
- typedef typename STORAGE_TYPE storage_t;
- typedef void is_unit_tag_t;
-
- LLUnitType()
- {}
-
- LLUnitType(storage_t value)
- : BASE_UNIT(convertToBase(value))
- {}
-
- // implicit downcast
- operator unit_t& ()
- {
- return static_cast<unit_t&>(*this);
- }
-
- operator storage_t () const
- {
- return value();
- }
-
- storage_t value() const
- {
- return convertToDerived(mBaseValue);
- }
-
- template<typename CONVERTED_TYPE>
- storage_t as() const
- {
- return CONVERTED_TYPE(*this).value();
- }
-
-protected:
- static storage_t convertToBase(storage_t derived_value)
- {
- return (storage_t)((F32)derived_value * unit_t::conversionToBaseFactor());
- }
-
- static storage_t convertToDerived(storage_t base_value)
+template<typename DERIVED_UNITS_TAG, typename BASE_UNITS_TAG>
+struct ConversionFactor
+{
+ static F64 get()
{
- return (storage_t)((F32)base_value / unit_t::conversionToBaseFactor());
+ llstatic_assert(sizeof(DERIVED_UNITS_TAG) == 0, "Cannot convert between types.");
}
+};
+template<typename BASE_UNITS_TAG>
+struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG>
+{
+ static F64 get() { return 1.0; }
};
+}
-template<typename STORAGE_TYPE, typename T>
-struct LLUnitType<STORAGE_TYPE, T, T>
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+struct LLUnit
{
- typedef T unit_t;
- typedef STORAGE_TYPE storage_t;
+ typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> self_t;
+ typedef typename STORAGE_TYPE storage_t;
typedef void is_unit_tag_t;
- LLUnitType()
- : mBaseValue()
+ LLUnit(storage_t value = storage_t())
+ : mValue(value)
{}
- LLUnitType(storage_t value)
- : mBaseValue(value)
+ template<typename OTHER_UNIT, typename OTHER_STORAGE>
+ LLUnit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
+ : mValue(convert(other))
{}
- unit_t& operator=(storage_t value)
+ LLUnit(self_t& other)
+ : mValue(other.mValue)
+ {}
+
+ self_t& operator = (storage_t value)
{
- setBaseValue(value);
+ mValue = value;
return *this;
}
- //implicit downcast
- operator unit_t& ()
+ template<typename OTHER_UNIT, typename OTHER_STORAGE>
+ self_t& operator = (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
{
- return static_cast<unit_t&>(*this);
+ mValue = convert(other);
+ return *this;
}
- operator storage_t () const
+ operator storage_t() const
{
return value();
}
- storage_t value() const { return mBaseValue; }
-
- template<typename CONVERTED_TYPE>
- storage_t as() const
+ storage_t value() const
{
- return CONVERTED_TYPE(*this).value();
+ return mValue;
}
- static storage_t convertToBase(storage_t derived_value)
+ void operator += (storage_t value)
{
- return (storage_t)derived_value;
+ mValue += value;
}
- static storage_t convertToDerived(storage_t base_value)
+ template<typename OTHER_UNIT, typename OTHER_STORAGE>
+ void operator += (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
{
- return (storage_t)base_value;
+ mValue += convert(other);
}
- void operator += (const unit_t other)
+ void operator -= (storage_t value)
{
- mBaseValue += other.mBaseValue;
+ mValue -= value;
}
- void operator -= (const unit_t other)
+ template<typename OTHER_UNIT, typename OTHER_STORAGE>
+ void operator -= (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
{
- mBaseValue -= other.mBaseValue;
+ mValue -= convert(other);
}
void operator *= (storage_t multiplicand)
{
- mBaseValue *= multiplicand;
+ mValue *= multiplicand;
+ }
+
+ template<typename OTHER_UNIT, typename OTHER_STORAGE>
+ void operator *= (LLUnit<OTHER_UNIT, OTHER_STORAGE> multiplicand)
+ {
+ llstatic_assert(sizeof(OTHER_UNIT) == false, "Multiplication of unit types not supported.");
}
void operator /= (storage_t divisor)
{
- mBaseValue /= divisor;
+ mValue /= divisor;
}
-protected:
- void setBaseValue(storage_t value)
+ template<typename OTHER_UNIT, typename OTHER_STORAGE>
+ void operator /= (LLUnit<OTHER_UNIT, OTHER_STORAGE> divisor)
{
- mBaseValue = value;
+ llstatic_assert(sizeof(OTHER_UNIT) == false, "Division of unit types not supported.");
}
- storage_t mBaseValue;
-};
+ template<typename SOURCE_UNITS, typename SOURCE_VALUE>
+ static storage_t convert(LLUnit<SOURCE_UNITS, SOURCE_VALUE> v)
+ {
+ return (storage_t)(v.value()
+ * LLUnits::ConversionFactor<SOURCE_UNITS, typename UNIT_TYPE::base_unit_t>::get()
+ * LLUnits::ConversionFactor<typename UNIT_TYPE::base_unit_t, UNIT_TYPE>::get());
+ }
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-struct LLUnitTypeWrapper
-: public LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>
-{
- typedef LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> unit_t;
- LLUnitTypeWrapper(const unit_t& other)
- : unit_t(other)
- {}
-};
+protected:
+ storage_t mValue;
+};
//
// operator +
//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT, typename STORAGE_TYPE2, typename BASE_UNIT2, typename DERIVED_UNIT2>
-DERIVED_UNIT operator + (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE2, BASE_UNIT2, DERIVED_UNIT2> 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)
{
- return DERIVED_UNIT(first + LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>(second).value());
+ LLUnit<STORAGE_TYPE1, 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)
+{
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result += second;
+ return result;
+}
-//
-// operator -
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT, typename STORAGE_TYPE2, typename BASE_UNIT2, typename DERIVED_UNIT2>
-DERIVED_UNIT operator - (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> 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 DERIVED_UNIT(first - LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>(second).value());
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result += second;
+ return result;
}
//
-// operator *
+// operator -
//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-DERIVED_UNIT operator * (STORAGE_TYPE first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> 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)
{
- return DERIVED_UNIT(first * second.value());
+ LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ result -= second;
+ return result;
}
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-DERIVED_UNIT operator * (LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> first, STORAGE_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 DERIVED_UNIT(first.value() * second);
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result -= second;
+ return result;
}
+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<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result -= second;
+ return result;
+}
//
-// operator /
+// operator *
//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-DERIVED_UNIT operator / (STORAGE_TYPE first, LLUnitTypeWrapper<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> 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 DERIVED_UNIT(first / second.value());
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>(first * second.value());
}
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-DERIVED_UNIT operator / (LLUnitTypeWrapper<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> first, STORAGE_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 DERIVED_UNIT(first.value() / second);
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>(first.value() * second);
}
-//
-// operator <
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT, typename STORAGE_TYPE2, typename BASE_UNIT2, typename DERIVED_UNIT2>
-
-bool operator < (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+void operator * (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)
{
- return first < second.value();
+ llstatic_assert(sizeof(STORAGE_TYPE1) == false, "Multiplication of unit types results in new unit type - not supported.");
}
//
-// operator <=
+// operator /
//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator <= (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
{
- return first <= second.value();
+ return SCALAR_TYPE(first / second.value());
}
-
-//
-// operator >
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator > (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> 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 first > second.value();
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>(first.value() / second);
}
-//
-// operator >=
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator >= (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+void operator / (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)
{
- return first >= second.value();
+ llstatic_assert(sizeof(STORAGE_TYPE1) == false, "Multiplication of unit types results in new unit type - not supported.");
}
-//
-// operator ==
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator == (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
-{
- return first == second.value();
+#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 (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second); \
}
-//
-// operator !=
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator != (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+COMPARISON_OPERATORS(<)
+COMPARISON_OPERATORS(<=)
+COMPARISON_OPERATORS(>)
+COMPARISON_OPERATORS(>=)
+COMPARISON_OPERATORS(==)
+COMPARISON_OPERATORS(!=)
+
+namespace LLUnits
{
- return first != second.value();
+#define LL_DECLARE_DERIVED_UNIT(base_unit_name, unit_name, conversion_factor)\
+struct unit_name \
+{ \
+ typedef base_unit_name base_unit_t; \
+}; \
+template<> \
+struct ConversionFactor<unit_name, base_unit_name> \
+{ \
+ static F64 get() { return (conversion_factor); } \
+}; \
+ \
+template<> \
+struct ConversionFactor<base_unit_name, unit_name> \
+{ \
+ static F64 get() { return 1.0 / (conversion_factor); } \
}
-#define LL_DECLARE_BASE_UNIT(unit_name) \
- template<typename STORAGE> \
- struct unit_name : public LLUnitType<STORAGE, unit_name<STORAGE>, unit_name<STORAGE> > \
- { \
- typedef LLUnitType<STORAGE, unit_name> unit_t; \
- \
- unit_name(storage_t value = 0) \
- : LLUnitType(value) \
- {} \
- \
- template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE> \
- unit_name(LLUnitType<SOURCE_STORAGE_TYPE, unit_name<SOURCE_STORAGE_TYPE>, SOURCE_TYPE> source) \
- { \
- assignFrom(source); \
- } \
- \
- template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE> \
- void assignFrom(LLUnitType<SOURCE_STORAGE_TYPE, unit_name<SOURCE_STORAGE_TYPE>, SOURCE_TYPE> source) \
- { \
- setBaseValue((storage_t)source.unit_name<SOURCE_STORAGE_TYPE>::unit_t::value()); \
- } \
- \
- }; \
-
-#define LL_DECLARE_DERIVED_UNIT(base_unit, derived_unit, conversion_factor) \
- template<typename STORAGE> \
- struct derived_unit : public LLUnitType<STORAGE, base_unit<STORAGE>, derived_unit<STORAGE> > \
- { \
- typedef LLUnitType<STORAGE, base_unit<STORAGE>, derived_unit<STORAGE> > unit_t; \
- \
- derived_unit(storage_t value = 0) \
- : LLUnitType(value) \
- {} \
- \
- template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE> \
- derived_unit(LLUnitType<SOURCE_STORAGE_TYPE, base_unit<SOURCE_STORAGE_TYPE>, SOURCE_TYPE> source) \
- { \
- assignFrom(source); \
- } \
- \
- template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE> \
- void assignFrom(LLUnitType<SOURCE_STORAGE_TYPE, base_unit<SOURCE_STORAGE_TYPE>, SOURCE_TYPE> source) \
- { \
- setBaseValue((storage_t)source.base_unit<SOURCE_STORAGE_TYPE>::unit_t::value()); \
- } \
- \
- static F32 conversionToBaseFactor() { return (F32)(conversion_factor); } \
- \
- }; \
-
-namespace LLUnit
-{
- LL_DECLARE_BASE_UNIT(Bytes);
- LL_DECLARE_DERIVED_UNIT(Bytes, Kilobytes, 1024);
- LL_DECLARE_DERIVED_UNIT(Bytes, Megabytes, 1024 * 1024);
- LL_DECLARE_DERIVED_UNIT(Bytes, Gigabytes, 1024 * 1024 * 1024);
- LL_DECLARE_DERIVED_UNIT(Bytes, Bits, (1.f / 8.f));
- LL_DECLARE_DERIVED_UNIT(Bytes, Kilobits, (1024 / 8));
- LL_DECLARE_DERIVED_UNIT(Bytes, Megabits, (1024 / 8));
- LL_DECLARE_DERIVED_UNIT(Bytes, Gigabits, (1024 * 1024 * 1024 / 8));
-
- LL_DECLARE_BASE_UNIT(Seconds);
- LL_DECLARE_DERIVED_UNIT(Seconds, Minutes, 60);
- LL_DECLARE_DERIVED_UNIT(Seconds, Hours, 60 * 60);
- LL_DECLARE_DERIVED_UNIT(Seconds, Days, 60 * 60 * 24);
- LL_DECLARE_DERIVED_UNIT(Seconds, Weeks, 60 * 60 * 24 * 7);
- LL_DECLARE_DERIVED_UNIT(Seconds, Milliseconds, (1.f / 1000.f));
- LL_DECLARE_DERIVED_UNIT(Seconds, Microseconds, (1.f / (1000000.f)));
- LL_DECLARE_DERIVED_UNIT(Seconds, Nanoseconds, (1.f / (1000000000.f)));
-
- LL_DECLARE_BASE_UNIT(Meters);
- LL_DECLARE_DERIVED_UNIT(Meters, Kilometers, 1000);
- LL_DECLARE_DERIVED_UNIT(Meters, Centimeters, 1 / 100);
- LL_DECLARE_DERIVED_UNIT(Meters, Millimeters, 1 / 1000);
+struct Bytes { typedef Bytes base_unit_t; };
+LL_DECLARE_DERIVED_UNIT(Bytes, Kilobytes, 1024);
+LL_DECLARE_DERIVED_UNIT(Bytes, Megabytes, 1024 * 1024);
+LL_DECLARE_DERIVED_UNIT(Bytes, Gigabytes, 1024 * 1024 * 1024);
+LL_DECLARE_DERIVED_UNIT(Bytes, Bits, (1.0 / 8.0));
+LL_DECLARE_DERIVED_UNIT(Bytes, Kilobits, (1024 / 8));
+LL_DECLARE_DERIVED_UNIT(Bytes, Megabits, (1024 / 8));
+LL_DECLARE_DERIVED_UNIT(Bytes, Gigabits, (1024 * 1024 * 1024 / 8));
+
+struct Seconds { typedef Seconds base_unit_t; };
+LL_DECLARE_DERIVED_UNIT(Seconds, Minutes, 60);
+LL_DECLARE_DERIVED_UNIT(Seconds, Hours, 60 * 60);
+LL_DECLARE_DERIVED_UNIT(Seconds, Days, 60 * 60 * 24);
+LL_DECLARE_DERIVED_UNIT(Seconds, Weeks, 60 * 60 * 24 * 7);
+LL_DECLARE_DERIVED_UNIT(Seconds, Milliseconds, (1.0 / 1000.0));
+LL_DECLARE_DERIVED_UNIT(Seconds, Microseconds, (1.0 / (1000000.0)));
+LL_DECLARE_DERIVED_UNIT(Seconds, Nanoseconds, (1.0 / (1000000000.0)));
+
+struct Meters { typedef Meters base_unit_t; };
+LL_DECLARE_DERIVED_UNIT(Meters, Kilometers, 1000);
+LL_DECLARE_DERIVED_UNIT(Meters, Centimeters, (1.0 / 100));
+LL_DECLARE_DERIVED_UNIT(Meters, Millimeters, (1.0 / 1000));
}
#endif // LL_LLUNIT_H