diff --git a/include/nix/Dimensions.hpp b/include/nix/Dimensions.hpp index 2e09f024a..eb4452bef 100644 --- a/include/nix/Dimensions.hpp +++ b/include/nix/Dimensions.hpp @@ -789,12 +789,18 @@ class NIXAPI RangeDimension : public base::ImplContainer * * @param start_positions Vector of start positions * @param end_positions Vector of end positions + * @param match Enum entry that defines whether the range is inclusive + * or exclusive regarding the end position + * @param strict Bool that indicates whether the function will throw an + * OutOfBounds exception when an invalid range occurred or + * if such ranges are silently ignored. Default is true. * * @return Vector of pairs of start and end indices. */ std::vector> indexOf(const std::vector &start_positions, const std::vector &end_positions, - RangeMatch match = RangeMatch::Inclusive) const; + RangeMatch match = RangeMatch::Inclusive, + bool strict = true) const; /** diff --git a/src/Dimensions.cpp b/src/Dimensions.cpp index 88e25a065..9acb1fea5 100644 --- a/src/Dimensions.cpp +++ b/src/Dimensions.cpp @@ -414,7 +414,7 @@ boost::optional getIndex(const double position, std::vector &t idx = 0; return idx; } else if (position > *prev(ticks.end())) { - if (matching == PositionMatch::Less || matching == PositionMatch::LessOrEqual) + if (matching == PositionMatch::Less || matching == PositionMatch::LessOrEqual) idx = prev(ticks.end()) - ticks.begin(); return idx; } @@ -467,10 +467,10 @@ boost::optional> RangeDimension::indexOf(double st if (start > end){ std::swap(start, end); } - + boost::optional si = getIndex(start, ticks, PositionMatch::GreaterOrEqual); if (!si) { - return range; + return range; } PositionMatch endMatching = (match == RangeMatch::Inclusive) ? PositionMatch::LessOrEqual : PositionMatch::Less; boost::optional ei = getIndex(end, ticks, endMatching); @@ -505,7 +505,7 @@ pair RangeDimension::indexOf(const double start, const doubl std::vector> RangeDimension::indexOf(const std::vector &start_positions, const std::vector &end_positions, - RangeMatch match) const { + RangeMatch match, bool strict) const { if (start_positions.size() != end_positions.size()) { throw runtime_error("Dimension::IndexOf - Number of start and end positions must match!"); } @@ -516,6 +516,9 @@ std::vector> RangeDimension::indexOf(const std::ve for (size_t i = 0; i < start_positions.size(); ++i) { boost::optional> range; range = this->indexOf(start_positions[i], end_positions[i], std::move(ticks), match); + if (!range && strict) { + throw nix::OutOfBounds("RangeDimension::indexOf an invalid range occurred!"); + } if (range) { indices.push_back(*range); } diff --git a/test/BaseTestDimension.cpp b/test/BaseTestDimension.cpp index abb517653..bc83be268 100644 --- a/test/BaseTestDimension.cpp +++ b/test/BaseTestDimension.cpp @@ -419,7 +419,7 @@ void BaseTestDimension::testRangeDimIndexOfOld() { CPPUNIT_ASSERT(rd.indexOf(-10.0) == 1); CPPUNIT_ASSERT(rd.indexOf(-5.0) == 1); CPPUNIT_ASSERT(rd.indexOf(5.0) == 2); - + CPPUNIT_ASSERT_NO_THROW(rd.indexOf(257.28)); CPPUNIT_ASSERT_THROW(rd.indexOf(257.28, false), nix::OutOfBounds); CPPUNIT_ASSERT_THROW(rd.indexOf(-257.28), nix::OutOfBounds); @@ -431,7 +431,7 @@ void BaseTestDimension::testRangeDimIndexOfOld() { CPPUNIT_ASSERT(range.first == 0 && range.second == 4); range = rd.indexOf(-200., 200.); CPPUNIT_ASSERT(range.first == 0 && range.second == 4); - + CPPUNIT_ASSERT_THROW(rd.indexOf({-100.0, -90, 0.0}, {10.}), std::runtime_error); CPPUNIT_ASSERT_NO_THROW(rd.indexOf({-100.0, 20.0, 40.0}, {-45, 120., 100.})); CPPUNIT_ASSERT(rd.indexOf({-100.0, 20.0, 40.0}, {-45, 120., 100.}).size() == 3); @@ -453,13 +453,13 @@ void BaseTestDimension::testRangeDimIndexOf() { CPPUNIT_ASSERT(!rd.indexOf(-110., PositionMatch::LessOrEqual)); CPPUNIT_ASSERT(!rd.indexOf(-110., PositionMatch::Less)); CPPUNIT_ASSERT(!rd.indexOf(-110., PositionMatch::Equal)); - + CPPUNIT_ASSERT(*rd.indexOf(-100., PositionMatch::GreaterOrEqual) == 0); CPPUNIT_ASSERT(*rd.indexOf(-100., PositionMatch::Greater) == 1); CPPUNIT_ASSERT(*rd.indexOf(-100., PositionMatch::LessOrEqual) == 0); CPPUNIT_ASSERT(!rd.indexOf(-100., PositionMatch::Less)); CPPUNIT_ASSERT(*rd.indexOf(-100., PositionMatch::Equal) == 0); - + CPPUNIT_ASSERT(*rd.indexOf(-50., PositionMatch::GreaterOrEqual) == 1); CPPUNIT_ASSERT(*rd.indexOf(-50., PositionMatch::Greater) == 1); CPPUNIT_ASSERT(*rd.indexOf(-50., PositionMatch::LessOrEqual) == 0); @@ -517,7 +517,8 @@ void BaseTestDimension::testRangeDimIndexOf() { CPPUNIT_ASSERT(ranges[0].first == 4 && ranges[0].second == 4); CPPUNIT_ASSERT(ranges[1].first == 0 && ranges[1].second == 4); - ranges = rd.indexOf({40., -100., -100.}, {100., 100., 101.}, RangeMatch::Exclusive); + CPPUNIT_ASSERT_THROW(rd.indexOf({40., -100., -100.}, {100., 100., 101.}, RangeMatch::Exclusive), nix::OutOfBounds); + ranges = rd.indexOf({40., -100., -100.}, {100., 100., 101.}, RangeMatch::Exclusive, false); CPPUNIT_ASSERT(ranges.size() == 2); CPPUNIT_ASSERT(ranges[0].first == 0 && ranges[0].second == 3); CPPUNIT_ASSERT(ranges[1].first == 0 && ranges[1].second == 4);