axis_integer_test.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright 2015-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/histogram/axis/integer.hpp>
  8. #include <boost/histogram/axis/ostream.hpp>
  9. #include <limits>
  10. #include <sstream>
  11. #include <type_traits>
  12. #include "std_ostream.hpp"
  13. #include "throw_exception.hpp"
  14. #include "utility_axis.hpp"
  15. #include "utility_str.hpp"
  16. int main() {
  17. using namespace boost::histogram;
  18. BOOST_TEST(std::is_nothrow_move_assignable<axis::integer<>>::value);
  19. BOOST_TEST(std::is_nothrow_move_constructible<axis::integer<>>::value);
  20. // bad_ctor
  21. { BOOST_TEST_THROWS(axis::integer<>(1, -1), std::invalid_argument); }
  22. // axis::integer with double type
  23. {
  24. axis::integer<double> a{-1, 2, "foo"};
  25. BOOST_TEST_EQ(a.metadata(), "foo");
  26. BOOST_TEST_EQ(static_cast<const axis::integer<double>&>(a).metadata(), "foo");
  27. a.metadata() = "bar";
  28. BOOST_TEST_EQ(static_cast<const axis::integer<double>&>(a).metadata(), "bar");
  29. BOOST_TEST_EQ(a.bin(-1).lower(), -std::numeric_limits<double>::infinity());
  30. BOOST_TEST_EQ(a.bin(a.size()).upper(), std::numeric_limits<double>::infinity());
  31. BOOST_TEST_EQ(a.index(-10), -1);
  32. BOOST_TEST_EQ(a.index(-2), -1);
  33. BOOST_TEST_EQ(a.index(-1), 0);
  34. BOOST_TEST_EQ(a.index(0), 1);
  35. BOOST_TEST_EQ(a.index(1), 2);
  36. BOOST_TEST_EQ(a.index(2), 3);
  37. BOOST_TEST_EQ(a.index(10), 3);
  38. BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 3);
  39. BOOST_TEST_EQ(str(a),
  40. "integer(-1, 2, metadata=\"bar\", options=underflow | overflow)");
  41. axis::integer<double> b;
  42. BOOST_TEST_NE(a, b);
  43. b = a;
  44. BOOST_TEST_EQ(a, b);
  45. axis::integer<double> c = std::move(b);
  46. BOOST_TEST_EQ(c, a);
  47. axis::integer<double> d;
  48. BOOST_TEST_NE(c, d);
  49. d = std::move(c);
  50. BOOST_TEST_EQ(d, a);
  51. }
  52. // empty axis::integer
  53. {
  54. axis::integer<> a;
  55. BOOST_TEST_EQ(a.size(), 0);
  56. BOOST_TEST_EQ(a.bin(1), 1);
  57. BOOST_TEST_EQ(a.bin(0), 0);
  58. BOOST_TEST_EQ(a.bin(-1), -1);
  59. BOOST_TEST_EQ(a.index(-10), -1);
  60. BOOST_TEST_EQ(a.index(-1), -1);
  61. BOOST_TEST_EQ(a.index(0), 0);
  62. BOOST_TEST_EQ(a.index(10), 0);
  63. BOOST_TEST_EQ(str(a), "integer(0, 0, options=underflow | overflow)");
  64. axis::integer<> b{1, 1};
  65. BOOST_TEST_EQ(b.size(), 0);
  66. BOOST_TEST_EQ(b.bin(1), 2);
  67. BOOST_TEST_EQ(b.bin(0), 1);
  68. BOOST_TEST_EQ(b.bin(-1), 0);
  69. BOOST_TEST_EQ(b.index(-10), -1);
  70. BOOST_TEST_EQ(b.index(-1), -1);
  71. BOOST_TEST_EQ(b.index(0), -1);
  72. BOOST_TEST_EQ(b.index(1), 0);
  73. BOOST_TEST_EQ(b.index(10), 0);
  74. BOOST_TEST_EQ(str(b), "integer(1, 1, options=underflow | overflow)");
  75. }
  76. // axis::integer with int type
  77. {
  78. axis::integer<int> a{-1, 2};
  79. BOOST_TEST_EQ(a.bin(-2), -3);
  80. BOOST_TEST_EQ(a.bin(4), 3);
  81. BOOST_TEST_EQ(a.index(-10), -1);
  82. BOOST_TEST_EQ(a.index(-2), -1);
  83. BOOST_TEST_EQ(a.index(-1), 0);
  84. BOOST_TEST_EQ(a.index(0), 1);
  85. BOOST_TEST_EQ(a.index(1), 2);
  86. BOOST_TEST_EQ(a.index(2), 3);
  87. BOOST_TEST_EQ(a.index(10), 3);
  88. BOOST_TEST_EQ(str(a), "integer(-1, 2, options=underflow | overflow)");
  89. }
  90. // axis::integer int,circular
  91. {
  92. axis::integer<int, axis::null_type, axis::option::circular_t> a(-1, 1);
  93. BOOST_TEST_EQ(a.value(-1), -2);
  94. BOOST_TEST_EQ(a.value(0), -1);
  95. BOOST_TEST_EQ(a.value(1), 0);
  96. BOOST_TEST_EQ(a.value(2), 1);
  97. BOOST_TEST_EQ(a.value(3), 2);
  98. BOOST_TEST_EQ(a.index(-2), 1);
  99. BOOST_TEST_EQ(a.index(-1), 0);
  100. BOOST_TEST_EQ(a.index(0), 1);
  101. BOOST_TEST_EQ(a.index(1), 0);
  102. BOOST_TEST_EQ(a.index(2), 1);
  103. BOOST_TEST_EQ(str(a), "integer(-1, 1, options=circular)");
  104. }
  105. // axis::integer double,circular
  106. {
  107. axis::integer<double, axis::null_type, axis::option::circular_t> a(-1, 1);
  108. BOOST_TEST_EQ(a.value(-1), -2);
  109. BOOST_TEST_EQ(a.value(0), -1);
  110. BOOST_TEST_EQ(a.value(1), 0);
  111. BOOST_TEST_EQ(a.value(2), 1);
  112. BOOST_TEST_EQ(a.value(3), 2);
  113. BOOST_TEST_EQ(a.index(-2), 1);
  114. BOOST_TEST_EQ(a.index(-1), 0);
  115. BOOST_TEST_EQ(a.index(0), 1);
  116. BOOST_TEST_EQ(a.index(1), 0);
  117. BOOST_TEST_EQ(a.index(2), 1);
  118. BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 2);
  119. }
  120. // axis::integer with growth
  121. {
  122. axis::integer<double, axis::null_type, axis::option::growth_t> a;
  123. BOOST_TEST_EQ(a.size(), 0);
  124. BOOST_TEST_EQ(a.update(0), std::make_pair(0, -1));
  125. BOOST_TEST_EQ(a.size(), 1);
  126. BOOST_TEST_EQ(a.update(1), std::make_pair(1, -1));
  127. BOOST_TEST_EQ(a.size(), 2);
  128. BOOST_TEST_EQ(a.update(-1), std::make_pair(0, 1));
  129. BOOST_TEST_EQ(a.size(), 3);
  130. BOOST_TEST_EQ(a.update(std::numeric_limits<double>::infinity()),
  131. std::make_pair(a.size(), 0));
  132. BOOST_TEST_EQ(a.update(std::numeric_limits<double>::quiet_NaN()),
  133. std::make_pair(a.size(), 0));
  134. BOOST_TEST_EQ(a.update(-std::numeric_limits<double>::infinity()),
  135. std::make_pair(-1, 0));
  136. }
  137. // iterators
  138. {
  139. test_axis_iterator(axis::integer<int>(0, 4), 0, 4);
  140. test_axis_iterator(axis::integer<double>(0, 4), 0, 4);
  141. test_axis_iterator(
  142. axis::integer<int, axis::null_type, axis::option::circular_t>(0, 4), 0, 4);
  143. }
  144. // shrink and rebin
  145. {
  146. using A = axis::integer<>;
  147. auto a = A(-1, 5);
  148. auto b = A(a, 2, 5, 1);
  149. BOOST_TEST_EQ(b.size(), 3);
  150. BOOST_TEST_EQ(b.value(0), 1);
  151. BOOST_TEST_EQ(b.value(3), 4);
  152. auto c = A(a, 1, 5, 1);
  153. BOOST_TEST_EQ(c.size(), 4);
  154. BOOST_TEST_EQ(c.value(0), 0);
  155. BOOST_TEST_EQ(c.value(4), 4);
  156. auto e = A(a, 2, 5, 1);
  157. BOOST_TEST_EQ(e.size(), 3);
  158. BOOST_TEST_EQ(e.value(0), 1);
  159. BOOST_TEST_EQ(e.value(3), 4);
  160. }
  161. // shrink and rebin with circular option
  162. {
  163. using A = axis::integer<int, axis::null_type, axis::option::circular_t>;
  164. auto a = A(1, 5);
  165. auto b = A(a, 0, 4, 1);
  166. BOOST_TEST_EQ(a, b);
  167. BOOST_TEST_THROWS(A(a, 1, 4, 1), std::invalid_argument);
  168. BOOST_TEST_THROWS(A(a, 0, 3, 1), std::invalid_argument);
  169. BOOST_TEST_THROWS(A(a, 0, 4, 2), std::invalid_argument);
  170. }
  171. return boost::report_errors();
  172. }