Skip to content

Instantly share code, notes, and snippets.

@daniel-j-h
Last active December 21, 2015 23:58
Show Gist options
  • Save daniel-j-h/4bf5de9f2db2e89ebcd9 to your computer and use it in GitHub Desktop.
Save daniel-j-h/4bf5de9f2db2e89ebcd9 to your computer and use it in GitHub Desktop.
REALLY_STRONG_TYPEDEF
#include <type_traits>
#include <iostream>
#define REALLY_STRONG_TYPEDEF(From, To) \
class To final { \
static_assert(std::is_scalar<From>(), ""); \
From x; \
\
public: \
To() = default; \
explicit To(From x_) : x(x_) {} \
explicit operator From&() { return x; } \
explicit operator const From&() const { return x; } \
}; \
inline From from##To(To to) { return static_cast<From>(to); }
REALLY_STRONG_TYPEDEF(int, Latitude)
REALLY_STRONG_TYPEDEF(int, Longitude)
// you still can extend the types
inline bool operator<(Latitude lhs, Latitude rhs) {
return fromLatitude(lhs) < fromLatitude(rhs);
}
void fn(const Latitude& lat, const Longitude& lon) {
std::cout << fromLatitude(lat) << " " << fromLongitude(lon) << std::endl;
}
int main() {
Latitude lat{48};
Longitude lon{12};
fn(lat, lon);
// accidentally mixing arguments fails at compile time
// fn(lon, lat);
// initialization from different type fails at compile time
// lat = lon;
// implicit conversion fails at compile time
// lat += 2;
// NOTE: Boost's STRONG_TYPEDEF allows the last two to compile!
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment