File indexing completed on 2025-01-18 10:10:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef ROOT_TSeq
0013 #define ROOT_TSeq
0014
0015 #include "TError.h"
0016 #include <iterator>
0017 #include <type_traits>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 namespace ROOT {
0065
0066 template<class T>
0067 class TSeq {
0068 private:
0069 void checkIntegralType() {
0070 static_assert(std::is_integral<T>::value, "Only integral types are supported.");
0071 }
0072 const T fBegin;
0073 const T fEnd;
0074 const T fStep;
0075 public:
0076 using value_type = T;
0077 using difference_type = typename std::make_signed<T>::type;
0078
0079 TSeq(T theEnd): fBegin(), fEnd(theEnd), fStep(1) {
0080 checkIntegralType();
0081 }
0082 TSeq(T theBegin, T theEnd, T theStep = 1):
0083 fBegin(theBegin), fEnd(theEnd), fStep(theStep) {
0084 checkIntegralType();
0085 R__ASSERT(fStep != 0 && "TSeq does not support steps of size 0.");
0086 }
0087
0088 class iterator {
0089 private:
0090 T fCounter;
0091 T fStep;
0092 public:
0093 using iterator_category = std::random_access_iterator_tag;
0094 using value_type = T;
0095 using difference_type = typename std::make_signed<T>::type;
0096 using pointer = T *;
0097 using const_pointer = const T *;
0098 using reference = T &;
0099
0100 iterator(T start, T step): fCounter(start), fStep(step) {}
0101 T operator*() const {
0102 return fCounter;
0103 }
0104
0105 bool operator==(const iterator &other) const {
0106 return fCounter == other.fCounter;
0107 }
0108
0109 bool operator!=(const iterator &other) const {
0110 return fCounter != other.fCounter;
0111 }
0112
0113 iterator operator+(difference_type v) const {
0114 return iterator(fCounter + v * fStep, fStep);
0115 }
0116
0117 iterator operator-(difference_type v) const {
0118 return iterator(fCounter - v * fStep, fStep);
0119 }
0120
0121 difference_type operator-(const iterator &other) const {
0122 return (fCounter - other.fCounter) / fStep;
0123 }
0124
0125 iterator &operator++() {
0126 fCounter += fStep;
0127 return *this;
0128 }
0129 iterator operator++(int) {
0130 iterator tmp(*this);
0131 operator++();
0132 return tmp;
0133 }
0134
0135 iterator &operator--() {
0136 fCounter -= fStep;
0137 return *this;
0138 }
0139 iterator operator--(int) {
0140 iterator tmp(*this);
0141 operator--();
0142 return tmp;
0143 }
0144
0145 iterator &operator+=(const difference_type& v) {
0146 *this = *this + v;
0147 return *this;
0148 }
0149 iterator &operator-=(const difference_type& v) {
0150 *this = *this - v;
0151 return *this;
0152 }
0153
0154 bool operator <(const iterator &other) const {
0155 return (other - *this) > 0;
0156 }
0157 bool operator >(const iterator &other) const {
0158 return other < *this;
0159 }
0160 bool operator <=(const iterator &other) const {
0161 return !(*this > other);
0162 }
0163 bool operator >=(const iterator &other) const {
0164 return !(other > *this);
0165 }
0166
0167 const T operator[](const difference_type& v) const{
0168 return *(*this + v);
0169 }
0170 };
0171
0172 iterator begin() const {
0173 return iterator(fBegin, fStep);
0174 }
0175 iterator end() const {
0176 auto isStepMultiple = (fEnd - fBegin) % fStep == 0;
0177 auto theEnd = isStepMultiple ? fEnd : fStep * (((fEnd - fBegin) / fStep) + 1) + fBegin;
0178 return iterator(theEnd, fStep);
0179 }
0180
0181 T const &front() const {
0182 return fBegin;
0183 }
0184
0185 T operator[](T s) const {
0186 return s * fStep + fBegin;
0187 }
0188
0189 std::size_t size() const {
0190 return end() - begin();
0191 }
0192
0193 T step() const {
0194 return fStep;
0195 }
0196
0197 bool empty() const {
0198 return fEnd == fBegin;
0199 }
0200
0201 };
0202
0203 using TSeqI = TSeq<int>;
0204 using TSeqU = TSeq<unsigned int>;
0205 using TSeqL = TSeq<long>;
0206 using TSeqUL = TSeq<unsigned long>;
0207
0208 template<class T>
0209 TSeq<T> MakeSeq(T end)
0210 {
0211 return TSeq<T>(end);
0212 }
0213
0214 template<class T>
0215 TSeq<T> MakeSeq(T begin, T end, T step = 1)
0216 {
0217 return TSeq<T>(begin, end, step);
0218 }
0219
0220 }
0221
0222 #include <sstream>
0223
0224
0225
0226
0227 namespace cling {
0228 template<class T>
0229 std::string printValue(ROOT::TSeq<T> *val)
0230 {
0231 std::ostringstream ret;
0232 auto step = val->step();
0233 ret << "A sequence of values: " << *val->begin() << ((step > 0) ? " <= i < " : " >= i > ") << *val->end();
0234 if (1 != step)
0235 ret << " in steps of " << step;
0236 return ret.str();
0237 }
0238 }
0239
0240 #endif