Embedded Template Library  1.0
cyclic_value.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2014 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_CYCLIC_VALUE_INCLUDED
32 #define ETL_CYCLIC_VALUE_INCLUDED
33 
34 #include <stddef.h>
35 
39 
40 #include "platform.h"
41 #include "static_assert.h"
42 #include "exception.h"
43 #include "static_assert.h"
44 #include "type_traits.h"
45 
46 #include "algorithm.h"
47 
48 namespace etl
49 {
50  //***************************************************************************
57  //***************************************************************************
58  template <typename T, T FIRST = 0, T LAST = 0, typename = void>
60  {
61  public:
62 
63  //*************************************************************************
66  //*************************************************************************
68  : value(FIRST)
69  {
70  }
71 
72  //*************************************************************************
74  //*************************************************************************
76  : value(other.value)
77  {
78  }
79 
80  //*************************************************************************
83  //*************************************************************************
84  void set(T value_)
85  {
86  if (value_ > LAST)
87  {
88  value_ = LAST;
89  }
90  else if (value_ < FIRST)
91  {
92  value_ = FIRST;
93  }
94 
95  value = value_;
96  }
97 
98  //*************************************************************************
100  //*************************************************************************
101  void to_first()
102  {
103  value = FIRST;
104  }
105 
106  //*************************************************************************
108  //*************************************************************************
109  void to_last()
110  {
111  value = LAST;
112  }
113 
114  //*************************************************************************
117  //*************************************************************************
118  void advance(int n)
119  {
120  if (n > 0)
121  {
122  for (int i = 0; i < n; ++i)
123  {
124  operator ++();
125  }
126  }
127  else
128  {
129  for (int i = 0; i < -n; ++i)
130  {
131  operator --();
132  }
133  }
134  }
135 
136  //*************************************************************************
139  //*************************************************************************
140  operator T()
141  {
142  return value;
143  }
144 
145  //*************************************************************************
148  //*************************************************************************
149  operator const T() const
150  {
151  return value;
152  }
153 
154  //*************************************************************************
156  //*************************************************************************
158  {
159  if (value >= LAST)
160  {
161  value = FIRST;
162  }
163  else
164  {
165  ++value;
166  }
167 
168  return *this;
169  }
170 
171  //*************************************************************************
173  //*************************************************************************
175  {
176  cyclic_value temp(*this);
177 
178  operator++();
179 
180  return temp;
181  }
182 
183  //*************************************************************************
185  //*************************************************************************
187  {
188  if (value <= FIRST)
189  {
190  value = LAST;
191  }
192  else
193  {
194  --value;
195  }
196 
197  return *this;
198  }
199 
200  //*************************************************************************
202  //*************************************************************************
204  {
205  cyclic_value temp(*this);
206 
207  operator--();
208 
209  return temp;
210  }
211 
212  //*************************************************************************
214  //*************************************************************************
216  {
217  set(t);
218  return *this;
219  }
220 
221  //*************************************************************************
223  //*************************************************************************
224  template <const T FIRST2, const T LAST2>
226  {
227  set(other.get());
228  return *this;
229  }
230 
231  //*************************************************************************
233  //*************************************************************************
234  T get() const
235  {
236  return value;
237  }
238 
239  //*************************************************************************
241  //*************************************************************************
242  const T first() const
243  {
244  return FIRST;
245  }
246 
247  //*************************************************************************
249  //*************************************************************************
250  const T last() const
251  {
252  return LAST;
253  }
254 
255  //*************************************************************************
257  //*************************************************************************
259  {
260  using ETL_OR_STD::swap; // Allow ADL
261 
262  swap(value, other.value);
263  }
264 
265  //*************************************************************************
267  //*************************************************************************
269  {
270  lhs.swap(rhs);
271  }
272 
273  //*************************************************************************
275  //*************************************************************************
277  {
278  return lhs.value == rhs.value;
279  }
280 
281  //*************************************************************************
283  //*************************************************************************
285  {
286  return !(lhs == rhs);
287  }
288 
289  private:
290 
291  T value;
292  };
293 
294  //***************************************************************************
301  //***************************************************************************
302  template <typename T, const T FIRST, const T LAST>
303  class cyclic_value<T, FIRST, LAST, typename etl::enable_if<(FIRST == 0) && (LAST == 0)>::type>
304  {
305  public:
306 
307  //*************************************************************************
311  //*************************************************************************
313  : value(FIRST),
314  first_value(FIRST),
315  last_value(LAST)
316  {
317  }
318 
319  //*************************************************************************
324  //*************************************************************************
325  cyclic_value(T first_, T last_)
326  : value(first_),
327  first_value(first_),
328  last_value(last_)
329  {
330  }
331 
332  //*************************************************************************
334  //*************************************************************************
336  : value(other.value),
337  first_value(other.first_value),
338  last_value(other.last_value)
339  {
340  }
341 
342  //*************************************************************************
347  //*************************************************************************
348  void set(T first_, T last_)
349  {
350  first_value = first_;
351  last_value = last_;
352  value = first_;
353  }
354 
355  //*************************************************************************
358  //*************************************************************************
359  void set(T value_)
360  {
361  if (value_ > last_value)
362  {
363  value_ = last_value;
364  }
365  else if (value_ < first_value)
366  {
367  value_ = first_value;
368  }
369 
370  value = value_;
371  }
372 
373  //*************************************************************************
375  //*************************************************************************
376  void to_first()
377  {
378  value = first_value;
379  }
380 
381  //*************************************************************************
383  //*************************************************************************
384  void to_last()
385  {
386  value = last_value;
387  }
388 
389  //*************************************************************************
392  //*************************************************************************
393  void advance(int n)
394  {
395  if (n > 0)
396  {
397  for (int i = 0; i < n; ++i)
398  {
399  operator ++();
400  }
401  }
402  else
403  {
404  for (int i = 0; i < -n; ++i)
405  {
406  operator --();
407  }
408  }
409  }
410 
411  //*************************************************************************
414  //*************************************************************************
415  operator T()
416  {
417  return value;
418  }
419 
420  //*************************************************************************
423  //*************************************************************************
424  operator const T() const
425  {
426  return value;
427  }
428 
429  //*************************************************************************
431  //*************************************************************************
433  {
434  if (value >= last_value)
435  {
436  value = first_value;
437  }
438  else
439  {
440  ++value;
441  }
442 
443  return *this;
444  }
445 
446  //*************************************************************************
448  //*************************************************************************
450  {
451  cyclic_value temp(*this);
452 
453  operator++();
454 
455  return temp;
456  }
457 
458  //*************************************************************************
460  //*************************************************************************
462  {
463  if (value <= first_value)
464  {
465  value = last_value;
466  }
467  else
468  {
469  --value;
470  }
471 
472  return *this;
473  }
474 
475  //*************************************************************************
477  //*************************************************************************
479  {
480  cyclic_value temp(*this);
481 
482  operator--();
483 
484  return temp;
485  }
486 
487  //*************************************************************************
489  //*************************************************************************
491  {
492  set(t);
493  return *this;
494  }
495 
496  //*************************************************************************
498  //*************************************************************************
500  {
501  value = other.value;
502  first_value = other.first_value;
503  last_value = other.last_value;
504  return *this;
505  }
506 
507  //*************************************************************************
509  //*************************************************************************
510  T get() const
511  {
512  return value;
513  }
514 
515  //*************************************************************************
517  //*************************************************************************
518  T first() const
519  {
520  return first_value;
521  }
522 
523  //*************************************************************************
525  //*************************************************************************
526  T last() const
527  {
528  return last_value;
529  }
530 
531  //*************************************************************************
533  //*************************************************************************
535  {
536  using ETL_OR_STD::swap; // Allow ADL
537 
538  swap(first_value, other.first_value);
539  swap(last_value, other.last_value);
540  swap(value, other.value);
541  }
542 
543  //*************************************************************************
545  //*************************************************************************
547  {
548  lhs.swap(rhs);
549  }
550 
551  //*************************************************************************
553  //*************************************************************************
555  {
556  return (lhs.value == rhs.value) &&
557  (lhs.first_value == rhs.first_value) &&
558  (lhs.last_value == rhs.last_value);
559  }
560 
561  //*************************************************************************
563  //*************************************************************************
565  {
566  return !(lhs == rhs);
567  }
568 
569  private:
570 
571  T value;
572  T first_value;
573  T last_value;
574  };
575 }
576 
577 #endif
void to_first()
Resets the value to the first in the range.
Definition: cyclic_value.h:101
void swap(cyclic_value< T, FIRST, LAST > &other)
Swaps the values.
Definition: cyclic_value.h:534
friend bool operator==(const cyclic_value< T, FIRST, LAST > &lhs, const cyclic_value< T, FIRST, LAST > &rhs)
Operator ==.
Definition: cyclic_value.h:276
void to_first()
Resets the value to the first in the range.
Definition: cyclic_value.h:376
cyclic_value & operator++()
++ operator.
Definition: cyclic_value.h:157
void to_last()
Resets the value to the last in the range.
Definition: cyclic_value.h:109
cyclic_value(const cyclic_value &other)
Copy constructor.
Definition: cyclic_value.h:335
cyclic_value(const cyclic_value< T, FIRST, LAST > &other)
Copy constructor.
Definition: cyclic_value.h:75
void swap(cyclic_value< T, FIRST, LAST > &other)
Swaps the values.
Definition: cyclic_value.h:258
T get() const
Gets the value.
Definition: cyclic_value.h:234
cyclic_value & operator=(T t)
= operator.
Definition: cyclic_value.h:215
T first() const
Gets the first value.
Definition: cyclic_value.h:518
T last() const
Gets the last value.
Definition: cyclic_value.h:526
friend void swap(cyclic_value< T, FIRST, LAST > &lhs, cyclic_value< T, FIRST, LAST > &rhs)
Swaps the values.
Definition: cyclic_value.h:268
cyclic_value & operator--()
– operator.
Definition: cyclic_value.h:186
const T first() const
Gets the first value.
Definition: cyclic_value.h:242
cyclic_value()
Definition: cyclic_value.h:67
void advance(int n)
Definition: cyclic_value.h:118
const T last() const
Gets the last value.
Definition: cyclic_value.h:250
void to_last()
Resets the value to the last in the range.
Definition: cyclic_value.h:384
void set(T value_)
Definition: cyclic_value.h:84
friend bool operator!=(const cyclic_value< T, FIRST, LAST > &lhs, const cyclic_value< T, FIRST, LAST > &rhs)
Operator !=.
Definition: cyclic_value.h:284
Definition: cyclic_value.h:60
enable_if
Definition: type_traits_generator.h:1228
Definition: absolute.h:37
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:570