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 "TError.h"
16#include <iterator>
17#include <type_traits>
18
19/**
20\class ROOT::TSeq
21\brief A pseudo container class which is a generator of indices.
22
23\tparam T Type of the numerical sequence.
24\ingroup Containers
25A pseudo container class which is a generator of indices. The model is the `xrange`
26built-in function of Python.
27Possible usages:
28Loop on a sequence of integers
29~~~{.cpp}
30 for (auto i : TSeqI(10)) {
31 cout << "Element " << i << endl;
32 }
33~~~
34Loop on a sequence of integers in steps
35~~~{.cpp}
36 for (auto i : TSeqI(-5, 29, 6)) {
37 cout << "Element " << i << endl;
38 }
39~~~
40Loop backwards on a sequence of integers
41~~~{.cpp}
42 for (auto i : TSeqI(50, 30, -3)) {
43 cout << "Element " << i << endl;
44 }
45~~~
46Use an stl algorithm, for_each
47~~~{.cpp}
48 TSeqUL ulSeq(2,30,3);
49 std::for_each(std::begin(ulSeq),std::end(ulSeq),[](ULong_t i){cout << "For each: " << i <<endl;});
50~~~
51Random access:
52~~~{.cpp}
53 cout << "Random access: 3rd element is " << ulSeq[2] << endl;
54~~~
55A function to create sequences inferring the type:
56~~~{.cpp}
57 for (auto i : MakeSeq(1000000000000UL, 1000000000003UL)) {
58 cout << "Element " << i << endl;
59 }
60~~~
61
62**/
63
64namespace ROOT {
65
66 template<class T>
67 class TSeq {
68 private:
70 static_assert(std::is_integral<T>::value, "Only integral types are supported.");
71 }
72 const T fBegin;
73 const T fEnd;
74 const T fStep;
75 public:
76 using value_type = T;
77 using difference_type = typename std::make_signed<T>::type;
78
79 TSeq(T theEnd): fBegin(), fEnd(theEnd), fStep(1) {
81 }
82 TSeq(T theBegin, T theEnd, T theStep = 1):
83 fBegin(theBegin), fEnd(theEnd), fStep(theStep) {
85 R__ASSERT(fStep != 0 && "TSeq does not support steps of size 0.");
86 }
87
88 class iterator {
89 private:
92 public:
93 using iterator_category = std::random_access_iterator_tag;
94 using value_type = T;
95 using difference_type = typename std::make_signed<T>::type;
96 using pointer = T *;
97 using const_pointer = const T *;
98 using reference = T &;
99
100 iterator(T start, T step): fCounter(start), fStep(step) {}
101 T operator*() const {
102 return fCounter;
103 }
104 // equality
105 bool operator==(const iterator &other) const {
106 return fCounter == other.fCounter;
107 }
108 // inequality
109 bool operator!=(const iterator &other) const {
110 return fCounter != other.fCounter;
111 }
112 // sum with integer
114 return iterator(fCounter + v * fStep, fStep);
115 }
116 // difference with integer
118 return iterator(fCounter - v * fStep, fStep);
119 }
120 // distance
121 difference_type operator-(const iterator &other) const {
122 return (fCounter - other.fCounter) / fStep;
123 }
124 // increments
126 fCounter += fStep;
127 return *this;
128 }
130 iterator tmp(*this);
131 operator++();
132 return tmp;
133 }
134 // decrements
136 fCounter -= fStep;
137 return *this;
138 }
140 iterator tmp(*this);
141 operator--();
142 return tmp;
143 }
144 // compound assignments
146 *this = *this + v;
147 return *this;
148 }
150 *this = *this - v;
151 return *this;
152 }
153 // comparison operators
154 bool operator <(const iterator &other) const {
155 return (other - *this) > 0;
156 }
157 bool operator >(const iterator &other) const {
158 return other < *this;
159 }
160 bool operator <=(const iterator &other) const {
161 return !(*this > other);
162 }
163 bool operator >=(const iterator &other) const {
164 return !(other > *this);
165 }
166 // subscript operator
167 const T operator[](const difference_type& v) const{
168 return *(*this + v);
169 }
170 };
171
172 iterator begin() const {
173 return iterator(fBegin, fStep);
174 }
175 iterator end() const {
176 auto isStepMultiple = (fEnd - fBegin) % fStep == 0;
177 auto theEnd = isStepMultiple ? fEnd : fStep * (((fEnd - fBegin) / fStep) + 1) + fBegin;
178 return iterator(theEnd, fStep);
179 }
180
181 T const &front() const {
182 return fBegin;
183 }
184
185 T operator[](T s) const {
186 return s * fStep + fBegin;
187 }
188
189 std::size_t size() const {
190 return end() - begin();
191 }
192
193 T step() const {
194 return fStep;
195 }
196
197 bool empty() const {
198 return fEnd == fBegin;
199 }
200
201 };
202
207
208 template<class T>
210 {
211 return TSeq<T>(end);
212 }
213
214 template<class T>
215 TSeq<T> MakeSeq(T begin, T end, T step = 1)
216 {
217 return TSeq<T>(begin, end, step);
218 }
219
220}
221
222#include <sstream>
223
224////////////////////////////////////////////////////////////////////////////////
225/// Print a TSeq at the prompt:
226
227namespace cling {
228 template<class T>
229 std::string printValue(ROOT::TSeq<T> *val)
230 {
231 std::ostringstream ret;
232 auto step = val->step();
233 ret << "A sequence of values: " << *val->begin() << ((step > 0) ? " <= i < " : " >= i > ") << *val->end();
234 if (1 != step)
235 ret << " in steps of " << step;
236 return ret.str();
237 }
238}
239
240#endif
#define R__ASSERT(e)
Definition TError.h:118
typename std::make_signed< T >::type difference_type
Definition TSeq.hxx:95
std::random_access_iterator_tag iterator_category
Definition TSeq.hxx:93
iterator(T start, T step)
Definition TSeq.hxx:100
bool operator>=(const iterator &other) const
Definition TSeq.hxx:163
iterator operator-(difference_type v) const
Definition TSeq.hxx:117
const T operator[](const difference_type &v) const
Definition TSeq.hxx:167
const T * const_pointer
Definition TSeq.hxx:97
iterator operator++(int)
Definition TSeq.hxx:129
T operator*() const
Definition TSeq.hxx:101
bool operator!=(const iterator &other) const
Definition TSeq.hxx:109
bool operator>(const iterator &other) const
Definition TSeq.hxx:157
iterator & operator-=(const difference_type &v)
Definition TSeq.hxx:149
iterator & operator+=(const difference_type &v)
Definition TSeq.hxx:145
iterator & operator++()
Definition TSeq.hxx:125
difference_type operator-(const iterator &other) const
Definition TSeq.hxx:121
bool operator==(const iterator &other) const
Definition TSeq.hxx:105
bool operator<(const iterator &other) const
Definition TSeq.hxx:154
iterator operator+(difference_type v) const
Definition TSeq.hxx:113
bool operator<=(const iterator &other) const
Definition TSeq.hxx:160
iterator & operator--()
Definition TSeq.hxx:135
iterator operator--(int)
Definition TSeq.hxx:139
A pseudo container class which is a generator of indices.
Definition TSeq.hxx:67
const T fEnd
Definition TSeq.hxx:73
typename std::make_signed< T >::type difference_type
Definition TSeq.hxx:77
T value_type
Definition TSeq.hxx:76
iterator begin() const
Definition TSeq.hxx:172
const T fBegin
Definition TSeq.hxx:72
bool empty() const
Definition TSeq.hxx:197
T step() const
Definition TSeq.hxx:193
T operator[](T s) const
Definition TSeq.hxx:185
std::size_t size() const
Definition TSeq.hxx:189
TSeq(T theEnd)
Definition TSeq.hxx:79
T const & front() const
Definition TSeq.hxx:181
iterator end() const
Definition TSeq.hxx:175
void checkIntegralType()
Definition TSeq.hxx:69
const T fStep
Definition TSeq.hxx:74
TSeq(T theBegin, T theEnd, T theStep=1)
Definition TSeq.hxx:82
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
TSeq< T > MakeSeq(T end)
Definition TSeq.hxx:209