Skip to content

Instantly share code, notes, and snippets.

@3noch
Created January 7, 2021 21:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 3noch/3dc06c87263044d82968995314d67a7b to your computer and use it in GitHub Desktop.
Save 3noch/3dc06c87263044d82968995314d67a7b to your computer and use it in GitHub Desktop.
C++ Typesafe Units
#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