axis_traits_test.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // Copyright 2018 Hans Dembinski
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/core/lightweight_test.hpp>
  7. #include <boost/core/lightweight_test_trait.hpp>
  8. #include <boost/histogram/axis.hpp>
  9. #include <boost/histogram/axis/traits.hpp>
  10. #include "std_ostream.hpp"
  11. #include "throw_exception.hpp"
  12. #include "utility_axis.hpp"
  13. using namespace boost::histogram::axis;
  14. int main() {
  15. // value_type
  16. {
  17. BOOST_TEST_TRAIT_SAME(traits::value_type<integer<int>>, int);
  18. BOOST_TEST_TRAIT_SAME(traits::value_type<category<int>>, int);
  19. BOOST_TEST_TRAIT_SAME(traits::value_type<regular<double>>, double);
  20. }
  21. // is_continuous
  22. {
  23. BOOST_TEST_TRAIT_TRUE((traits::is_continuous<regular<>>));
  24. BOOST_TEST_TRAIT_FALSE((traits::is_continuous<integer<int>>));
  25. BOOST_TEST_TRAIT_FALSE((traits::is_continuous<category<int>>));
  26. BOOST_TEST_TRAIT_TRUE((traits::is_continuous<integer<double>>));
  27. }
  28. // is_reducible
  29. {
  30. struct not_reducible {};
  31. struct reducible {
  32. reducible(const reducible&, index_type, index_type, unsigned);
  33. };
  34. BOOST_TEST_TRAIT_TRUE((traits::is_reducible<reducible>));
  35. BOOST_TEST_TRAIT_FALSE((traits::is_reducible<not_reducible>));
  36. BOOST_TEST_TRAIT_TRUE((traits::is_reducible<regular<>>));
  37. BOOST_TEST_TRAIT_TRUE((traits::is_reducible<variable<>>));
  38. BOOST_TEST_TRAIT_TRUE((traits::is_reducible<circular<>>));
  39. BOOST_TEST_TRAIT_TRUE((traits::is_reducible<integer<>>));
  40. BOOST_TEST_TRAIT_FALSE((traits::is_reducible<category<>>));
  41. }
  42. // static_is_inclusive
  43. {
  44. struct empty {};
  45. struct with_opts_not_inclusive {
  46. static constexpr unsigned options() { return option::underflow | option::overflow; }
  47. static constexpr bool inclusive() { return false; }
  48. };
  49. BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive<empty>));
  50. BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive<with_opts_not_inclusive>));
  51. BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive<regular<>>));
  52. BOOST_TEST_TRAIT_FALSE(
  53. (traits::static_is_inclusive<
  54. regular<double, boost::use_default, boost::use_default, option::growth_t>>));
  55. BOOST_TEST_TRAIT_FALSE(
  56. (traits::static_is_inclusive<regular<double, boost::use_default,
  57. boost::use_default, option::circular_t>>));
  58. BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive<variable<>>));
  59. BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive<
  60. variable<double, boost::use_default, option::growth_t>>));
  61. BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive<
  62. variable<double, boost::use_default, option::circular_t>>));
  63. BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive<integer<int>>));
  64. BOOST_TEST_TRAIT_TRUE((
  65. traits::static_is_inclusive<integer<int, boost::use_default, option::growth_t>>));
  66. BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive<
  67. integer<int, boost::use_default, option::circular_t>>));
  68. BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive<integer<double>>));
  69. BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive<
  70. integer<double, boost::use_default, option::growth_t>>));
  71. BOOST_TEST_TRAIT_FALSE((traits::static_is_inclusive<
  72. integer<double, boost::use_default, option::circular_t>>));
  73. BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive<category<int>>));
  74. BOOST_TEST_TRAIT_TRUE((traits::static_is_inclusive<
  75. category<int, boost::use_default, option::growth_t>>));
  76. BOOST_TEST_TRAIT_FALSE(
  77. (traits::static_is_inclusive<category<int, boost::use_default, option::none_t>>));
  78. }
  79. // index, rank, value, width
  80. {
  81. auto a = integer<>(1, 3);
  82. BOOST_TEST_EQ(traits::index(a, 1), 0);
  83. BOOST_TEST_EQ(traits::rank(a), 1);
  84. BOOST_TEST_EQ(traits::value(a, 0), 1);
  85. BOOST_TEST_EQ(traits::width(a, 0), 0);
  86. BOOST_TEST_EQ(traits::width(a, 0), 0);
  87. auto b = integer<double>(1, 3);
  88. BOOST_TEST_EQ(traits::index(b, 1), 0);
  89. BOOST_TEST_EQ(traits::rank(b), 1);
  90. BOOST_TEST_EQ(traits::value(b, 0), 1);
  91. BOOST_TEST_EQ(traits::width(b, 0), 1);
  92. BOOST_TEST(traits::static_options<decltype(b)>::test(option::underflow));
  93. auto c = category<std::string>{"red", "blue"};
  94. BOOST_TEST_EQ(traits::index(c, "blue"), 1);
  95. BOOST_TEST_EQ(traits::rank(c), 1);
  96. BOOST_TEST_EQ(traits::value(c, 0), std::string("red"));
  97. BOOST_TEST_EQ(traits::width(c, 0), 0);
  98. struct D {
  99. index_type index(const std::tuple<int, double>& args) const {
  100. return static_cast<index_type>(std::get<0>(args) + std::get<1>(args));
  101. }
  102. index_type size() const { return 5u; }
  103. } d;
  104. BOOST_TEST_EQ(traits::index(d, std::make_tuple(1, 2.0)), 3.0);
  105. BOOST_TEST_EQ(traits::rank(d), 2u);
  106. variant<D, integer<>> v;
  107. v = a;
  108. BOOST_TEST_EQ(traits::rank(v), 1u);
  109. v = d;
  110. BOOST_TEST_EQ(traits::rank(v), 2u);
  111. }
  112. // static_options, options()
  113. {
  114. using A = integer<>;
  115. BOOST_TEST_EQ(traits::static_options<A>::test(option::growth), false);
  116. auto expected = option::underflow | option::overflow;
  117. auto a = A{};
  118. BOOST_TEST_EQ(traits::options(a), expected);
  119. BOOST_TEST_EQ(traits::options(static_cast<A&>(a)), expected);
  120. BOOST_TEST_EQ(traits::options(static_cast<const A&>(a)), expected);
  121. BOOST_TEST_EQ(traits::options(std::move(a)), expected);
  122. using B = integer<int, null_type, option::growth_t>;
  123. BOOST_TEST_EQ(traits::static_options<B>::test(option::growth), true);
  124. BOOST_TEST_EQ(traits::options(B{}), option::growth);
  125. struct growing {
  126. auto update(double) { return std::make_pair(0, 0); }
  127. };
  128. using C = growing;
  129. BOOST_TEST_EQ(traits::static_options<C>::test(option::growth), true);
  130. auto c = C{};
  131. BOOST_TEST_EQ(traits::options(c), option::growth);
  132. BOOST_TEST_EQ(traits::options(static_cast<C&>(c)), option::growth);
  133. BOOST_TEST_EQ(traits::options(static_cast<const C&>(c)), option::growth);
  134. BOOST_TEST_EQ(traits::options(std::move(c)), option::growth);
  135. struct notgrowing {
  136. auto index(double) { return 0; }
  137. };
  138. using D = notgrowing;
  139. BOOST_TEST_EQ(traits::static_options<D>::test(option::growth), false);
  140. auto d = D{};
  141. BOOST_TEST_EQ(traits::options(d), option::none);
  142. BOOST_TEST_EQ(traits::options(static_cast<D&>(d)), option::none);
  143. BOOST_TEST_EQ(traits::options(static_cast<const D&>(d)), option::none);
  144. BOOST_TEST_EQ(traits::options(std::move(d)), option::none);
  145. }
  146. // update
  147. {
  148. auto a = integer<int, null_type, option::growth_t>();
  149. BOOST_TEST_EQ(traits::update(a, 0), (std::pair<index_type, index_type>(0, -1)));
  150. BOOST_TEST_THROWS(traits::update(a, "foo"), std::invalid_argument);
  151. variant<integer<int, null_type, option::growth_t>, integer<>> v(a);
  152. BOOST_TEST_EQ(traits::update(v, 0), (std::pair<index_type, index_type>(0, 0)));
  153. }
  154. // metadata
  155. {
  156. struct None {};
  157. struct Const {
  158. const int& metadata() const { return m; };
  159. int m = 0;
  160. };
  161. struct Both {
  162. const int& metadata() const { return m; };
  163. int& metadata() { return m; };
  164. int m = 0;
  165. };
  166. None none;
  167. BOOST_TEST_TRAIT_SAME(decltype(traits::metadata(none)), null_type&);
  168. BOOST_TEST_TRAIT_SAME(decltype(traits::metadata(static_cast<None&>(none))),
  169. null_type&);
  170. BOOST_TEST_TRAIT_SAME(decltype(traits::metadata(static_cast<const None&>(none))),
  171. const null_type&);
  172. Const c;
  173. BOOST_TEST_EQ(traits::metadata(c), 0);
  174. BOOST_TEST_EQ(traits::metadata(static_cast<Const&>(c)), 0);
  175. BOOST_TEST_EQ(traits::metadata(static_cast<const Const&>(c)), 0);
  176. Both b;
  177. BOOST_TEST_EQ(traits::metadata(b), 0);
  178. BOOST_TEST_EQ(traits::metadata(static_cast<Both&>(b)), 0);
  179. BOOST_TEST_EQ(traits::metadata(static_cast<const Both&>(b)), 0);
  180. }
  181. return boost::report_errors();
  182. }