• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2019 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 <algorithm>
8 #include <boost/core/lightweight_test.hpp>
9 #include <boost/core/lightweight_test_trait.hpp>
10 #include <boost/histogram/accumulators/weighted_sum.hpp>
11 #include <boost/histogram/axis/integer.hpp>
12 #include <boost/histogram/detail/common_type.hpp>
13 #include <boost/histogram/detail/counting_streambuf.hpp>
14 #include <boost/histogram/detail/index_translator.hpp>
15 #include <boost/histogram/detail/nonmember_container_access.hpp>
16 #include <boost/histogram/detail/span.hpp>
17 #include <boost/histogram/detail/sub_array.hpp>
18 #include <boost/histogram/fwd.hpp>
19 #include <boost/histogram/literals.hpp>
20 #include <boost/histogram/storage_adaptor.hpp>
21 #include <boost/histogram/unlimited_storage.hpp>
22 #include <iostream>
23 #include <ostream>
24 #include "std_ostream.hpp"
25 #include "throw_exception.hpp"
26 
27 namespace boost {
28 namespace histogram {
29 template <std::size_t N>
operator <<(std::ostream & os,const multi_index<N> & mi)30 std::ostream& operator<<(std::ostream& os, const multi_index<N>& mi) {
31   os << "(";
32   bool first = true;
33   for (auto&& x : mi) {
34     if (!first)
35       os << " ";
36     else
37       first = false;
38     os << x << ", ";
39   }
40   os << ")";
41   return os;
42 }
43 
44 template <std::size_t N, std::size_t M>
operator ==(const multi_index<N> & a,const multi_index<M> & b)45 bool operator==(const multi_index<N>& a, const multi_index<M>& b) {
46   return std::equal(a.begin(), a.end(), b.begin(), b.end());
47 }
48 } // namespace histogram
49 } // namespace boost
50 
51 using namespace boost::histogram;
52 using namespace boost::histogram::literals;
53 namespace dtl = boost::histogram::detail;
54 
main()55 int main() {
56   // literals
57   {
58     BOOST_TEST_TRAIT_SAME(std::integral_constant<unsigned, 0>, decltype(0_c));
59     BOOST_TEST_TRAIT_SAME(std::integral_constant<unsigned, 3>, decltype(3_c));
60     BOOST_TEST_EQ(decltype(10_c)::value, 10);
61     BOOST_TEST_EQ(decltype(213_c)::value, 213);
62   }
63 
64   // common_storage
65   {
66     BOOST_TEST_TRAIT_SAME(dtl::common_storage<unlimited_storage<>, unlimited_storage<>>,
67                           unlimited_storage<>);
68     BOOST_TEST_TRAIT_SAME(
69         dtl::common_storage<dense_storage<double>, dense_storage<double>>,
70         dense_storage<double>);
71     BOOST_TEST_TRAIT_SAME(dtl::common_storage<dense_storage<int>, dense_storage<double>>,
72                           dense_storage<double>);
73     BOOST_TEST_TRAIT_SAME(dtl::common_storage<dense_storage<double>, dense_storage<int>>,
74                           dense_storage<double>);
75     BOOST_TEST_TRAIT_SAME(dtl::common_storage<dense_storage<double>, unlimited_storage<>>,
76                           dense_storage<double>);
77     BOOST_TEST_TRAIT_SAME(dtl::common_storage<dense_storage<int>, unlimited_storage<>>,
78                           unlimited_storage<>);
79     BOOST_TEST_TRAIT_SAME(dtl::common_storage<dense_storage<double>, weight_storage>,
80                           weight_storage);
81   }
82 
83   // size & data
84   {
85     char a[4] = {1, 2, 3, 4};
86     BOOST_TEST_EQ(dtl::size(a), 4u);
87     BOOST_TEST_EQ(dtl::data(a), a);
88     auto b = {1, 2};
89     BOOST_TEST_EQ(dtl::size(b), 2u);
90     BOOST_TEST_EQ(dtl::data(b), b.begin());
91     struct C {
92       unsigned size() const { return 3; }
93       int* data() { return buf; }
94       const int* data() const { return buf; }
95       int buf[1];
96     } c;
97     BOOST_TEST_EQ(dtl::size(c), 3u);
98     BOOST_TEST_EQ(dtl::data(c), c.buf);
99     BOOST_TEST_EQ(dtl::data(static_cast<const C&>(c)), c.buf);
100     struct {
101       int size() const { return 5; }
102     } d;
103     BOOST_TEST_EQ(dtl::size(d), 5u);
104   }
105 
106   // counting_streambuf
107   {
108     std::streamsize count = 0;
109     dtl::counting_streambuf<char> csb(count);
110     std::ostream os(&csb);
111     os.put('x');
112     BOOST_TEST_EQ(count, 1);
113     os << 12;
114     BOOST_TEST_EQ(count, 3);
115     os << "123";
116     BOOST_TEST_EQ(count, 6);
117   }
118   {
119     std::streamsize count = 0;
120     auto g = dtl::make_count_guard(std::cout, count);
121     std::cout.put('x');
122     BOOST_TEST_EQ(count, 1);
123     std::cout << 12;
124     BOOST_TEST_EQ(count, 3);
125     std::cout << "123";
126     BOOST_TEST_EQ(count, 6);
127   }
128 
129   // sub_array and span
130   {
131     dtl::sub_array<int, 2> a(2, 1);
132     a[1] = 2;
133     auto sp = dtl::span<int>(a);
134     BOOST_TEST_EQ(sp.size(), 2);
135     BOOST_TEST_EQ(sp.front(), 1);
136     BOOST_TEST_EQ(sp.back(), 2);
137 
138     const auto& ca = a;
139     auto csp = dtl::span<const int>(ca);
140     BOOST_TEST_EQ(csp.size(), 2);
141     BOOST_TEST_EQ(csp.front(), 1);
142     BOOST_TEST_EQ(csp.back(), 2);
143   }
144 
145   // index_translator
146   {
147     using I = axis::integer<>;
148 
149     {
150       auto t = std::vector<I>{I{0, 1}, I{1, 3}};
151       auto tr = dtl::make_index_translator(t, t);
152       multi_index<static_cast<std::size_t>(-1)> mi{0, 1};
153       BOOST_TEST_EQ(tr(mi), mi);
154       multi_index<2> mi2{0, 1};
155       BOOST_TEST_EQ(tr(mi2), mi);
156     }
157 
158     {
159       auto t = std::make_tuple(I{0, 1});
160       auto tr = dtl::make_index_translator(t, t);
161       multi_index<static_cast<std::size_t>(-1)> mi{0};
162       BOOST_TEST_EQ(tr(mi), mi);
163     }
164 
165     BOOST_TEST_THROWS(multi_index<1>::create(2), std::invalid_argument);
166   }
167 
168   return boost::report_errors();
169 }
170