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/lightweight_test.hpp>
8 #include <boost/core/lightweight_test_trait.hpp>
9 #include <boost/histogram/axis/category.hpp>
10 #include <boost/histogram/axis/ostream.hpp>
11 #include <boost/histogram/axis/traits.hpp>
15 #include <type_traits>
16 #include "std_ostream.hpp"
17 #include "throw_exception.hpp"
18 #include "utility_axis.hpp"
19 #include "utility_str.hpp"
22 using namespace boost::histogram
;
24 BOOST_TEST(std::is_nothrow_move_constructible
<axis::category
<int>>::value
);
25 BOOST_TEST(std::is_nothrow_move_constructible
<axis::category
<std::string
>>::value
);
26 BOOST_TEST(std::is_nothrow_move_assignable
<axis::category
<int>>::value
);
27 BOOST_TEST(std::is_nothrow_move_assignable
<axis::category
<std::string
>>::value
);
33 BOOST_TEST_THROWS(axis::category
<int>(x
+ 1, x
), std::invalid_argument
);
36 // value should return copy for arithmetic types and const reference otherwise
38 enum class Foo
{ foo
};
40 BOOST_TEST_TRAIT_SAME(axis::traits::value_type
<axis::category
<std::string
>>,
42 BOOST_TEST_TRAIT_SAME(decltype(std::declval
<axis::category
<std::string
>>().value(0)),
44 BOOST_TEST_TRAIT_SAME(axis::traits::value_type
<axis::category
<const char*>>,
46 BOOST_TEST_TRAIT_SAME(decltype(std::declval
<axis::category
<const char*>>().value(0)),
48 BOOST_TEST_TRAIT_SAME(axis::traits::value_type
<axis::category
<Foo
>>, Foo
);
49 BOOST_TEST_TRAIT_SAME(decltype(std::declval
<axis::category
<Foo
>>().value(0)), Foo
);
50 BOOST_TEST_TRAIT_SAME(axis::traits::value_type
<axis::category
<int>>, int);
51 BOOST_TEST_TRAIT_SAME(decltype(std::declval
<axis::category
<int>>().value(0)), int);
54 // empty axis::category
56 axis::category
<int> a
;
57 axis::category
<int> b(std::vector
<int>(0));
59 BOOST_TEST_EQ(a
.size(), 0);
60 BOOST_TEST_EQ(a
.index(-1), 0);
61 BOOST_TEST_EQ(a
.index(0), 0);
62 BOOST_TEST_EQ(a
.index(1), 0);
67 std::string
A("A"), B("B"), C("C"), other
;
69 axis::category
<std::string
> a({A
, B
, C
}, "foo");
70 BOOST_TEST_EQ(a
.metadata(), "foo");
71 BOOST_TEST_EQ(static_cast<const axis::category
<std::string
>&>(a
).metadata(), "foo");
73 BOOST_TEST_EQ(static_cast<const axis::category
<std::string
>&>(a
).metadata(), "bar");
74 BOOST_TEST_EQ(a
.size(), 3);
75 BOOST_TEST_EQ(a
.index(A
), 0);
76 BOOST_TEST_EQ(a
.index(B
), 1);
77 BOOST_TEST_EQ(a
.index(C
), 2);
78 BOOST_TEST_EQ(a
.index(other
), 3);
79 BOOST_TEST_EQ(a
.value(0), A
);
80 BOOST_TEST_EQ(a
.value(1), B
);
81 BOOST_TEST_EQ(a
.value(2), C
);
82 BOOST_TEST_THROWS(a
.value(3), std::out_of_range
);
86 "category(\"A\", \"B\", \"C\", metadata=\"bar\", options=overflow)");
89 // category<int, axis::null_type>: copy, move
91 using C
= axis::category
<int, axis::null_type
>;
111 // category<std::string>: copy, move
113 using C
= axis::category
<std::string
>;
115 C
a({"A", "B", "C"}, "foo");
117 BOOST_TEST_EQ(a2
, a
);
122 b
= C
{{"B", "A", "C"}};
134 // axis::category with growth
136 using pii_t
= std::pair
<axis::index_type
, axis::index_type
>;
137 axis::category
<int, axis::null_type
, axis::option::growth_t
> a
;
138 BOOST_TEST_EQ(a
.size(), 0);
139 BOOST_TEST_EQ(a
.update(5), pii_t(0, -1));
140 BOOST_TEST_EQ(a
.size(), 1);
141 BOOST_TEST_EQ(a
.update(1), pii_t(1, -1));
142 BOOST_TEST_EQ(a
.size(), 2);
143 BOOST_TEST_EQ(a
.update(10), pii_t(2, -1));
144 BOOST_TEST_EQ(a
.size(), 3);
145 BOOST_TEST_EQ(a
.update(10), pii_t(2, 0));
146 BOOST_TEST_EQ(a
.size(), 3);
148 BOOST_TEST_EQ(str(a
), "category(5, 1, 10, options=growth)");
153 test_axis_iterator(axis::category
<>({3, 1, 2}, ""), 0, 3);
154 test_axis_iterator(axis::category
<std::string
>({"A", "B"}, ""), 0, 2);
157 return boost::report_errors();