opaque_typedef_test.cpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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. struct degree : types::opaque_typedef<double, struct degree_tag, types::Comparable, types::Convertable<radian>::type> {
  13. using super::super;
  14. };
  15. struct radian : types::opaque_typedef<double, struct radian_tag, types::Comparable, types::Convertable<degree>::type> {
  16. using super::super;
  17. };
  18. template<> template <>
  19. types::Convertable<degree>::type<radian::super>::operator degree() const {
  20. return degree{ self().get() * 90.0 / M_PI_2 };
  21. }
  22. template <> template <>
  23. types::Convertable<radian>::type<degree::super>::operator radian() const {
  24. return radian{ self().get() * M_PI_2 / 90.0 };
  25. }
  26. void PrintTo(radian const & ot, std::ostream * os) {
  27. (*os) << double(ot)/M_PI << "π";
  28. }
  29. void PrintTo(degree const & ot, std::ostream * os) {
  30. (*os) << double(ot) << "°";
  31. }
  32. TEST(OpaqueTypedefTest, Conversion) {
  33. degree deg{90.0};
  34. radian rad{M_PI_2};
  35. EXPECT_THAT(radian(deg), rad);
  36. EXPECT_THAT(degree(rad), deg);
  37. EXPECT_THAT(radian(double(deg)), ::testing::Not(rad));
  38. EXPECT_THAT(degree(double(rad)), ::testing::Not(deg));
  39. }
  40. using meters = types::opaque_typedef<double, struct meters_tag, types::Comparable>;
  41. using seconds = types::opaque_typedef<double, struct seconds_tag, types::Comparable>;
  42. using meter_per_second = types::opaque_typedef<double, struct mps_tag, types::Comparable>;
  43. meter_per_second operator/(meters m, seconds s) {
  44. return meter_per_second{m.get() / s.get()};
  45. }
  46. TEST(OpaqueTypedefTest, MixedFunctions) {
  47. meters m{10.0};
  48. seconds s{0.5};
  49. EXPECT_THAT(m/s, meter_per_second{20.0});
  50. }