Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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;
76 using difference_type = typename std::make_signed<T>::type;
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 {
87 private:
90 public:
91 using iterator_category = std::random_access_iterator_tag;
92 using value_type = T;
93 using difference_type = typename std::make_signed<T>::type;
94 using pointer = T *;
95 using const_pointer = const T *;
96 using reference = T &;
97
98 iterator(T start, T step): fCounter(start), fStep(step) {}
99 T operator*() const {
100 return fCounter;
101 }
102 // equality
103 bool operator==(const iterator &other) const {
104 return fCounter == other.fCounter;
105 }
106 // inequality
107 bool operator!=(const iterator &other) const {
108 return fCounter != other.fCounter;
109 }
110 // sum with integer
112 return iterator(fCounter + v * fStep, fStep);
113 }
114 // difference with integer
116 return iterator(fCounter - v * fStep, fStep);
117 }
118 // distance
119 difference_type operator-(const iterator &other) const {
120 return (fCounter - other.fCounter) / fStep;
121 }
122 // increments
124 fCounter += fStep;
125 return *this;
126 }
128 iterator tmp(*this);
129 operator++();
130 return tmp;
131 }
132 // decrements
134 fCounter -= fStep;
135 return *this;
136 }
138 iterator tmp(*this);
139 operator--();
140 return tmp;
141 }
142 // compound assignments
144 *this = *this + v;
145 return *this;
146 }
148 *this = *this - v;
149 return *this;
150 }
151 // comparison operators
152 bool operator <(const iterator &other) const {
153 return (other - *this) > 0;
154 }
155 bool operator >(const iterator &other) const {
156 return other < *this;
157 }
158 bool operator <=(const iterator &other) const {
159 return !(*this > other);
160 }
161 bool operator >=(const iterator &other) const {
162 return !(other > *this);
163 }
164 // subscript operator
165 const T operator[](const difference_type& v) const{
166 return *(*this + v);
167 }
168 };
169
170 iterator begin() const {
171 return iterator(fBegin, fStep);
172 }
173 iterator end() const {
174 auto isStepMultiple = (fEnd - fBegin) % fStep == 0;
175 auto theEnd = isStepMultiple ? fEnd : fStep * (((fEnd - fBegin) / fStep) + 1) + fBegin;
176 return iterator(theEnd, fStep);
177 }
178
179 T const &front() const {
180 return fBegin;
181 }
182
183 T operator[](T s) const {
184 return s * fStep + fBegin;
185 }
186
187 std::size_t size() const {
188 return end() - begin();
189 }
190
191 T step() const {
192 return fStep;
193 }
194
195 bool empty() const {
196 return fEnd == fBegin;
197 }
198
199 };
200
205
206 template<class T>
208 {
209 return TSeq<T>(end);
210 }
211
212 template<class T>
213 TSeq<T> MakeSeq(T begin, T end, T step = 1)
214 {
215 return TSeq<T>(begin, end, step);
216 }
217
218}
219
220#include <sstream>
221
222////////////////////////////////////////////////////////////////////////////////
223/// Print a TSeq at the prompt:
224
225namespace cling {
226 template<class T>
227 std::string printValue(ROOT::TSeq<T> *val)
228 {
229 std::ostringstream ret;
230 ret << "A sequence of values: " << *val->begin()
231 << " <= i < " << *val->end();
232 auto step = val->step();
233 if (1 != step)
234 ret << " in steps of " << step;
235 return ret.str();
236 }
237}
238
239#endif
typename std::make_signed< T >::type difference_type
Definition TSeq.hxx:93
std::random_access_iterator_tag iterator_category
Definition TSeq.hxx:91
iterator(T start, T step)
Definition TSeq.hxx:98
bool operator>=(const iterator &other) const
Definition TSeq.hxx:161
iterator operator-(difference_type v) const
Definition TSeq.hxx:115
const T operator[](const difference_type &v) const
Definition TSeq.hxx:165
const T * const_pointer
Definition TSeq.hxx:95
iterator operator++(int)
Definition TSeq.hxx:127
T operator*() const
Definition TSeq.hxx:99
bool operator!=(const iterator &other) const
Definition TSeq.hxx:107
bool operator>(const iterator &other) const
Definition TSeq.hxx:155
iterator & operator-=(const difference_type &v)
Definition TSeq.hxx:147
iterator & operator+=(const difference_type &v)
Definition TSeq.hxx:143
iterator & operator++()
Definition TSeq.hxx:123
difference_type operator-(const iterator &other) const
Definition TSeq.hxx:119
bool operator==(const iterator &other) const
Definition TSeq.hxx:103
bool operator<(const iterator &other) const
Definition TSeq.hxx:152
iterator operator+(difference_type v) const
Definition TSeq.hxx:111
bool operator<=(const iterator &other) const
Definition TSeq.hxx:158
iterator & operator--()
Definition TSeq.hxx:133
iterator operator--(int)
Definition TSeq.hxx:137
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:170
const T fBegin
Definition TSeq.hxx:71
bool empty() const
Definition TSeq.hxx:195
T step() const
Definition TSeq.hxx:191
T operator[](T s) const
Definition TSeq.hxx:183
std::size_t size() const
Definition TSeq.hxx:187
TSeq(T theEnd)
Definition TSeq.hxx:78
T const & front() const
Definition TSeq.hxx:179
iterator end() const
Definition TSeq.hxx:173
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
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
TSeq< T > MakeSeq(T end)
Definition TSeq.hxx:207