histogram_dynamic_test.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Copyright 2015-2017 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 <algorithm>
  7. #include <boost/core/ignore_unused.hpp>
  8. #include <boost/core/lightweight_test.hpp>
  9. #include <boost/histogram/axis.hpp>
  10. #include <boost/histogram/axis/ostream.hpp>
  11. #include <boost/histogram/histogram.hpp>
  12. #include <boost/histogram/make_histogram.hpp>
  13. #include <boost/histogram/ostream.hpp>
  14. #include <cstdlib>
  15. #include <limits>
  16. #include <numeric>
  17. #include <sstream>
  18. #include <tuple>
  19. #include <utility>
  20. #include <vector>
  21. #include "throw_exception.hpp"
  22. #include "utility_histogram.hpp"
  23. using namespace boost::histogram;
  24. int main() {
  25. // special stuff that only works with dynamic_tag
  26. // init with vector of axis and vector of axis::variant
  27. {
  28. using R = axis::regular<>;
  29. using I = axis::integer<>;
  30. using V = axis::variable<>;
  31. auto v = std::vector<axis::variant<R, I, V>>();
  32. v.emplace_back(R{4, -1, 1});
  33. v.emplace_back(I{1, 7});
  34. v.emplace_back(V{1, 2, 3});
  35. auto h = make_histogram(v.begin(), v.end());
  36. BOOST_TEST_EQ(h.rank(), 3);
  37. BOOST_TEST_EQ(h.axis(0), v[0]);
  38. BOOST_TEST_EQ(h.axis(1), v[1]);
  39. BOOST_TEST_EQ(h.axis(2), v[2]);
  40. auto h2 = make_histogram_with(std::vector<int>(), v);
  41. BOOST_TEST_EQ(h2.rank(), 3);
  42. BOOST_TEST_EQ(h2.axis(0), v[0]);
  43. BOOST_TEST_EQ(h2.axis(1), v[1]);
  44. BOOST_TEST_EQ(h2.axis(2), v[2]);
  45. auto v2 = std::vector<R>();
  46. v2.emplace_back(10, 0, 1);
  47. v2.emplace_back(20, 0, 2);
  48. auto h3 = make_histogram(v2);
  49. BOOST_TEST_EQ(h3.axis(0), v2[0]);
  50. BOOST_TEST_EQ(h3.axis(1), v2[1]);
  51. }
  52. // too many axes
  53. {
  54. using I = axis::integer<int, axis::null_type, axis::option::none_t>;
  55. // test edge case
  56. auto av = std::vector<I>(BOOST_HISTOGRAM_DETAIL_AXES_LIMIT, I(0, 1));
  57. auto h = make_histogram(av);
  58. auto inputs = std::vector<std::vector<int>>(BOOST_HISTOGRAM_DETAIL_AXES_LIMIT,
  59. std::vector<int>(1, 0));
  60. h.fill(inputs); // should not crash
  61. auto bad = std::vector<I>(BOOST_HISTOGRAM_DETAIL_AXES_LIMIT + 1, I(0, 1));
  62. boost::ignore_unused(bad);
  63. BOOST_TEST_THROWS((void)make_histogram(bad), std::invalid_argument);
  64. }
  65. // bad fill
  66. {
  67. auto a = axis::integer<>(0, 1);
  68. auto b = make(dynamic_tag(), a);
  69. BOOST_TEST_THROWS(b(0, 0), std::invalid_argument);
  70. auto c = make(dynamic_tag(), a, a);
  71. BOOST_TEST_THROWS(c(0), std::invalid_argument);
  72. auto d = make(dynamic_tag(), a);
  73. BOOST_TEST_THROWS(d(std::string()), std::invalid_argument);
  74. struct axis2d {
  75. auto index(const std::tuple<double, double>& x) const {
  76. return axis::index_type{std::get<0>(x) == 1 && std::get<1>(x) == 2};
  77. }
  78. auto size() const { return axis::index_type{2}; }
  79. } e;
  80. auto f = make(dynamic_tag(), a, e);
  81. BOOST_TEST_THROWS(f(0, 0, 0), std::invalid_argument);
  82. BOOST_TEST_THROWS(f(0, std::make_tuple(0, 0), 1), std::invalid_argument);
  83. }
  84. // bad at
  85. {
  86. auto h1 = make(dynamic_tag(), axis::integer<>(0, 2));
  87. h1(1);
  88. BOOST_TEST_THROWS(h1.at(0, 0), std::invalid_argument);
  89. BOOST_TEST_THROWS(h1.at(std::make_tuple(0, 0)), std::invalid_argument);
  90. }
  91. // incompatible axis variant methods
  92. {
  93. auto c = make(dynamic_tag(), axis::category<std::string>({"A", "B"}));
  94. BOOST_TEST_THROWS(c.axis().value(0), std::runtime_error);
  95. }
  96. {
  97. auto h = make_histogram(std::vector<axis::integer<>>(1, axis::integer<>(0, 3)));
  98. h(0);
  99. h(1);
  100. h(2);
  101. BOOST_TEST_EQ(h.at(0), 1);
  102. BOOST_TEST_EQ(h.at(1), 1);
  103. BOOST_TEST_EQ(h.at(2), 1);
  104. }
  105. return boost::report_errors();
  106. }