constant.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  4. #ifndef BOOST_HANA_TEST_LAWS_CONSTANT_HPP
  5. #define BOOST_HANA_TEST_LAWS_CONSTANT_HPP
  6. #include <boost/hana/assert.hpp>
  7. #include <boost/hana/bool.hpp>
  8. #include <boost/hana/concept/comparable.hpp>
  9. #include <boost/hana/core/when.hpp>
  10. #include <boost/hana/functional/capture.hpp>
  11. #include <boost/hana/concept/logical.hpp>
  12. #include <laws/base.hpp>
  13. #include <laws/comparable.hpp>
  14. #include <laws/euclidean_ring.hpp>
  15. #include <laws/group.hpp>
  16. #include <laws/logical.hpp>
  17. #include <laws/monoid.hpp>
  18. #include <laws/orderable.hpp>
  19. #include <laws/ring.hpp>
  20. #include <type_traits>
  21. namespace boost { namespace hana { namespace test {
  22. template <typename C, typename = when<true>>
  23. struct TestConstant {
  24. using T = typename C::value_type;
  25. template <typename X>
  26. struct wrap_arbitrary_constant {
  27. static constexpr bool value = boost::hana::value<X>();
  28. using hana_tag = detail::CanonicalConstant<T>;
  29. };
  30. template <typename Xs, typename Convertibles>
  31. TestConstant(Xs xs, Convertibles types) {
  32. hana::for_each(xs, [](auto x) {
  33. static_assert(Constant<decltype(x)>{}, "");
  34. });
  35. hana::for_each(xs, hana::capture(types)([](auto types, auto c) {
  36. // constexpr-ness of hana::value(c)
  37. constexpr auto must_be_constexpr1 = hana::value(c);
  38. constexpr auto must_be_constexpr2 = hana::value<decltype(c)>();
  39. (void)must_be_constexpr1;
  40. (void)must_be_constexpr2;
  41. // consistency of C::value_type
  42. static_assert(std::is_same<
  43. T,
  44. tag_of_t<decltype(hana::value(c))>
  45. >{}, "");
  46. // equivalence of value_of(c) and value<decltype(c)>
  47. BOOST_HANA_CHECK(hana::equal(
  48. hana::value_of(c),
  49. hana::value<decltype(c)>()
  50. ));
  51. // equivalence of value<decltype(c)>() and value(c)
  52. BOOST_HANA_CHECK(hana::equal(
  53. hana::value<decltype(c)>(),
  54. hana::value(c)
  55. ));
  56. // conversion from an arbitrary Constant
  57. (void)to<C>(wrap_arbitrary_constant<decltype(c)>{});
  58. static_assert(is_embedded<detail::CanonicalConstant<T>, C>{}, "");
  59. hana::for_each(types, hana::capture(c)([](auto c, auto u) {
  60. using U = typename decltype(u)::type;
  61. // conversion to something to which the underlying data
  62. // type can be converted.
  63. BOOST_HANA_CHECK(equal(
  64. to<U>(c),
  65. make<U>(hana::value(c))
  66. ));
  67. static_assert(is_embedded<C, U>::value ^iff^ is_embedded<T, U>::value, "");
  68. // common data type
  69. static_assert(std::is_same<
  70. common_t<C, detail::CanonicalConstant<U>>,
  71. detail::CanonicalConstant<common_t<T, U>>
  72. >{}, "");
  73. static_assert(std::is_same<
  74. common_t<detail::CanonicalConstant<U>, C>,
  75. detail::CanonicalConstant<common_t<T, U>>
  76. >{}, "");
  77. static_assert(std::is_same<
  78. common_t<C, U>,
  79. common_t<typename C::value_type, U>
  80. >{}, "");
  81. }));
  82. }));
  83. }
  84. };
  85. }}} // end namespace boost::hana::test
  86. #endif // !BOOST_HANA_TEST_LAWS_CONSTANT_HPP