DeSiGNAR  0.5a
Data Structures General Library
range.H
Go to the documentation of this file.
1 /*
2  This file is part of Designar.
3  Copyright (C) 2017 by Alejandro J. Mujica
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Any user request of this software, write to
19 
20  Alejandro Mujica
21 
22  aledrums@gmail.com
23 */
24 
25 # ifndef DSGRANGE_H
26 # define DSGRANGE_H
27 
28 # include <types.H>
29 # include <math.H>
30 # include <iterator.H>
31 # include <containeralgorithms.H>
32 
33 namespace Designar
34 {
35 
36  template <typename T>
37  class Range : public ContainerAlgorithms<Range<T>, T>
38  {
39  static_assert(std::is_arithmetic<T>::value,
40  "Template argument must be an arithmetic type");
41 
42  public:
43  using ItemType = T;
44  using KeyType = T;
45  using DataType = T;
46  using ValueType = T;
47  using SizeType = nat_t;
48 
49  private:
50  T first;
51  T last;
52  T step;
53 
54  public:
55  Range(T _first, T _last, T _step = T(1))
56  : first(_first), last(_last), step(_step)
57  {
58  if (first > last)
59  throw std::range_error("First value cannot be greater than last value");
60 
61  if (num_equal(step, T(0)))
62  throw std::logic_error("Step cannot be zero");
63  }
64 
65  Range(T _last)
66  : Range(T(0), _last, T(1))
67  {
68  // empty
69  }
70 
72  : Range(std::numeric_limits<T>::max())
73  {
74  // empty
75  }
76 
77  T min() const
78  {
79  return first;
80  }
81 
82  T max() const
83  {
84  return last;
85  }
86 
87  T step_size() const
88  {
89  return step;
90  }
91 
92  nat_t size() const
93  {
94  return std::ceil(double(last - first) / step);
95  }
96 
97  bool operator == (const Range & r) const
98  {
99  return num_equal(first, r.first) and num_equal(last, r.last)
100  and num_equal(step, r.step);
101  }
102 
103  bool operator != (const Range & r) const
104  {
105  return not (*this == r);
106  }
107 
108  class Iterator : public RandomAccessIterator<Iterator, T, true>
109  {
110  friend class BasicIterator<Iterator, T, true>;
111 
112  const Range & r;
113  T c;
114  nat_t p;
115 
116  protected:
118  {
119  return p;
120  }
121 
122  public:
123  Iterator(const Range & _r)
124  : r(_r), c(r.min()), p(0)
125  {
126  // empty
127  }
128 
129  Iterator(const Range & _r, T current_position)
130  : r(_r), c(r.min() + current_position * r.step_size()),
131  p(current_position)
132  {
133  // empty
134  }
135 
136  bool has_current() const
137  {
138  return c < r.max();
139  }
140 
141  T get_current() const
142  {
143  if (not has_current())
144  throw std::overflow_error("There is not current element");
145 
146  return c;
147  }
148 
149  void next()
150  {
151  if (not has_current())
152  return;
153 
154  ++p;
155  c += r.step_size();
156  }
157 
158  void next_n(nat_t n)
159  {
160  if (not has_current())
161  return;
162 
163  p = std::min(p + n, r.size());
164  c = std::min(c + r.step_size() * n, r.size() * r.step_size());
165  }
166 
167  void prev()
168  {
169  if (c == r.min())
170  return;
171 
172  --p;
173  c -= r.step_size();
174  }
175 
176  void prev_n(nat_t n)
177  {
178  if (n * r.step_size() > c - r.min())
179  return;
180 
181  p -= n;
182  c -= n * r.step_size();
183  }
184 
185  void reset()
186  {
187  c = r.min();
188  p = 0;
189  }
190  };
191 
192  Iterator begin() const
193  {
194  return Iterator(*this);
195  }
196 
197  Iterator end() const
198  {
199  return Iterator(*this, size());
200  }
201  };
202 
203  class IntRange : public Range<long long>
204  {
205  using Base = Range<long long>;
206  using Base::Base;
207  };
208 
209  class UIntRange : public Range<nat_t>
210  {
211  using Base = Range<nat_t>;
212  using Base::Base;
213  };
214 
215  class RealRange : public Range<real_t>
216  {
217  using Base = Range<real_t>;
218  using Base::Base;
219  };
220 
221  template <typename T>
222  Range<T> range(T f, T l, T s = T(1))
223  {
224  return Range<T>(f, l, s);
225  }
226 
227  template <typename T>
229  {
230  return Range<T>(l);
231  }
232 
233 } // end namespace Designar
234 
235 # endif // DSGRANGE__H
T step_size() const
Definition: range.H:87
long long ValueType
Definition: range.H:46
T get_current() const
Definition: range.H:141
Range(T _first, T _last, T _step=T(1))
Definition: range.H:55
Iterator(const Range &_r, T current_position)
Definition: range.H:129
Definition: iterator.H:132
bool num_equal(T, T)
Definition: math.H:99
Definition: range.H:203
bool has_current() const
Definition: range.H:136
Definition: iterator.H:36
Definition: range.H:37
Iterator end() const
Definition: range.H:197
bool operator==(const Range &r) const
Definition: range.H:97
nat_t size() const
Definition: range.H:92
long long ItemType
Definition: range.H:43
void prev_n(nat_t n)
Definition: range.H:176
nat_t SizeType
Definition: range.H:47
long long DataType
Definition: range.H:45
T min() const
Definition: range.H:77
Range(T _last)
Definition: range.H:65
Definition: range.H:215
Definition: range.H:209
Definition: containeralgorithms.H:33
Range()
Definition: range.H:71
Definition: range.H:108
nat_t get_location() const
Definition: range.H:117
void next_n(nat_t n)
Definition: range.H:158
Iterator(const Range &_r)
Definition: range.H:123
Definition: array.H:32
bool operator!=(const Range &r) const
Definition: range.H:103
unsigned long int nat_t
Definition: types.H:50
Range< T > range(T f, T l, T s=T(1))
Definition: range.H:222
void reset()
Definition: range.H:185
Iterator begin() const
Definition: range.H:192
Value & value(MapKey< Key, Value > &item)
Definition: map.H:77
long long KeyType
Definition: range.H:44
void next()
Definition: range.H:149
T max() const
Definition: range.H:82
void prev()
Definition: range.H:167