Logo ROOT   6.18/05
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
24A pseudo container class which is a generator of indices. The model is the `xrange`
25built-in function of Python.
26Possible usages:
27Loop on a sequence of integers
28~~~{.cpp}
29 for (auto i : TSeqI(10)) {
30 cout << "Element " << i << endl;
31 }
32~~~
33Loop on a sequence of integers in steps
34~~~{.cpp}
35 for (auto i : TSeqI(-5, 29, 6)) {
36 cout << "Element " << i << endl;
37 }
38~~~
39Loop backwards on a sequence of integers
40~~~{.cpp}
41 for (auto i : TSeqI(50, 30, -3)) {
42 cout << "Element " << i << endl;
43 }
44~~~
45Use 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~~~
50Random access:
51~~~{.cpp}
52 cout << "Random access: 3rd element is " << ulSeq[2] << endl;
53~~~
54A 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
63namespace 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
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
218namespace 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
SVector< double, 2 > v
Definition: Dict.h:5
int type
Definition: TGX11.cxx:120
iterator(T start, T step)
Definition: TSeq.hxx:91
bool operator>=(const iterator &other) const
Definition: TSeq.hxx:154
iterator operator-(difference_type v) const
Definition: TSeq.hxx:108
const T operator[](const difference_type &v) const
Definition: TSeq.hxx:158
iterator operator++(int)
Definition: TSeq.hxx:120
T operator*() const
Definition: TSeq.hxx:92
bool operator!=(const iterator &other) const
Definition: TSeq.hxx:100
bool operator>(const iterator &other) const
Definition: TSeq.hxx:148
iterator & operator-=(const difference_type &v)
Definition: TSeq.hxx:140
iterator & operator+=(const difference_type &v)
Definition: TSeq.hxx:136
iterator & operator++()
Definition: TSeq.hxx:116
difference_type operator-(const iterator &other) const
Definition: TSeq.hxx:112
bool operator==(const iterator &other) const
Definition: TSeq.hxx:96
bool operator<(const iterator &other) const
Definition: TSeq.hxx:145
iterator operator+(difference_type v) const
Definition: TSeq.hxx:104
bool operator<=(const iterator &other) const
Definition: TSeq.hxx:151
iterator & operator--()
Definition: TSeq.hxx:126
iterator operator--(int)
Definition: TSeq.hxx:130
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
const T fEnd
Definition: TSeq.hxx:72
typename std::make_signed< T >::type difference_type
Definition: TSeq.hxx:76
T value_type
Definition: TSeq.hxx:75
iterator begin() const
Definition: TSeq.hxx:163
const T fBegin
Definition: TSeq.hxx:71
bool empty() const
Definition: TSeq.hxx:188
T step() const
Definition: TSeq.hxx:184
T operator[](T s) const
Definition: TSeq.hxx:176
std::size_t size() const
Definition: TSeq.hxx:180
TSeq(T theEnd)
Definition: TSeq.hxx:78
T const & front() const
Definition: TSeq.hxx:172
iterator end() const
Definition: TSeq.hxx:166
void checkIntegralType()
Definition: TSeq.hxx:68
const T fStep
Definition: TSeq.hxx:73
TSeq(T theBegin, T theEnd, T theStep=1)
Definition: TSeq.hxx:81
double T(double x)
Definition: ChebyshevPol.h:34
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
TSeq< T > MakeSeq(T end)
Definition: TSeq.hxx:200
static constexpr double s