@@ -30,6 +30,19 @@ TEST(RVariableBinAxis, Constructor)
3030 EXPECT_THROW (RVariableBinAxis ({0 , 1 , 0 }), std::invalid_argument);
3131 EXPECT_THROW (RVariableBinAxis ({0 , 1 , 1 }), std::invalid_argument);
3232
33+ // Construction works with infinite bin edges (which make most sense with disabling builtin flow bins).
34+ static constexpr double NegativeInfinity = -std::numeric_limits<double >::infinity ();
35+ static constexpr double PositiveInfinity = std::numeric_limits<double >::infinity ();
36+ axis = RVariableBinAxis ({NegativeInfinity, 0 }, /* enableFlowBins=*/ false );
37+ axis = RVariableBinAxis ({NegativeInfinity, PositiveInfinity}, /* enableFlowBins=*/ false );
38+ axis = RVariableBinAxis ({0 , PositiveInfinity}, /* enableFlowBins=*/ false );
39+
40+ EXPECT_THROW (RVariableBinAxis ({NegativeInfinity, NegativeInfinity}), std::invalid_argument);
41+ EXPECT_THROW (RVariableBinAxis ({0 , NegativeInfinity}), std::invalid_argument);
42+ EXPECT_THROW (RVariableBinAxis ({PositiveInfinity, NegativeInfinity}), std::invalid_argument);
43+ EXPECT_THROW (RVariableBinAxis ({PositiveInfinity, 0 }), std::invalid_argument);
44+ EXPECT_THROW (RVariableBinAxis ({PositiveInfinity, PositiveInfinity}), std::invalid_argument);
45+
3346 static constexpr double NaN = std::numeric_limits<double >::quiet_NaN ();
3447 EXPECT_THROW (RVariableBinAxis ({NaN, 0 }), std::invalid_argument);
3548 EXPECT_THROW (RVariableBinAxis ({0 , NaN}), std::invalid_argument);
@@ -142,6 +155,40 @@ TEST(RVariableBinAxis, ComputeLinearizedIndex)
142155 }
143156}
144157
158+ TEST (RVariableBinAxis, ComputeLinearizedIndexInfinity)
159+ {
160+ static constexpr double NegativeInfinity = -std::numeric_limits<double >::infinity ();
161+ static constexpr double PositiveInfinity = std::numeric_limits<double >::infinity ();
162+ const RVariableBinAxis axis ({NegativeInfinity, 0 , 1 , PositiveInfinity}, /* enableFlowBins=*/ false );
163+
164+ auto linIndex = axis.ComputeLinearizedIndex (NegativeInfinity);
165+ EXPECT_EQ (linIndex.fIndex , 0 );
166+ EXPECT_TRUE (linIndex.fValid );
167+ linIndex = axis.ComputeLinearizedIndex (-100 );
168+ EXPECT_EQ (linIndex.fIndex , 0 );
169+ EXPECT_TRUE (linIndex.fValid );
170+ linIndex = axis.ComputeLinearizedIndex (0 );
171+ EXPECT_EQ (linIndex.fIndex , 1 );
172+ EXPECT_TRUE (linIndex.fValid );
173+ linIndex = axis.ComputeLinearizedIndex (0.5 );
174+ EXPECT_EQ (linIndex.fIndex , 1 );
175+ EXPECT_TRUE (linIndex.fValid );
176+ linIndex = axis.ComputeLinearizedIndex (1 );
177+ EXPECT_EQ (linIndex.fIndex , 2 );
178+ EXPECT_TRUE (linIndex.fValid );
179+ linIndex = axis.ComputeLinearizedIndex (100 );
180+ EXPECT_EQ (linIndex.fIndex , 2 );
181+ EXPECT_TRUE (linIndex.fValid );
182+ // The upper bin edges are exclusive, so positive infinity falls into the builtin overflow bin, which is disabled
183+ linIndex = axis.ComputeLinearizedIndex (PositiveInfinity);
184+ EXPECT_FALSE (linIndex.fValid );
185+
186+ // NaN will be silently discard because the builtin overflow bin is disabled
187+ static constexpr double NaN = std::numeric_limits<double >::quiet_NaN ();
188+ linIndex = axis.ComputeLinearizedIndex (NaN);
189+ EXPECT_FALSE (linIndex.fValid );
190+ }
191+
145192TEST (RVariableBinAxis, GetLinearizedIndex)
146193{
147194 static constexpr std::size_t Bins = 20 ;
0 commit comments