// // opaque_typedef_test.cpp // opaque_typedef // // Created by Sam Jaffe on 6/3/18. // #include #include #include "opaque_typedef.hpp" struct degree; struct radian; CREATE_CONVERTABLE_OPAQUE_TYPEDEF(degree, double, orderable)(radian); CREATE_CONVERTABLE_OPAQUE_TYPEDEF(radian, double, orderable)(degree); radian::operator degree() const { return degree{ self() * 90.0 / M_PI_2 }; } degree::operator radian() const { return radian{ self() * M_PI_2 / 90.0 }; } void PrintTo(radian const & ot, std::ostream * os) { (*os) << double(ot)/M_PI << "π"; } void PrintTo(degree const & ot, std::ostream * os) { (*os) << double(ot) << "°"; } TEST(OpaqueTypedefTest, Conversion) { degree deg{90.0}; radian rad{M_PI_2}; EXPECT_THAT(radian(deg), rad); EXPECT_THAT(degree(rad), deg); EXPECT_THAT(radian(double(deg)), ::testing::Not(rad)); EXPECT_THAT(degree(double(rad)), ::testing::Not(deg)); } struct meters; struct seconds; struct meter_per_second; CREATE_OPAQUE_TYPEDEF(seconds, double, orderable); CREATE_OPAQUE_TYPEDEF(meter_per_second, double, orderable); template using mps = mixed_division; CREATE_OPAQUE_TYPEDEF(meters, double, orderable, mps); TEST(OpaqueTypedefTest, MixedFunctions) { meters m{10.0}; seconds s{0.5}; EXPECT_THAT(m/s, meter_per_second{20.0}); }