summaryrefslogtreecommitdiff
path: root/indra/llcommon/llunit.h
diff options
context:
space:
mode:
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