summaryrefslogtreecommitdiff
path: root/indra/llcommon/llunit.h
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-08-18 22:30:27 -0700
committerRichard Linden <none@none>2013-08-18 22:30:27 -0700
commit612892b45a3413b16e40c49d3bfde77a4ca927fd (patch)
tree2272a24c7f0a8354791f74c7485a376abb377f67 /indra/llcommon/llunit.h
parentf8e3a34348ab98ecd56d53360b8f2b6512ad6bba (diff)
SH-4433 WIP: Interesting: Statistics > Ping Sim is always 0 ms
continued conversion to units system made units perform type promotion correctly and preserve type in arithmetic e.g. can now do LLVector3 in units added typedefs for remaining common unit types, including implicits
Diffstat (limited to 'indra/llcommon/llunit.h')
-rw-r--r--indra/llcommon/llunit.h727
1 files changed, 493 insertions, 234 deletions
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