opaque_typedef_test.cpp 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. //
  2. // opaque_typedef_test.cpp
  3. // opaque_typedef
  4. //
  5. // Created by Sam Jaffe on 6/3/18.
  6. //
  7. #include <gmock/gmock.h>
  8. #include <cmath>
  9. #include "opaque_typedef.hpp"
  10. struct degree;
  11. struct radian;
  12. CREATE_CONVERTABLE_OPAQUE_TYPEDEF(degree, double, orderable)(radian);
  13. CREATE_CONVERTABLE_OPAQUE_TYPEDEF(radian, double, orderable)(degree);
  14. radian::operator degree() const {
  15. return degree{ self() * 90.0 / M_PI_2 };
  16. }
  17. degree::operator radian() const {
  18. return radian{ self() * M_PI_2 / 90.0 };
  19. }
  20. void PrintTo(radian const & ot, std::ostream * os) {
  21. (*os) << double(ot)/M_PI << "π";
  22. }
  23. void PrintTo(degree const & ot, std::ostream * os) {
  24. (*os) << double(ot) << "°";
  25. }
  26. TEST(OpaqueTypedefTest, Conversion) {
  27. degree deg{90.0};
  28. radian rad{M_PI_2};
  29. EXPECT_THAT(radian(deg), rad);
  30. EXPECT_THAT(degree(rad), deg);
  31. EXPECT_THAT(radian(double(deg)), ::testing::Not(rad));
  32. EXPECT_THAT(degree(double(rad)), ::testing::Not(deg));
  33. }
  34. struct meters;
  35. struct seconds;
  36. struct meter_per_second;
  37. CREATE_OPAQUE_TYPEDEF(seconds, double, orderable);
  38. CREATE_OPAQUE_TYPEDEF(meter_per_second, double, orderable);
  39. template <typename T> using mps = mixed_division<T, seconds, meter_per_second>;
  40. CREATE_OPAQUE_TYPEDEF(meters, double, orderable, mps);
  41. TEST(OpaqueTypedefTest, MixedFunctions) {
  42. meters m{10.0};
  43. seconds s{0.5};
  44. EXPECT_THAT(m/s, meter_per_second{20.0});
  45. }