]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
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 | ||
7 | #include <array> | |
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/detail/axes.hpp> | |
13 | #include <limits> | |
14 | #include <tuple> | |
15 | #include <utility> | |
16 | #include <vector> | |
17 | #include "std_ostream.hpp" | |
18 | #include "throw_exception.hpp" | |
19 | ||
20 | using namespace boost::histogram; | |
21 | ||
22 | int main() { | |
23 | // dynamic axis_get with tuples | |
24 | { | |
25 | auto a1 = axis::integer<>(0, 1); | |
26 | auto a2 = axis::integer<>(1, 2); | |
27 | auto tup = std::make_tuple(a1, a2); | |
28 | using E1 = axis::variant<axis::integer<>*>; | |
29 | BOOST_TEST_TRAIT_SAME(decltype(detail::axis_get(tup, 0)), E1); | |
30 | BOOST_TEST_EQ(detail::axis_get(tup, 0), a1); | |
31 | BOOST_TEST_EQ(detail::axis_get(tup, 1), a2); | |
32 | BOOST_TEST_NE(detail::axis_get(tup, 0), a2); | |
33 | } | |
34 | ||
35 | // sequence equality | |
36 | { | |
37 | using R = axis::regular<>; | |
38 | using I = axis::integer<>; | |
39 | using V = axis::variable<>; | |
40 | auto r = R(2, -1, 1); | |
41 | auto i = I(-1, 1); | |
42 | auto v = V{-1, 0, 1}; | |
43 | ||
44 | std::vector<axis::variant<R, I, V>> v1 = {r, i}; | |
45 | std::vector<axis::variant<R, I>> v2 = {r, i}; | |
46 | std::vector<axis::variant<R, I>> v3 = {i, r}; | |
47 | std::vector<axis::variant<I, R>> v4 = {r, i}; | |
48 | std::vector<axis::variant<R, I>> v5 = {r, r}; | |
49 | std::vector<R> v6 = {r, r}; | |
50 | ||
51 | BOOST_TEST(detail::axes_equal(v1, v2)); | |
52 | BOOST_TEST(detail::axes_equal(v1, v4)); | |
53 | BOOST_TEST(detail::axes_equal(v5, v6)); | |
54 | BOOST_TEST_NOT(detail::axes_equal(v1, v3)); | |
55 | BOOST_TEST_NOT(detail::axes_equal(v2, v3)); | |
56 | BOOST_TEST_NOT(detail::axes_equal(v3, v4)); | |
57 | BOOST_TEST_NOT(detail::axes_equal(v1, v5)); | |
58 | ||
59 | auto t1 = std::make_tuple(r, i); | |
60 | auto t2 = std::make_tuple(i, r); | |
61 | auto t3 = std::make_tuple(v, i); | |
62 | auto t4 = std::make_tuple(r, r); | |
63 | ||
20effc67 | 64 | BOOST_TEST(detail::axes_equal(t1, t1)); |
92f5a8d4 TL |
65 | BOOST_TEST(detail::axes_equal(t1, v1)); |
66 | BOOST_TEST(detail::axes_equal(t1, v2)); | |
67 | BOOST_TEST(detail::axes_equal(t1, v4)); | |
68 | BOOST_TEST(detail::axes_equal(v1, t1)); | |
69 | BOOST_TEST(detail::axes_equal(v2, t1)); | |
70 | BOOST_TEST(detail::axes_equal(v4, t1)); | |
71 | BOOST_TEST(detail::axes_equal(t2, v3)); | |
72 | BOOST_TEST(detail::axes_equal(v3, t2)); | |
73 | BOOST_TEST(detail::axes_equal(t4, v5)); | |
74 | BOOST_TEST(detail::axes_equal(t4, v6)); | |
75 | BOOST_TEST_NOT(detail::axes_equal(t1, t2)); | |
76 | BOOST_TEST_NOT(detail::axes_equal(t2, t3)); | |
77 | BOOST_TEST_NOT(detail::axes_equal(t1, v3)); | |
78 | BOOST_TEST_NOT(detail::axes_equal(t1, v3)); | |
79 | BOOST_TEST_NOT(detail::axes_equal(t3, v1)); | |
80 | BOOST_TEST_NOT(detail::axes_equal(t3, v2)); | |
81 | BOOST_TEST_NOT(detail::axes_equal(t3, v3)); | |
82 | BOOST_TEST_NOT(detail::axes_equal(t3, v4)); | |
83 | } | |
84 | ||
85 | // sequence assign | |
86 | { | |
87 | using R = axis::regular<>; | |
88 | using I = axis::integer<>; | |
89 | using V = axis::variable<>; | |
90 | auto r = R(2, -1, 1); | |
91 | auto i = I(-1, 1); | |
92 | auto v = V{-1, 0, 1}; | |
93 | ||
94 | std::vector<axis::variant<R, V, I>> v1 = {r, i}; | |
95 | std::vector<axis::variant<I, R>> v2; | |
96 | std::vector<R> v3 = {r, r}; | |
97 | ||
98 | BOOST_TEST_NOT(detail::axes_equal(v2, v1)); | |
99 | detail::axes_assign(v2, v1); | |
100 | BOOST_TEST(detail::axes_equal(v2, v1)); | |
101 | detail::axes_assign(v2, v3); | |
102 | BOOST_TEST(detail::axes_equal(v2, v3)); | |
103 | ||
104 | auto t1 = std::make_tuple(r); | |
105 | detail::axes_assign(v3, t1); | |
106 | BOOST_TEST(detail::axes_equal(v3, t1)); | |
107 | ||
108 | auto t2 = std::make_tuple(r, i); | |
109 | detail::axes_assign(v2, t2); | |
110 | BOOST_TEST(detail::axes_equal(v2, t2)); | |
111 | ||
112 | auto t3 = std::make_tuple(R{3, -1, 1}, i); | |
113 | BOOST_TEST_NOT(detail::axes_equal(t2, t3)); | |
114 | detail::axes_assign(t2, t3); | |
115 | BOOST_TEST(detail::axes_equal(t2, t3)); | |
116 | } | |
117 | ||
20effc67 TL |
118 | // axes_transform |
119 | { | |
120 | using R = axis::regular<>; | |
121 | using I = axis::integer<double>; | |
122 | ||
123 | { | |
124 | auto t = std::make_tuple(R(1, 0, 1), R(2, 0, 2), I(0, 3)); | |
125 | auto t2 = detail::axes_transform( | |
126 | t, [](std::size_t, const auto& a) { return I(0, a.size()); }); | |
127 | BOOST_TEST_EQ(t2, std::make_tuple(I(0, 1), I(0, 2), I(0, 3))); | |
128 | } | |
129 | { | |
130 | auto t = std::vector<I>{{I(0, 1), I(0, 2)}}; | |
131 | auto t2 = detail::axes_transform( | |
132 | t, [](std::size_t, const auto& a) { return I(0, a.size() + 1); }); | |
133 | auto t3 = std::vector<I>{{I(0, 2), I(0, 3)}}; | |
134 | BOOST_TEST(detail::axes_equal(t2, t3)); | |
135 | } | |
136 | { | |
137 | using V = axis::variant<R, I>; | |
138 | auto t = std::vector<V>{{V{I(0, 1)}, V{R(2, 0, 2)}}}; | |
139 | auto t2 = detail::axes_transform( | |
140 | t, [](std::size_t, const auto& a) { return I(0, a.size() + 1); }); | |
141 | auto t3 = std::vector<V>{{I(0, 2), I(0, 3)}}; | |
142 | BOOST_TEST(detail::axes_equal(t2, t3)); | |
143 | } | |
144 | ||
145 | { | |
146 | using V = axis::variant<R, I>; | |
147 | auto t1 = std::vector<V>{{V{I(0, 1)}, V{R(2, 0, 2)}}}; | |
148 | auto t2 = std::vector<V>{{V{I(0, 1)}, V{R(2, 0, 2)}}}; | |
149 | auto t3 = detail::axes_transform( | |
150 | t1, t2, [](const auto& a, const auto& b) { return I(0, a.size() + b.size()); }); | |
151 | auto t4 = std::vector<V>{{I(0, 2), I(0, 4)}}; | |
152 | BOOST_TEST(detail::axes_equal(t3, t4)); | |
153 | } | |
154 | ||
155 | { | |
156 | // test otherwise unreachable code | |
157 | auto a = R(2, 0, 2); | |
158 | auto b = I(0, 2); | |
159 | BOOST_TEST_THROWS(detail::axis_merger{}(a, b), std::invalid_argument); | |
160 | } | |
161 | } | |
162 | ||
92f5a8d4 TL |
163 | // axes_rank |
164 | { | |
165 | std::tuple<int, int> a; | |
166 | std::vector<int> b(3); | |
167 | std::array<int, 4> c; | |
168 | const std::tuple<int> d; | |
169 | BOOST_TEST_EQ(detail::axes_rank(a), 2); | |
170 | BOOST_TEST_EQ(detail::axes_rank(b), 3); | |
171 | BOOST_TEST_EQ(detail::axes_rank(c), 4); | |
172 | BOOST_TEST_EQ(detail::axes_rank(d), 1); | |
173 | } | |
174 | ||
175 | // bincount overflow | |
176 | { | |
177 | auto v = std::vector<axis::integer<>>( | |
178 | 100, axis::integer<>(0, (std::numeric_limits<int>::max)() - 2)); | |
179 | BOOST_TEST_THROWS(detail::bincount(v), std::overflow_error); | |
180 | } | |
181 | ||
182 | // has_growing_axis | |
183 | { | |
184 | struct growing { | |
185 | auto update(int) { return std::make_pair(0, 0); } | |
186 | }; | |
187 | using T = growing; | |
188 | using I = axis::integer<>; | |
189 | ||
190 | using A = std::tuple<I, T>; | |
191 | using B = std::vector<T>; | |
192 | using C = std::vector<axis::variant<I, T>>; | |
193 | using D = std::tuple<I>; | |
194 | using E = std::vector<I>; | |
195 | using F = std::vector<axis::variant<I>>; | |
196 | ||
197 | BOOST_TEST_TRAIT_TRUE((detail::has_growing_axis<A>)); | |
198 | BOOST_TEST_TRAIT_TRUE((detail::has_growing_axis<B>)); | |
199 | BOOST_TEST_TRAIT_TRUE((detail::has_growing_axis<C>)); | |
200 | BOOST_TEST_TRAIT_FALSE((detail::has_growing_axis<D>)); | |
201 | BOOST_TEST_TRAIT_FALSE((detail::has_growing_axis<E>)); | |
202 | BOOST_TEST_TRAIT_FALSE((detail::has_growing_axis<F>)); | |
203 | } | |
204 | ||
205 | // value_types | |
206 | { | |
207 | using R = axis::regular<float>; | |
208 | using I = axis::integer<int>; | |
209 | using CI = axis::category<int>; | |
210 | using CS = axis::category<std::string>; | |
211 | using A = std::vector<axis::variant<R, I, CS>>; | |
212 | using B = std::vector<axis::variant<CS, I, CI, R>>; | |
213 | using C = std::tuple<I, R, CS>; | |
214 | using D = std::tuple<CS, I, CI, R>; | |
215 | using Expected = boost::mp11::mp_list<int, float, std::string>; | |
216 | BOOST_TEST_TRAIT_SAME(detail::value_types<A>, Expected); | |
217 | BOOST_TEST_TRAIT_SAME(detail::value_types<B>, Expected); | |
218 | BOOST_TEST_TRAIT_SAME(detail::value_types<C>, Expected); | |
219 | BOOST_TEST_TRAIT_SAME(detail::value_types<D>, Expected); | |
220 | } | |
221 | ||
222 | return boost::report_errors(); | |
223 | } |