1 // Copyright 2015-2018 Hans Dembinski
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)
7 #include <boost/core/is_same.hpp>
8 #include <boost/core/lightweight_test.hpp>
9 #include <boost/core/lightweight_test_trait.hpp>
10 #include <boost/histogram/axis.hpp>
11 #include <boost/histogram/axis/ostream.hpp>
12 #include <boost/histogram/histogram.hpp>
13 #include <boost/histogram/ostream.hpp>
14 #include <boost/throw_exception.hpp>
17 #include "std_ostream.hpp"
18 #include "throw_exception.hpp"
19 #include "utility_histogram.hpp"
21 using namespace boost::histogram;
23 template <typename Tag>
25 // arithmetic operators
27 auto a = make(Tag(), axis::integer<int, use_default, axis::option::none_t>(0, 2));
32 BOOST_TEST_EQ(c.at(0), 1);
33 BOOST_TEST_EQ(c.at(1), 1);
35 BOOST_TEST_EQ(c.at(0), 1);
36 BOOST_TEST_EQ(c.at(1), 2);
38 BOOST_TEST_TRAIT_SAME(decltype(d), decltype(a));
39 BOOST_TEST_EQ(d.at(0), 2);
40 BOOST_TEST_EQ(d.at(1), 3);
42 auto d2 = d - a - b - c;
43 BOOST_TEST_TRAIT_SAME(decltype(d2), decltype(a));
44 BOOST_TEST_EQ(d2.at(0), 0);
45 BOOST_TEST_EQ(d2.at(1), 0);
47 BOOST_TEST_EQ(d2.at(0), -1);
48 BOOST_TEST_EQ(d2.at(1), 0);
52 BOOST_TEST_EQ(d3.at(0), 4);
53 BOOST_TEST_EQ(d3.at(1), 9);
54 auto d4 = d3 * (1 * d); // converted return type
55 BOOST_TEST_TRAIT_FALSE((boost::core::is_same<decltype(d4), decltype(d3)>));
56 BOOST_TEST_EQ(d4.at(0), 8);
57 BOOST_TEST_EQ(d4.at(1), 27);
59 BOOST_TEST_EQ(d4.at(0), 4);
60 BOOST_TEST_EQ(d4.at(1), 9);
62 BOOST_TEST_EQ(d5.at(0), 2);
63 BOOST_TEST_EQ(d5.at(1), 3);
65 auto e = 3 * a; // converted return type
66 auto f = b * 2; // converted return type
67 BOOST_TEST_TRAIT_FALSE((boost::core::is_same<decltype(e), decltype(a)>));
68 BOOST_TEST_TRAIT_FALSE((boost::core::is_same<decltype(f), decltype(a)>));
69 BOOST_TEST_EQ(e.at(0), 3);
70 BOOST_TEST_EQ(e.at(1), 0);
71 BOOST_TEST_EQ(f.at(0), 0);
72 BOOST_TEST_EQ(f.at(1), 2);
76 BOOST_TEST_EQ(r.at(0), 4);
77 BOOST_TEST_EQ(r.at(1), 1);
78 BOOST_TEST_EQ(r, a + b + 3 * a);
81 BOOST_TEST_EQ(r.at(0), 1);
82 BOOST_TEST_EQ(r.at(1), 0.25);
86 // arithmetic operators with mixed storage: unlimited vs. vector<unsigned>
88 auto ia = axis::integer<int, axis::null_type, axis::option::none_t>(0, 2);
89 auto a = make(Tag(), ia);
93 auto c = make_s(Tag(), std::vector<int>(), ia);
98 BOOST_TEST_EQ(a2, (a + b));
101 BOOST_TEST_EQ(a3, (a * b));
104 BOOST_TEST_EQ(a4, (a - b));
107 BOOST_TEST_EQ(a5, (a / b));
110 // arithmetic operators with mixed storage: vector<unsigned char> vs. vector<unsigned>
112 auto ia = axis::integer<int, axis::null_type, axis::option::none_t>(0, 2);
113 auto a = make_s(Tag(), std::vector<unsigned long>{}, ia);
114 auto c = make_s(Tag(), std::vector<unsigned>(), ia);
122 BOOST_TEST_EQ(a2, (a + b));
125 BOOST_TEST_EQ(a3, (a * b));
128 BOOST_TEST_EQ(a4, (a - b));
131 BOOST_TEST_EQ(a5, (a / b));
134 // add operators with weighted storage
136 auto ia = axis::integer<int, axis::null_type, axis::option::none_t>(0, 2);
137 auto a = make_s(Tag(), std::vector<accumulators::weighted_sum<>>(), ia);
138 auto b = make_s(Tag(), std::vector<accumulators::weighted_sum<>>(), ia);
141 BOOST_TEST_EQ(a.at(0).variance(), 1);
143 BOOST_TEST_EQ(b.at(1).variance(), 9);
146 BOOST_TEST_EQ(c.at(0).value(), 1);
147 BOOST_TEST_EQ(c.at(0).variance(), 1);
148 BOOST_TEST_EQ(c.at(1).value(), 3);
149 BOOST_TEST_EQ(c.at(1).variance(), 9);
152 BOOST_TEST_EQ(d.at(0).value(), 1);
153 BOOST_TEST_EQ(d.at(0).variance(), 1);
154 BOOST_TEST_EQ(d.at(1).value(), 3);
155 BOOST_TEST_EQ(d.at(1).variance(), 9);
160 auto a = make(Tag(), axis::integer<>(0, 2));
161 auto b = make(Tag(), axis::integer<>(0, 3));
162 BOOST_TEST_THROWS(a += b, std::invalid_argument);
163 BOOST_TEST_THROWS(a -= b, std::invalid_argument);
164 BOOST_TEST_THROWS(a *= b, std::invalid_argument);
165 BOOST_TEST_THROWS(a /= b, std::invalid_argument);
170 run_tests<static_tag>();
171 run_tests<dynamic_tag>();
173 return boost::report_errors();