File indexing completed on 2026-08-16 09:21:12
0001
0002
0003
0004
0005 #ifndef ROOT_RBinIndexMultiDimRange
0006 #define ROOT_RBinIndexMultiDimRange
0007
0008 #include "RBinIndex.hxx"
0009 #include "RBinIndexRange.hxx"
0010
0011 #include <cassert>
0012 #include <cstddef>
0013 #include <cstdint>
0014 #include <iterator>
0015 #include <utility>
0016 #include <vector>
0017
0018 namespace ROOT {
0019 namespace Experimental {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 class RBinIndexMultiDimRange final {
0030
0031 std::vector<RBinIndexRange> fRanges;
0032
0033 bool fHasEmptyRange = false;
0034
0035 public:
0036
0037 RBinIndexMultiDimRange() = default;
0038
0039 RBinIndexMultiDimRange(std::vector<RBinIndexRange> ranges) : fRanges(std::move(ranges))
0040 {
0041 for (auto &&range : fRanges) {
0042 if (range.GetBegin() == range.GetEnd()) {
0043 fHasEmptyRange = true;
0044 }
0045 }
0046 }
0047
0048 const std::vector<RBinIndexRange> &GetRanges() const { return fRanges; }
0049
0050 friend bool operator==(const RBinIndexMultiDimRange &lhs, const RBinIndexMultiDimRange &rhs)
0051 {
0052 return lhs.fRanges == rhs.fRanges;
0053 }
0054
0055 friend bool operator!=(const RBinIndexMultiDimRange &lhs, const RBinIndexMultiDimRange &rhs)
0056 {
0057 return !(lhs == rhs);
0058 }
0059
0060
0061 class RIterator final {
0062 friend class RBinIndexMultiDimRange;
0063
0064
0065 std::vector<RBinIndexRange::RIterator> fIterators;
0066
0067 std::vector<RBinIndex> fIndices;
0068
0069 const RBinIndexMultiDimRange *fMultiDimRange = nullptr;
0070
0071 RIterator(const RBinIndexMultiDimRange &multiDimRange) : fMultiDimRange(&multiDimRange) {}
0072
0073 public:
0074 using difference_type = std::ptrdiff_t;
0075 using value_type = std::vector<RBinIndex>;
0076 using pointer = const std::vector<RBinIndex> *;
0077 using reference = const std::vector<RBinIndex> &;
0078 using iterator_category = std::input_iterator_tag;
0079
0080 RIterator() = default;
0081
0082 RIterator &operator++()
0083 {
0084 const std::size_t N = fIterators.size();
0085 std::size_t j = 0;
0086 for (; j < N; j++) {
0087
0088 const std::size_t i = N - 1 - j;
0089
0090
0091
0092
0093 fIterators[i]++;
0094 fIndices[i] = *fIterators[i];
0095
0096 if (fIndices[i] != fMultiDimRange->fRanges[i].GetEnd()) {
0097 break;
0098 }
0099 }
0100
0101 if (j == N) {
0102
0103 fIterators.clear();
0104 } else {
0105
0106 for (std::size_t k = 0; k < j; k++) {
0107
0108 const std::size_t i = N - 1 - k;
0109 fIterators[i] = fMultiDimRange->fRanges[i].begin();
0110 fIndices[i] = *fIterators[i];
0111 }
0112 }
0113 return *this;
0114 }
0115 RIterator operator++(int)
0116 {
0117 RIterator old = *this;
0118 operator++();
0119 return old;
0120 }
0121
0122 const std::vector<RBinIndex> &operator*() const { return fIndices; }
0123 const std::vector<RBinIndex> *operator->() const { return &fIndices; }
0124
0125 friend bool operator==(const RIterator &lhs, const RIterator &rhs)
0126 {
0127 return lhs.fIterators == rhs.fIterators && lhs.fMultiDimRange == rhs.fMultiDimRange;
0128 }
0129 friend bool operator!=(const RIterator &lhs, const RIterator &rhs) { return !(lhs == rhs); }
0130 };
0131
0132 RIterator begin() const
0133 {
0134 RIterator it(*this);
0135
0136 if (fHasEmptyRange) {
0137 return it;
0138 }
0139
0140 for (auto &&range : fRanges) {
0141 it.fIterators.push_back(range.begin());
0142 it.fIndices.push_back(*it.fIterators.back());
0143 }
0144 return it;
0145 }
0146 RIterator end() const { return RIterator(*this); }
0147 };
0148
0149 }
0150 }
0151
0152 #endif