Skip to content

Commit 4a215ce

Browse files
committed
[hist] Test user-defined bin content type
1 parent 41a4849 commit 4a215ce

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

hist/histv7/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ HIST_ADD_GTEST(hist_hist hist_hist.cxx)
44
HIST_ADD_GTEST(hist_index hist_index.cxx)
55
HIST_ADD_GTEST(hist_regular hist_regular.cxx)
66
HIST_ADD_GTEST(hist_stats hist_stats.cxx)
7+
HIST_ADD_GTEST(hist_user hist_user.cxx)
78
HIST_ADD_GTEST(hist_variable hist_variable.cxx)
89

910
if(NOT DEFINED histv7_standalone)

hist/histv7/test/hist_user.cxx

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "hist_test.hxx"
2+
3+
#include <type_traits>
4+
5+
// User-defined bin content type consisting of a single double, but can be much more complicated.
6+
struct User {
7+
double fValue = 0;
8+
9+
User &operator++()
10+
{
11+
fValue++;
12+
return *this;
13+
}
14+
15+
User operator++(int)
16+
{
17+
User old = *this;
18+
operator++();
19+
return old;
20+
}
21+
22+
User &operator+=(const User &rhs)
23+
{
24+
fValue += rhs.fValue;
25+
return *this;
26+
}
27+
};
28+
29+
static_assert(std::is_nothrow_move_constructible_v<RHistEngine<User>>);
30+
static_assert(std::is_nothrow_move_assignable_v<RHistEngine<User>>);
31+
32+
static_assert(std::is_nothrow_move_constructible_v<RHist<User>>);
33+
static_assert(std::is_nothrow_move_assignable_v<RHist<User>>);
34+
35+
TEST(RHistEngineUser, Add)
36+
{
37+
// Addition uses operator+=(const User &)
38+
static constexpr std::size_t Bins = 20;
39+
const RRegularAxis axis(Bins, {0, Bins});
40+
RHistEngine<User> engineA({axis});
41+
RHistEngine<User> engineB({axis});
42+
43+
engineA.Fill(8.5);
44+
engineB.Fill(9.5);
45+
46+
engineA.Add(engineB);
47+
48+
EXPECT_EQ(engineA.GetBinContent(RBinIndex(8)).fValue, 1);
49+
EXPECT_EQ(engineA.GetBinContent(RBinIndex(9)).fValue, 1);
50+
}
51+
52+
TEST(RHistEngineUser, Clear)
53+
{
54+
// Clearing assigns default-constructed objects.
55+
static constexpr std::size_t Bins = 20;
56+
const RRegularAxis axis(Bins, {0, Bins});
57+
RHistEngine<User> engine({axis});
58+
59+
engine.Fill(8.5);
60+
engine.Fill(9.5);
61+
62+
engine.Clear();
63+
64+
EXPECT_EQ(engine.GetBinContent(RBinIndex(8)).fValue, 0);
65+
EXPECT_EQ(engine.GetBinContent(RBinIndex(9)).fValue, 0);
66+
}
67+
68+
TEST(RHistEngineUser, Clone)
69+
{
70+
// Cloning copy-assigns the objects.
71+
static constexpr std::size_t Bins = 20;
72+
const RRegularAxis axis(Bins, {0, Bins});
73+
RHistEngine<User> engineA({axis});
74+
75+
engineA.Fill(8.5);
76+
77+
RHistEngine<User> engineB = engineA.Clone();
78+
EXPECT_EQ(engineB.GetBinContent(8).fValue, 1);
79+
80+
// Check that we can continue filling the clone.
81+
engineB.Fill(9.5);
82+
83+
EXPECT_EQ(engineA.GetBinContent(9).fValue, 0);
84+
EXPECT_EQ(engineB.GetBinContent(9).fValue, 1);
85+
}
86+
87+
TEST(RHistEngineUser, Fill)
88+
{
89+
// Unweighted filling uses operator++(int)
90+
static constexpr std::size_t Bins = 20;
91+
const RRegularAxis axis(Bins, {0, Bins});
92+
RHistEngine<User> engine({axis});
93+
94+
engine.Fill(8.5);
95+
engine.Fill(std::make_tuple(9.5));
96+
97+
EXPECT_EQ(engine.GetBinContent(RBinIndex(8)).fValue, 1);
98+
std::array<RBinIndex, 1> indices = {9};
99+
EXPECT_EQ(engine.GetBinContent(indices).fValue, 1);
100+
}

0 commit comments

Comments
 (0)