Created
January 7, 2021 21:57
-
-
Save 3noch/3dc06c87263044d82968995314d67a7b to your computer and use it in GitHub Desktop.
C++ Typesafe Units
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <math.h> | |
struct RTK{}; | |
struct Barometer{}; | |
struct Meters{}; | |
template<typename Repr, typename Self> | |
struct UnitWrapped { | |
UnitWrapped(std::string const & unitAbbreviation, Repr val) : unitAbbreviation_(unitAbbreviation), val_(val) {} | |
Repr get() const { return val_; } | |
std::string unitAbbreviation() const { return unitAbbreviation_; } | |
Self operator+(UnitWrapped<Repr, Self> const & other) const { return Self(other.get() + val_); } | |
Self operator-(UnitWrapped<Repr, Self> const & other) const { return Self(other.get() - val_); } | |
protected: | |
Repr const val_; | |
std::string const unitAbbreviation_; | |
}; | |
template<typename Repr, typename Self> | |
std::ostream & operator<<(std::ostream & o, UnitWrapped<Repr, Self> const & v) { | |
o << v.get() << v.unitAbbreviation(); | |
return o; | |
} | |
template<typename Unit, typename Source> | |
struct Altitude : public UnitWrapped<float, Altitude<Unit, Source> > { | |
Altitude(float val) : UnitWrapped<float, Altitude<Unit, Source> >("m", val) {} | |
}; | |
struct Degrees : public UnitWrapped<float, Degrees> { | |
Degrees(float val) : UnitWrapped<float, Degrees>("deg", val) {} | |
}; | |
struct Radians : public UnitWrapped<float, Radians> { | |
Radians(float val) : UnitWrapped<float, Radians>("rad", val) {} | |
}; | |
template<typename Repr> | |
struct Longitude : public UnitWrapped<Repr, Longitude<Repr>> { | |
Longitude(Repr val) : UnitWrapped<Repr, Longitude<Repr>>("", val) {} | |
}; | |
template<typename Repr> | |
struct Latitude : public UnitWrapped<Repr, Latitude<Repr>> { | |
Latitude(Repr val) : UnitWrapped<Repr, Latitude<Repr>>("", val) {} | |
}; | |
Degrees deg2rad(Radians const & rad) { | |
return Degrees(rad.get() * M_PI/180); | |
} | |
Radians rad2deg(Degrees const & deg) { | |
return Radians(deg.get() * 180 / M_PI); | |
} | |
int main() { | |
Altitude<Meters, RTK> const v1(1); | |
Longitude<Radians> const lon(Radians(3)); | |
std::cout << "Hello, world! " << (v1 + Altitude<Meters, RTK>(1.0)) << " " << lon; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment