/** * @file llunit.h * @brief Unit conversion classes * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2012, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #ifndef LL_LLUNIT_H #define LL_LLUNIT_H #include "stdtypes.h" #include "llpreprocessor.h" #include "llerror.h" //lightweight replacement of type traits for simple type equality check template struct LLIsSameType { static const bool value = false; }; template struct LLIsSameType { static const bool value = true; }; template struct LLPromotedType { typedef LLTYPEOF(S() + T()) type_t; }; template struct LLUnit { typedef LLUnit self_t; typedef STORAGE_TYPE storage_t; // value initialization explicit LLUnit(storage_t value = storage_t()) : mValue(value) {} // unit initialization and conversion template LLUnit(LLUnit other) : mValue(convert(other).mValue) {} // unit assignment template self_t& operator = (LLUnit other) { mValue = convert(other).mValue; return *this; } storage_t value() const { return mValue; } void value(storage_t value) { mValue = value; } template storage_t valueInUnits() { return LLUnit(*this).value(); } template void valueInUnits(storage_t value) { *this = LLUnit(value); } template void operator += (LLUnit other) { mValue += convert(other).mValue; } template void operator -= (LLUnit other) { mValue -= convert(other).mValue; } void operator *= (storage_t multiplicand) { mValue *= multiplicand; } template void operator *= (LLUnit multiplicand) { // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template LL_BAD_TEMPLATE_INSTANTIATION(OTHER_UNIT, "Multiplication of unit types not supported."); } void operator /= (storage_t divisor) { mValue /= divisor; } template void operator /= (LLUnit divisor) { // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template LL_BAD_TEMPLATE_INSTANTIATION(OTHER_UNIT, "Illegal in-place division of unit types."); } template static self_t convert(LLUnit v) { self_t result; ll_convert_units(v, result); return result; } protected: storage_t mValue; }; template std::ostream& operator <<(std::ostream& s, const LLUnit& unit) { s << unit.value() << UNIT_TYPE::getUnitLabel(); return s; } template std::istream& operator >>(std::istream& s, LLUnit& unit) { STORAGE_TYPE val; s >> val; unit.value(val); return s; } template struct LLUnitImplicit : public LLUnit { typedef LLUnitImplicit self_t; typedef typename LLUnit::storage_t storage_t; typedef LLUnit base_t; LLUnitImplicit(storage_t value = storage_t()) : base_t(value) {} template LLUnitImplicit(LLUnit other) : base_t(convert(other)) {} // 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 void operator += (LLUnitImplicit other) { mValue += convert(other).value(); } using base_t::operator -=; void operator -= (storage_t value) { mValue -= value; } template void operator -= (LLUnitImplicit other) { mValue -= convert(other).value(); } }; template std::ostream& operator <<(std::ostream& s, const LLUnitImplicit& unit) { s << unit.value() << UNIT_TYPE::getUnitLabel(); return s; } template std::istream& operator >>(std::istream& s, LLUnitImplicit& unit) { STORAGE_TYPE val; s >> val; unit = val; return s; } template LL_FORCE_INLINE void ll_convert_units(LLUnit in, LLUnit& out, ...) { LL_STATIC_ASSERT((LLIsSameType::value || !LLIsSameType::value || !LLIsSameType::value), "invalid conversion: incompatible units"); if (LLIsSameType::value) { if (LLIsSameType::value) { // T1 and T2 fully reduced and equal...just copy out = LLUnit((S2)in.value()); } else { // reduce T2 LLUnit new_out; ll_convert_units(in, new_out); ll_convert_units(new_out, out); } } else { // reduce T1 LLUnit new_in; ll_convert_units(in, new_in); ll_convert_units(new_in, out); } } // // operator + // template LLUnit operator + (LLUnit first, LLUnit second) { LLUnit result(first); result += second; return result; } template LLUnit operator + (LLUnit first, UNITLESS second) { LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "operator + requires compatible unit types"); return LLUnit(0); } template LLUnit operator + (UNITLESS first, LLUnit second) { LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "operator + requires compatible unit types"); return LLUnit(0); } template LLUnitImplicit operator + (LLUnitImplicit first, LLUnitImplicit second) { LLUnitImplicit result(first); result += second; return result; } template LLUnitImplicit operator + (LLUnit first, LLUnitImplicit second) { LLUnitImplicit result(first); result += second; return result; } template LLUnitImplicit operator + (LLUnitImplicit first, LLUnit second) { LLUnitImplicit result(first); result += LLUnitImplicit(second); return result; } template LLUnitImplicit operator + (LLUnitImplicit first, UNITLESS_TYPE second) { LLUnitImplicit result(first); result += second; return result; } template LLUnitImplicit operator + (UNITLESS_TYPE first, LLUnitImplicit second) { LLUnitImplicit result(first); result += second; return result; } // // operator - // template LLUnit operator - (LLUnit first, LLUnit second) { LLUnit result(first); result -= second; return result; } template LLUnit operator - (LLUnit first, UNITLESS second) { LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "operator - requires compatible unit types"); return LLUnit(0); } template LLUnit operator - (UNITLESS first, LLUnit second) { LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "operator - requires compatible unit types"); return LLUnit(0); } template LLUnitImplicit operator - (LLUnitImplicit first, LLUnitImplicit second) { LLUnitImplicit result(first); result -= second; return result; } template LLUnitImplicit operator - (LLUnit first, LLUnitImplicit second) { LLUnitImplicit result(first); result -= second; return result; } template LLUnitImplicit operator - (LLUnitImplicit first, LLUnit second) { LLUnitImplicit result(first); result -= LLUnitImplicit(second); return result; } template LLUnitImplicit operator - (LLUnitImplicit first, UNITLESS_TYPE second) { LLUnitImplicit result(first); result -= second; return result; } template LLUnitImplicit operator - (UNITLESS_TYPE first, LLUnitImplicit second) { LLUnitImplicit result(first); result -= second; return result; } // // operator * // template LLUnit operator * (LLUnit, LLUnit) { // 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."); return LLUnit(); } template LLUnit operator * (LLUnit first, UNITLESS_TYPE second) { return LLUnit(first.value() * second); } template LLUnit operator * (UNITLESS_TYPE first, LLUnit second) { return LLUnit(first * second.value()); } template LLUnitImplicit operator * (LLUnitImplicit, LLUnitImplicit) { // 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."); return LLUnitImplicit(); } template LLUnitImplicit operator * (LLUnitImplicit first, UNITLESS_TYPE second) { return LLUnitImplicit(first.value() * second); } template LLUnitImplicit operator * (UNITLESS_TYPE first, LLUnitImplicit second) { return LLUnitImplicit(first * second.value()); } // // operator / // template LLUnit operator / (LLUnit first, UNITLESS_TYPE second) { return LLUnit(first.value() / second); } template LLTYPEOF(STORAGE_TYPE1() / STORAGE_TYPE2()) operator / (LLUnit first, LLUnit second) { return first.value() / first.convert(second).value(); } template LLUnitImplicit operator / (LLUnitImplicit first, UNITLESS_TYPE second) { return LLUnitImplicit(first.value() / second); } template LLTYPEOF(STORAGE_TYPE1() / STORAGE_TYPE2()) operator / (LLUnitImplicit first, LLUnitImplicit second) { return (LLTYPEOF(STORAGE_TYPE1() / STORAGE_TYPE2()))(first.value() / first.convert(second).value()); } template LLTYPEOF(STORAGE_TYPE1() / STORAGE_TYPE2()) operator / (LLUnit first, LLUnitImplicit second) { return (LLTYPEOF(STORAGE_TYPE1() / STORAGE_TYPE2()))(first.value() / first.convert(second).value()); } template LLTYPEOF(STORAGE_TYPE1() / STORAGE_TYPE2()) operator / (LLUnitImplicit first, LLUnit second) { return (LLTYPEOF(STORAGE_TYPE1() / STORAGE_TYPE2()))(first.value() / first.convert(second).value()); } // // comparison operators // #define LL_UNIT_DECLARE_COMPARISON_OPERATOR(op) \ template \ bool operator op (LLUnitImplicit first, LLUnitImplicit second) \ { \ return first.value() op first.convert(second).value(); \ } \ \ template \ bool operator op (LLUnitImplicit first, UNITLESS_TYPE second) \ { \ return first.value() op second; \ } \ \ template \ bool operator op (UNITLESS_TYPE first, LLUnitImplicit second) \ { \ return first op second.value(); \ } \ \ template \ bool operator op (LLUnit first, LLUnit second) \ { \ return first.value() op first.convert(second).value(); \ } \ \ template \ bool operator op (LLUnit first, UNITLESS_TYPE second) \ { \ LL_BAD_TEMPLATE_INSTANTIATION(UNITLESS_TYPE, "operator " #op " requires compatible unit types"); \ return false; \ } \ \ template \ bool operator op (UNITLESS_TYPE first, LLUnit second) \ { \ LL_BAD_TEMPLATE_INSTANTIATION(UNITLESS_TYPE, "operator " #op " requires compatible unit types"); \ return false; \ } \ \ template \ bool operator op (LLUnit first, LLUnitImplicit second) \ { \ return first.value() op first.convert(second).value(); \ } \ \ template \ bool operator op (LLUnitImplicit first, LLUnit 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 struct LLGetUnitLabel { static const char* getUnitLabel() { return ""; } }; template struct LLGetUnitLabel > { static const char* getUnitLabel() { return T::getUnitLabel(); } }; template struct LLUnitLinearOps { typedef LLUnitLinearOps output_t; LLUnitLinearOps(INPUT_TYPE val) : mInput (val) {} operator OUTPUT_TYPE() const { return (OUTPUT_TYPE)mInput; } INPUT_TYPE mInput; template output_t operator * (T other) { return typename LLPromotedType::type_t(mInput) * other; } template output_t operator / (T other) { return typename LLPromotedType::type_t(mInput) / other; } template output_t operator + (T other) { return typename LLPromotedType::type_t(mInput) + other; } template output_t operator - (T other) { return typename LLPromotedType::type_t(mInput) - other; } }; template struct LLUnitInverseLinearOps { typedef LLUnitInverseLinearOps output_t; LLUnitInverseLinearOps(INPUT_TYPE val) : mInput(val) {} operator OUTPUT_TYPE() const { return (OUTPUT_TYPE)mInput; } INPUT_TYPE mInput; template output_t operator * (T other) { return typename LLPromotedType::type_t(mInput) / other; } template output_t operator / (T other) { return typename LLPromotedType::type_t(mInput) * other; } template output_t operator + (T other) { return typename LLPromotedType::type_t(mInput) - other; } template output_t operator - (T other) { return typename LLPromotedType::type_t(mInput) + other; } }; #define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \ struct base_unit_name \ { \ typedef base_unit_name base_unit_t; \ static const char* getUnitLabel() { return unit_label; } \ template \ static LLUnit fromValue(T value) { return LLUnit(value); } \ template \ static LLUnit fromValue(LLUnit value) \ { return LLUnit(value); } \ } #define LL_DECLARE_DERIVED_UNIT(base_unit_name, conversion_operation, unit_name, unit_label) \ struct unit_name \ { \ typedef base_unit_name base_unit_t; \ static const char* getUnitLabel() { return unit_label; } \ template \ static LLUnit fromValue(T value) { return LLUnit(value); } \ template \ static LLUnit fromValue(LLUnit value) \ { return LLUnit(value); } \ }; \ \ template \ void ll_convert_units(LLUnit in, LLUnit& out) \ { \ out = LLUnit((S2)(LLUnitLinearOps(in.value()) conversion_operation)); \ } \ \ template \ void ll_convert_units(LLUnit in, LLUnit& out) \ { \ out = LLUnit((S2)(LLUnitInverseLinearOps(in.value()) conversion_operation)); \ } // // Unit declarations // namespace LLUnits { LL_DECLARE_BASE_UNIT(Bytes, "B"); // 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 F32Bytes; typedef LLUnit F32Kilobytes; typedef LLUnit F32Megabytes; typedef LLUnit F32Gigabytes; typedef LLUnitImplicit F32BytesImplicit; typedef LLUnitImplicit F32KilobytesImplicit; typedef LLUnitImplicit F32MegabytesImplicit; typedef LLUnitImplicit F32GigabytesImplicit; typedef LLUnit F64Bytes; typedef LLUnit F64Kilobytes; typedef LLUnit F64Megabytes; typedef LLUnit F64Gigabytes; typedef LLUnitImplicit F64BytesImplicit; typedef LLUnitImplicit F64KilobytesImplicit; typedef LLUnitImplicit F64MegabytesImplicit; typedef LLUnitImplicit F64GigabytesImplicit; typedef LLUnit S32Bytes; typedef LLUnit S32Kilobytes; typedef LLUnit S32Megabytes; typedef LLUnit S32Gigabytes; typedef LLUnitImplicit S32BytesImplicit; typedef LLUnitImplicit S32KilobytesImplicit; typedef LLUnitImplicit S32MegabytesImplicit; typedef LLUnitImplicit S32GigabytesImplicit; typedef LLUnit S64Bytes; typedef LLUnit S64Kilobytes; typedef LLUnit S64Megabytes; typedef LLUnit S64Gigabytes; typedef LLUnitImplicit S64BytesImplicit; typedef LLUnitImplicit S64KilobytesImplicit; typedef LLUnitImplicit S64MegabytesImplicit; typedef LLUnitImplicit S64GigabytesImplicit; typedef LLUnit U32Bytes; typedef LLUnit U32Kilobytes; typedef LLUnit U32Megabytes; typedef LLUnit U32Gigabytes; typedef LLUnitImplicit U32BytesImplicit; typedef LLUnitImplicit U32KilobytesImplicit; typedef LLUnitImplicit U32MegabytesImplicit; typedef LLUnitImplicit U32GigabytesImplicit; typedef LLUnit U64Bytes; typedef LLUnit U64Kilobytes; typedef LLUnit U64Megabytes; typedef LLUnit U64Gigabytes; typedef LLUnitImplicit U64BytesImplicit; typedef LLUnitImplicit U64KilobytesImplicit; typedef LLUnitImplicit U64MegabytesImplicit; typedef LLUnitImplicit 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, * 1024, Kilobits, "Kb"); LL_DECLARE_DERIVED_UNIT(Kilobits, * 1024, Megabits, "Mb"); LL_DECLARE_DERIVED_UNIT(Megabits, * 1024, Gigabits, "Gb"); } typedef LLUnit F32Bits; typedef LLUnit F32Kilobits; typedef LLUnit F32Megabits; typedef LLUnit F32Gigabits; typedef LLUnitImplicit F32BitsImplicit; typedef LLUnitImplicit F32KilobitsImplicit; typedef LLUnitImplicit F32MegabitsImplicit; typedef LLUnitImplicit F32GigabitsImplicit; typedef LLUnit F64Bits; typedef LLUnit F64Kilobits; typedef LLUnit F64Megabits; typedef LLUnit F64Gigabits; typedef LLUnitImplicit F64BitsImplicit; typedef LLUnitImplicit F64KilobitsImplicit; typedef LLUnitImplicit F64MegabitsImplicit; typedef LLUnitImplicit F64GigabitsImplicit; typedef LLUnit S32Bits; typedef LLUnit S32Kilobits; typedef LLUnit S32Megabits; typedef LLUnit S32Gigabits; typedef LLUnitImplicit S32BitsImplicit; typedef LLUnitImplicit S32KilobitsImplicit; typedef LLUnitImplicit S32MegabitsImplicit; typedef LLUnitImplicit S32GigabitsImplicit; typedef LLUnit S64Bits; typedef LLUnit S64Kilobits; typedef LLUnit S64Megabits; typedef LLUnit S64Gigabits; typedef LLUnitImplicit S64BitsImplicit; typedef LLUnitImplicit S64KilobitsImplicit; typedef LLUnitImplicit S64MegabitsImplicit; typedef LLUnitImplicit S64GigabitsImplicit; typedef LLUnit U32Bits; typedef LLUnit U32Kilobits; typedef LLUnit U32Megabits; typedef LLUnit U32Gigabits; typedef LLUnitImplicit U32BitsImplicit; typedef LLUnitImplicit U32KilobitsImplicit; typedef LLUnitImplicit U32MegabitsImplicit; typedef LLUnitImplicit U32GigabitsImplicit; typedef LLUnit U64Bits; typedef LLUnit U64Kilobits; typedef LLUnit U64Megabits; typedef LLUnit U64Gigabits; typedef LLUnitImplicit U64BitsImplicit; typedef LLUnitImplicit U64KilobitsImplicit; typedef LLUnitImplicit U64MegabitsImplicit; typedef LLUnitImplicit U64GigabitsImplicit; namespace LLUnits { LL_DECLARE_BASE_UNIT(Seconds, "s"); LL_DECLARE_DERIVED_UNIT(Seconds, * 60, Minutes, "min"); LL_DECLARE_DERIVED_UNIT(Minutes, * 60, Hours, "h"); LL_DECLARE_DERIVED_UNIT(Hours, * 24, Days, "d"); LL_DECLARE_DERIVED_UNIT(Seconds, / 1000, Milliseconds, "ms"); LL_DECLARE_DERIVED_UNIT(Milliseconds, / 1000, Microseconds, "\x09\x3cs"); LL_DECLARE_DERIVED_UNIT(Microseconds, / 1000, Nanoseconds, "ns"); } typedef LLUnit F32Seconds; typedef LLUnit F32Minutes; typedef LLUnit F32Hours; typedef LLUnit F32Days; typedef LLUnit F32Milliseconds; typedef LLUnit F32Microseconds; typedef LLUnit F32Nanoseconds; typedef LLUnitImplicit F32SecondsImplicit; typedef LLUnitImplicit F32MinutesImplicit; typedef LLUnitImplicit F32HoursImplicit; typedef LLUnitImplicit F32DaysImplicit; typedef LLUnitImplicit F32MillisecondsImplicit; typedef LLUnitImplicit F32MicrosecondsImplicit; typedef LLUnitImplicit F32NanosecondsImplicit; typedef LLUnit F64Seconds; typedef LLUnit F64Minutes; typedef LLUnit F64Hours; typedef LLUnit F64Days; typedef LLUnit F64Milliseconds; typedef LLUnit F64Microseconds; typedef LLUnit F64Nanoseconds; typedef LLUnitImplicit F64SecondsImplicit; typedef LLUnitImplicit F64MinutesImplicit; typedef LLUnitImplicit F64HoursImplicit; typedef LLUnitImplicit F64DaysImplicit; typedef LLUnitImplicit F64MillisecondsImplicit; typedef LLUnitImplicit F64MicrosecondsImplicit; typedef LLUnitImplicit F64NanosecondsImplicit; typedef LLUnit S32Seconds; typedef LLUnit S32Minutes; typedef LLUnit S32Hours; typedef LLUnit S32Days; typedef LLUnit S32Milliseconds; typedef LLUnit S32Microseconds; typedef LLUnit S32Nanoseconds; typedef LLUnitImplicit S32SecondsImplicit; typedef LLUnitImplicit S32MinutesImplicit; typedef LLUnitImplicit S32HoursImplicit; typedef LLUnitImplicit S32DaysImplicit; typedef LLUnitImplicit S32MillisecondsImplicit; typedef LLUnitImplicit S32MicrosecondsImplicit; typedef LLUnitImplicit S32NanosecondsImplicit; typedef LLUnit S64Seconds; typedef LLUnit S64Minutes; typedef LLUnit S64Hours; typedef LLUnit S64Days; typedef LLUnit S64Milliseconds; typedef LLUnit S64Microseconds; typedef LLUnit S64Nanoseconds; typedef LLUnitImplicit S64SecondsImplicit; typedef LLUnitImplicit S64MinutesImplicit; typedef LLUnitImplicit S64HoursImplicit; typedef LLUnitImplicit S64DaysImplicit; typedef LLUnitImplicit S64MillisecondsImplicit; typedef LLUnitImplicit S64MicrosecondsImplicit; typedef LLUnitImplicit S64NanosecondsImplicit; typedef LLUnit U32Seconds; typedef LLUnit U32Minutes; typedef LLUnit U32Hours; typedef LLUnit U32Days; typedef LLUnit U32Milliseconds; typedef LLUnit U32Microseconds; typedef LLUnit U32Nanoseconds; typedef LLUnitImplicit U32SecondsImplicit; typedef LLUnitImplicit U32MinutesImplicit; typedef LLUnitImplicit U32HoursImplicit; typedef LLUnitImplicit U32DaysImplicit; typedef LLUnitImplicit U32MillisecondsImplicit; typedef LLUnitImplicit U32MicrosecondsImplicit; typedef LLUnitImplicit U32NanosecondsImplicit; typedef LLUnit U64Seconds; typedef LLUnit U64Minutes; typedef LLUnit U64Hours; typedef LLUnit U64Days; typedef LLUnit U64Milliseconds; typedef LLUnit U64Microseconds; typedef LLUnit U64Nanoseconds; typedef LLUnitImplicit U64SecondsImplicit; typedef LLUnitImplicit U64MinutesImplicit; typedef LLUnitImplicit U64HoursImplicit; typedef LLUnitImplicit U64DaysImplicit; typedef LLUnitImplicit U64MillisecondsImplicit; typedef LLUnitImplicit U64MicrosecondsImplicit; typedef LLUnitImplicit U64NanosecondsImplicit; namespace LLUnits { LL_DECLARE_BASE_UNIT(Meters, "m"); LL_DECLARE_DERIVED_UNIT(Meters, * 1000, Kilometers, "km"); LL_DECLARE_DERIVED_UNIT(Meters, / 100, Centimeters, "cm"); LL_DECLARE_DERIVED_UNIT(Meters, / 1000, Millimeters, "mm"); } typedef LLUnit F32Meters; typedef LLUnit F32Kilometers; typedef LLUnit F32Centimeters; typedef LLUnit F32Millimeters; typedef LLUnitImplicit F32MetersImplicit; typedef LLUnitImplicit F32KilometersImplicit; typedef LLUnitImplicit F32CentimetersImplicit; typedef LLUnitImplicit F32MillimetersImplicit; typedef LLUnit F64Meters; typedef LLUnit F64Kilometers; typedef LLUnit F64Centimeters; typedef LLUnit F64Millimeters; typedef LLUnitImplicit F64MetersImplicit; typedef LLUnitImplicit F64KilometersImplicit; typedef LLUnitImplicit F64CentimetersImplicit; typedef LLUnitImplicit F64MillimetersImplicit; typedef LLUnit S32Meters; typedef LLUnit S32Kilometers; typedef LLUnit S32Centimeters; typedef LLUnit S32Millimeters; typedef LLUnitImplicit S32MetersImplicit; typedef LLUnitImplicit S32KilometersImplicit; typedef LLUnitImplicit S32CentimetersImplicit; typedef LLUnitImplicit S32MillimetersImplicit; typedef LLUnit S64Meters; typedef LLUnit S64Kilometers; typedef LLUnit S64Centimeters; typedef LLUnit S64Millimeters; typedef LLUnitImplicit S64MetersImplicit; typedef LLUnitImplicit S64KilometersImplicit; typedef LLUnitImplicit S64CentimetersImplicit; typedef LLUnitImplicit S64MillimetersImplicit; typedef LLUnit U32Meters; typedef LLUnit U32Kilometers; typedef LLUnit U32Centimeters; typedef LLUnit U32Millimeters; typedef LLUnitImplicit U32MetersImplicit; typedef LLUnitImplicit U32KilometersImplicit; typedef LLUnitImplicit U32CentimetersImplicit; typedef LLUnitImplicit U32MillimetersImplicit; typedef LLUnit U64Meters; typedef LLUnit U64Kilometers; typedef LLUnit U64Centimeters; typedef LLUnit U64Millimeters; typedef LLUnitImplicit U64MetersImplicit; typedef LLUnitImplicit U64KilometersImplicit; typedef LLUnitImplicit U64CentimetersImplicit; typedef LLUnitImplicit U64MillimetersImplicit; namespace LLUnits { // rare units LL_DECLARE_BASE_UNIT(Hertz, "Hz"); LL_DECLARE_DERIVED_UNIT(Hertz, * 1000, Kilohertz, "KHz"); LL_DECLARE_DERIVED_UNIT(Kilohertz, * 1000, Megahertz, "MHz"); LL_DECLARE_DERIVED_UNIT(Megahertz, * 1000, Gigahertz, "GHz"); LL_DECLARE_BASE_UNIT(Radians, "rad"); LL_DECLARE_DERIVED_UNIT(Radians, / 57.29578f, Degrees, "deg"); LL_DECLARE_BASE_UNIT(Percent, "%"); LL_DECLARE_DERIVED_UNIT(Percent, * 100, Ratio, "x"); LL_DECLARE_BASE_UNIT(Triangles, "tris"); LL_DECLARE_DERIVED_UNIT(Triangles, * 1000, Kilotriangles, "ktris"); } // namespace LLUnits // rare units typedef LLUnit F32Hertz; typedef LLUnit F32Kilohertz; typedef LLUnit F32Megahertz; typedef LLUnit F32Gigahertz; typedef LLUnit F32Radians; typedef LLUnit F32Degrees; typedef LLUnit F32Percent; typedef LLUnit F32Ratio; typedef LLUnit F32Triangles; typedef LLUnit F32KiloTriangles; typedef LLUnitImplicit F32HertzImplicit; typedef LLUnitImplicit F32KilohertzImplicit; typedef LLUnitImplicit F32MegahertzImplicit; typedef LLUnitImplicit F32GigahertzImplicit; typedef LLUnitImplicit F32RadiansImplicit; typedef LLUnitImplicit F32DegreesImplicit; typedef LLUnitImplicit F32PercentImplicit; typedef LLUnitImplicit F32RatioImplicit; typedef LLUnitImplicit F32TrianglesImplicit; typedef LLUnitImplicit F32KiloTrianglesImplicit; typedef LLUnit F64Hertz; typedef LLUnit F64Kilohertz; typedef LLUnit F64Megahertz; typedef LLUnit F64Gigahertz; typedef LLUnit F64Radians; typedef LLUnit F64Degrees; typedef LLUnit F64Percent; typedef LLUnit F64Ratio; typedef LLUnit F64Triangles; typedef LLUnit F64KiloTriangles; typedef LLUnitImplicit F64HertzImplicit; typedef LLUnitImplicit F64KilohertzImplicit; typedef LLUnitImplicit F64MegahertzImplicit; typedef LLUnitImplicit F64GigahertzImplicit; typedef LLUnitImplicit F64RadiansImplicit; typedef LLUnitImplicit F64DegreesImplicit; typedef LLUnitImplicit F64PercentImplicit; typedef LLUnitImplicit F64RatioImplicit; typedef LLUnitImplicit F64TrianglesImplicit; typedef LLUnitImplicit F64KiloTrianglesImplicit; typedef LLUnit S32Hertz; typedef LLUnit S32Kilohertz; typedef LLUnit S32Megahertz; typedef LLUnit S32Gigahertz; typedef LLUnit S32Radians; typedef LLUnit S32Degrees; typedef LLUnit S32Percent; typedef LLUnit S32Ratio; typedef LLUnit S32Triangles; typedef LLUnit S32KiloTriangles; typedef LLUnitImplicit S32HertzImplicit; typedef LLUnitImplicit S32KilohertzImplicit; typedef LLUnitImplicit S32MegahertzImplicit; typedef LLUnitImplicit S32GigahertzImplicit; typedef LLUnitImplicit S32RadiansImplicit; typedef LLUnitImplicit S32DegreesImplicit; typedef LLUnitImplicit S32PercentImplicit; typedef LLUnitImplicit S32RatioImplicit; typedef LLUnitImplicit S32TrianglesImplicit; typedef LLUnitImplicit S32KiloTrianglesImplicit; typedef LLUnit S64Hertz; typedef LLUnit S64Kilohertz; typedef LLUnit S64Megahertz; typedef LLUnit S64Gigahertz; typedef LLUnit S64Radians; typedef LLUnit S64Degrees; typedef LLUnit S64Percent; typedef LLUnit S64Ratio; typedef LLUnit S64Triangles; typedef LLUnit S64KiloTriangles; typedef LLUnitImplicit S64HertzImplicit; typedef LLUnitImplicit S64KilohertzImplicit; typedef LLUnitImplicit S64MegahertzImplicit; typedef LLUnitImplicit S64GigahertzImplicit; typedef LLUnitImplicit S64RadiansImplicit; typedef LLUnitImplicit S64DegreesImplicit; typedef LLUnitImplicit S64PercentImplicit; typedef LLUnitImplicit S64RatioImplicit; typedef LLUnitImplicit S64TrianglesImplicit; typedef LLUnitImplicit S64KiloTrianglesImplicit; typedef LLUnit U32Hertz; typedef LLUnit U32Kilohertz; typedef LLUnit U32Megahertz; typedef LLUnit U32Gigahertz; typedef LLUnit U32Radians; typedef LLUnit U32Degrees; typedef LLUnit U32Percent; typedef LLUnit U32Ratio; typedef LLUnit U32Triangles; typedef LLUnit U32KiloTriangles; typedef LLUnitImplicit U32HertzImplicit; typedef LLUnitImplicit U32KilohertzImplicit; typedef LLUnitImplicit U32MegahertzImplicit; typedef LLUnitImplicit U32GigahertzImplicit; typedef LLUnitImplicit U32RadiansImplicit; typedef LLUnitImplicit U32DegreesImplicit; typedef LLUnitImplicit U32PercentImplicit; typedef LLUnitImplicit U32RatioImplicit; typedef LLUnitImplicit U32TrianglesImplicit; typedef LLUnitImplicit U32KiloTrianglesImplicit; typedef LLUnit U64Hertz; typedef LLUnit U64Kilohertz; typedef LLUnit U64Megahertz; typedef LLUnit U64Gigahertz; typedef LLUnit U64Radians; typedef LLUnit U64Degrees; typedef LLUnit U64Percent; typedef LLUnit U64Ratio; typedef LLUnit U64Triangles; typedef LLUnit U64KiloTriangles; typedef LLUnitImplicit U64HertzImplicit; typedef LLUnitImplicit U64KilohertzImplicit; typedef LLUnitImplicit U64MegahertzImplicit; typedef LLUnitImplicit U64GigahertzImplicit; typedef LLUnitImplicit U64RadiansImplicit; typedef LLUnitImplicit U64DegreesImplicit; typedef LLUnitImplicit U64PercentImplicit; typedef LLUnitImplicit U64RatioImplicit; typedef LLUnitImplicit U64TrianglesImplicit; typedef LLUnitImplicit U64KiloTrianglesImplicit; #endif // LL_LLUNIT_H