Logo ROOT   6.19/01
Reference Guide
TSeq.hxx
Go to the documentation of this file.
1 /* @(#)root/core/cont:$Id$ */
2 // Author: Danilo Piparo November 2015
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TSeq
13 #define ROOT_TSeq
14 
15 #include <iterator>
16 #include <type_traits>
17 
18 /**
19 \class ROOT::TSeq
20 \brief A pseudo container class which is a generator of indices.
21 
22 \tparam T Type of the numerical sequence.
23 \ingroup Containers
24 A pseudo container class which is a generator of indices. The model is the `xrange`
25 built-in function of Python.
26 Possible usages:
27 Loop on a sequence of integers
28 ~~~{.cpp}
29  for (auto i : TSeqI(10)) {
30  cout << "Element " << i << endl;
31  }
32 ~~~
33 Loop on a sequence of integers in steps
34 ~~~{.cpp}
35  for (auto i : TSeqI(-5, 29, 6)) {
36  cout << "Element " << i << endl;
37  }
38 ~~~
39 Loop backwards on a sequence of integers
40 ~~~{.cpp}
41  for (auto i : TSeqI(50, 30, -3)) {
42  cout << "Element " << i << endl;
43  }
44 ~~~
45 Use an stl algorithm, for_each
46 ~~~{.cpp}
47  TSeqUL ulSeq(2,30,3);
48  std::for_each(std::begin(ulSeq),std::end(ulSeq),[](ULong_t i){cout << "For each: " << i <<endl;});
49 ~~~
50 Random access:
51 ~~~{.cpp}
52  cout << "Random access: 3rd element is " << ulSeq[2] << endl;
53 ~~~
54 A function to create sequences inferring the type:
55 ~~~{.cpp}
56  for (auto i : MakeSeq(1000000000000UL, 1000000000003UL)) {
57  cout << "Element " << i << endl;
58  }
59 ~~~
60 
61 **/
62 
63 namespace ROOT {
64 
65  template<class T>
66  class TSeq {
67  private:
69  static_assert(std::is_integral<T>::value, "Only integral types are supported.");
70  }
71  const T fBegin;
72  const T fEnd;
73  const T fStep;
74  public:
75  using value_type = T;
77 
78  TSeq(T theEnd): fBegin(), fEnd(theEnd), fStep(1) {
80  }
81  TSeq(T theBegin, T theEnd, T theStep = 1):
82  fBegin(theBegin), fEnd(theEnd), fStep(theStep) {
84  }
85 
86  class iterator: public std::iterator<std::random_access_iterator_tag, T, difference_type> {
87  private:
90  public:
91  iterator(T start, T step): fCounter(start), fStep(step) {}
92  T operator*() const {
93  return fCounter;
94  }
95  // equality
96  bool operator==(const iterator &other) const {
97  return fCounter == other.fCounter;
98  }
99  // inequality
100  bool operator!=(const iterator &other) const {
101  return fCounter != other.fCounter;
102  }
103  // sum with integer
105  return iterator(fCounter + v * fStep, fStep);
106  }
107  // difference with integer
109  return iterator(fCounter - v * fStep, fStep);
110  }
111  // distance
112  difference_type operator-(const iterator &other) const {
113  return (fCounter - other.fCounter) / fStep;
114  }
115  // increments
117  fCounter += fStep;
118  return *this;
119  }
121  iterator tmp(*this);
122  operator++();
123  return tmp;
124  }
125  // decrements
127  fCounter -= fStep;
128  return *this;
129  }
131  iterator tmp(*this);
132  operator--();
133  return tmp;
134  }
135  // compound assignments
137  *this = *this + v;
138  return *this;
139  }
141  *this = *this - v;
142  return *this;
143  }
144  // comparison operators
145  bool operator <(const iterator &other) const {
146  return (other - *this) > 0;
147  }
148  bool operator >(const iterator &other) const {
149  return other < *this;
150  }
151  bool operator <=(const iterator &other) const {
152  return !(*this > other);
153  }
154  bool operator >=(const iterator &other) const {
155  return !(other > *this);
156  }
157  // subscript operator
158  const T operator[](const difference_type& v) const{
159  return *(*this + v);
160  }
161  };
162 
163  iterator begin() const {
164  return iterator(fBegin, fStep);
165  }
166  iterator end() const {
167  auto isStepMultiple = (fEnd - fBegin) % fStep == 0;
168  auto theEnd = isStepMultiple ? fEnd : fStep * (((fEnd - fBegin) / fStep) + 1) + fBegin;
169  return iterator(theEnd, fStep);
170  }
171 
172  T const &front() const {
173  return fBegin;
174  }
175 
176  T operator[](T s) const {
177  return s * fStep + fBegin;
178  }
179 
180  std::size_t size() const {
181  return end() - begin();
182  }
183 
184  T step() const {
185  return fStep;
186  }
187 
188  bool empty() const {
189  return fEnd == fBegin;
190  }
191 
192  };
193 
194  using TSeqI = TSeq<int>;
196  using TSeqL = TSeq<long>;
198 
199  template<class T>
201  {
202  return TSeq<T>(end);
203  }
204 
205  template<class T>
206  TSeq<T> MakeSeq(T begin, T end, T step = 1)
207  {
208  return TSeq<T>(begin, end, step);
209  }
210 
211 }
212 
213 #include <sstream>
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Print a TSeq at the prompt:
217 
218 namespace cling {
219  template<class T>
220  std::string printValue(ROOT::TSeq<T> *val)
221  {
222  std::ostringstream ret;
223  ret << "A sequence of values: " << *val->begin()
224  << " <= i < " << *val->end();
225  auto step = val->step();
226  if (1 != step)
227  ret << " in steps of " << step;
228  return ret.str();
229  }
230 }
231 
232 #endif
iterator operator++(int)
Definition: TSeq.hxx:120
bool empty() const
Definition: TSeq.hxx:188
T const & front() const
Definition: TSeq.hxx:172
T operator[](T s) const
Definition: TSeq.hxx:176
const T fStep
Definition: TSeq.hxx:73
iterator & operator-=(const difference_type &v)
Definition: TSeq.hxx:140
bool operator>(const iterator &other) const
Definition: TSeq.hxx:148
typename std::make_signed< T >::type difference_type
Definition: TSeq.hxx:76
VSD Structures.
Definition: StringConv.hxx:21
bool operator>=(const iterator &other) const
Definition: TSeq.hxx:154
iterator operator+(difference_type v) const
Definition: TSeq.hxx:104
bool operator<(const iterator &other) const
Definition: TSeq.hxx:145
T operator*() const
Definition: TSeq.hxx:92
double T(double x)
Definition: ChebyshevPol.h:34
std::size_t size() const
Definition: TSeq.hxx:180
bool operator<=(const iterator &other) const
Definition: TSeq.hxx:151
iterator & operator--()
Definition: TSeq.hxx:126
TSeq(T theBegin, T theEnd, T theStep=1)
Definition: TSeq.hxx:81
static constexpr double s
iterator operator--(int)
Definition: TSeq.hxx:130
iterator(T start, T step)
Definition: TSeq.hxx:91
TSeq< T > MakeSeq(T end)
Definition: TSeq.hxx:200
void checkIntegralType()
Definition: TSeq.hxx:68
bool operator!=(const iterator &other) const
Definition: TSeq.hxx:100
const T fEnd
Definition: TSeq.hxx:72
TSeq(T theEnd)
Definition: TSeq.hxx:78
iterator operator-(difference_type v) const
Definition: TSeq.hxx:108
T step() const
Definition: TSeq.hxx:184
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
int type
Definition: TGX11.cxx:120
Print a TSeq at the prompt:
Definition: TDatime.h:115
T value_type
Definition: TSeq.hxx:75
iterator end() const
Definition: TSeq.hxx:166
bool operator==(const iterator &other) const
Definition: TSeq.hxx:96
const T fBegin
Definition: TSeq.hxx:71
iterator & operator+=(const difference_type &v)
Definition: TSeq.hxx:136
const T operator[](const difference_type &v) const
Definition: TSeq.hxx:158
difference_type operator-(const iterator &other) const
Definition: TSeq.hxx:112
iterator begin() const
Definition: TSeq.hxx:163
iterator & operator++()
Definition: TSeq.hxx:116