Last active
December 21, 2015 23:58
-
-
Save daniel-j-h/4bf5de9f2db2e89ebcd9 to your computer and use it in GitHub Desktop.
REALLY_STRONG_TYPEDEF
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 <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