Main Page · Modules · All Classes · Class Hierarchy
MANum.hpp
1 /*
2  * This file is part of the AiBO+ project
3  *
4  * Copyright (C) 2005-2016 Csaba Kertész (csaba.kertesz@gmail.com)
5  *
6  * AiBO+ is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * AiBO+ is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #pragma once
23 
24 #include "MASignal.hpp"
25 
26 #include <MCDefs.hpp>
27 
28 #include <boost/make_shared.hpp>
29 #include <boost/shared_ptr.hpp>
30 
31 #include <limits>
32 #include <vector>
33 
34 #include <limits.h>
35 #include <stdint.h>
36 
45 template <typename T>
46 struct MANum
47 {
49  typedef MASignal<MANum<T>&> ValueChangeSignalType;
51  typedef MASignal<MANum<T>&, int> NewHighResValuesSignalType;
52 
62  MANum(T value = (T)0, T min_value = (T)0, T max_value = (T)1) :
63  Value(value), MinValue(min_value), MaxValue(max_value), Changed(false),
64  ValueChange((T)0), Magnitude(1.0), BlockNotifications(false)
65  {
66  // We need to initialize the member variables in this way to have a proper
67  // minimal and maximal values if needed.
68  SetMinMax(min_value, max_value);
70  MANum<T>::Changed = false;
71  }
72 
73  virtual ~MANum()
74  {
75  }
76 
84  boost::shared_ptr<ValueChangeSignalType>& GetValueChangeSignal()
85  {
86  // Note: Must be created on demand otherwise the shared pointers have
87  // a high performance impact on this core class
88  if (ValueChangeSignal.get() == nullptr)
89  {
90  ValueChangeSignal = boost::make_shared<ValueChangeSignalType>();
91  }
92  return ValueChangeSignal;
93  }
94 
102  boost::shared_ptr<NewHighResValuesSignalType>& GetNewHighResValuesSignal()
103  {
104  // Note: Must be created on demand otherwise the shared pointers have
105  // a high performance impact on this core class
106  if (NewHighResValuesSignal.get() == nullptr)
107  {
108  NewHighResValuesSignal = boost::make_shared<NewHighResValuesSignalType>();
109  }
110  return NewHighResValuesSignal;
111  }
112 
120  void SetBlockedNotifications(bool new_state)
121  {
122  BlockNotifications = new_state;
123  }
124 
133  {
134  return BlockNotifications;
135  }
136 
144  void SetHighResolutionValues(const std::vector<T>& new_highres_values)
145  {
146  int OldHighResValueNumber = HighResolutionValues.size();
147 
148  HighResolutionValues.clear();
149  HighResolutionValues = new_highres_values;
150  if (!BlockNotifications && NewHighResValuesSignal.get() != nullptr)
151  (*NewHighResValuesSignal).Emit(*this, OldHighResValueNumber);
152  }
153 
161  template <typename U>
162  void SetHighResolutionValues(const std::vector<U>& new_highres_values)
163  {
164  int OldHighResValueNumber = HighResolutionValues.size();
165 
166  HighResolutionValues.clear();
167  for (typename std::vector<U>::const_iterator Iter = new_highres_values.begin();
168  Iter != new_highres_values.end(); ++Iter)
169  {
170  HighResolutionValues.push_back((T)(*Iter));
171  }
172  if (!BlockNotifications && NewHighResValuesSignal.get() != nullptr)
173  (*NewHighResValuesSignal).Emit(*this, OldHighResValueNumber);
174  }
175 
183  const std::vector<T>& GetHighResolutionValues() const
184  {
185  return HighResolutionValues;
186  }
187 
188 
196  int IsUchar() const
197  {
198  return MinValue >= (T)0 && MaxValue <= (T)255;
199  }
200 
208  bool IsInt16() const
209  {
210  return MinValue >= (T)std::numeric_limits<int16_t>::min() &&
211  MaxValue <= (T)std::numeric_limits<int16_t>::max();
212  }
213 
221  bool IsInt32() const
222  {
223  return MinValue >= (T)std::numeric_limits<int32_t>::min() &&
224  MaxValue <= (T)std::numeric_limits<int32_t>::max();
225  }
226 
235  virtual void SetMinMax(T min_value, T max_value)
236  {
237  MinValue = min_value;
238  MaxValue = max_value;
239  // Normalize the current hold value to the new value range and
240  // emit the changed event if needed.
241  *this = Value;
242  }
243 
251  T GetMin() const
252  {
253  return MinValue;
254  }
255 
263  T GetMax() const
264  {
265  return MaxValue;
266  }
267 
275  bool IsChanged() const
276  {
277  return Changed;
278  }
279 
287  T GetValueChange() const
288  {
289  return ValueChange;
290  }
291 
299  void SetMagnitude(float value)
300  {
301  Magnitude = value;
302  }
303 
311  float GetMagnitude() const
312  {
313  return Magnitude;
314  }
315 
323  float GetNormalizedValue() const
324  {
325  if (Magnitude == 0.0 || Magnitude == 1.0)
326  return Value;
327 
328  return (float)Value / Magnitude;
329  }
330 
340  MANum<T>& operator=(const MANum<T>& other)
341  {
342  if (this == &other)
343  return *this;
344 
345  MinValue = other.MinValue;
346  MaxValue = other.MaxValue;
347  if (Value != other.Value)
348  {
349  Changed = true;
350  ValueChange = other.Value-Value;
351  } else {
352  Changed = false;
353  ValueChange = (T)0;
354  }
355  Value = other.Value;
356  Magnitude = other.Magnitude;
357  if (Changed && !BlockNotifications && ValueChangeSignal.get() != nullptr)
358  (*ValueChangeSignal).Emit(*this);
359 
361  // Note: At this point BlockNotifications state can be copied.
363  return *this;
364  }
365 
375  template <typename U>
376  MANum<T>& operator=(const U& new_value)
377  {
378  T OldValue = Value;
379 
380  Value = MCBound(MinValue, (T)new_value, MaxValue);
381  if (Value != OldValue)
382  {
383  Changed = true;
384  ValueChange = Value-OldValue;
385  if (!BlockNotifications && ValueChangeSignal.get() != nullptr)
386  (*ValueChangeSignal).Emit(*this);
387  } else {
388  Changed = false;
389  ValueChange = (T)0;
390  }
391  return *this;
392  }
393 
403  bool operator==(const T value) const
404  {
405  return Value == value;
406  }
407 
417  bool operator!=(const T value) const
418  {
419  return Value != value;
420  }
421 
431  const MANum<T> operator-(const T value) const
432  {
433  return MANum<T>(*this) -= value;
434  }
435 
444  {
445  return operator-=((T)1);
446  }
447 
455  void operator--(int)
456  {
457  --(*this);
458  }
459 
469  MANum<T>& operator-=(const T value)
470  {
471  operator=(MCBound(MinValue, (T)(Value-value), MaxValue));
472  return *this;
473  }
474 
484  const MANum<T> operator+(const T value) const
485  {
486  return MANum<T>(*this) += value;
487  }
488 
497  {
498  return operator+=((T)1);
499  }
500 
508  void operator++(int)
509  {
510  ++(*this);
511  }
512 
522  MANum<T>& operator+=(const T value)
523  {
524  operator=(MCBound(MinValue, (T)(Value+value), MaxValue));
525  return *this;
526  }
527 
537  const MANum<T> operator*(const T value) const
538  {
539  return MANum<T>(*this) *= value;
540  }
541 
551  MANum<T>& operator*=(const T value)
552  {
553  operator=(MCBound(MinValue, (T)(Value*value), MaxValue));
554  return *this;
555  }
556 
566  const MANum<T> operator/(const T value) const
567  {
568  return MANum<T>(*this) /= value;
569  }
570 
580  MANum<T>& operator/=(const T value)
581  {
582  operator=(MCBound(MinValue, (T)(Value / value), MaxValue));
583  return *this;
584  }
585 
586 
594  operator T() const
595  {
596  return Value;
597  };
598 
599 protected:
601  T Value;
607  bool Changed;
611  float Magnitude;
613  boost::shared_ptr<ValueChangeSignalType> ValueChangeSignal;
615  boost::shared_ptr<NewHighResValuesSignalType> NewHighResValuesSignal;
619  std::vector<T> HighResolutionValues;
620 };
621 
622 template <typename T>
623 struct MAIntervalNum : public MANum<T>
624 {
625 public:
626 
636  MAIntervalNum(T value = (T)0, T min_value = (T)-100, T max_value = (T)100) :
637  MANum<T>(value, min_value, max_value)
638  {
639  }
640 
648  explicit MAIntervalNum(MANum<T>& other)
649  {
650  *static_cast<MANum<T>*>(this) = other;
651  }
652 
666  virtual void SetMinMax(T min_value, T max_value) override
667  {
668  MANum<T>::SetMinMax(min_value > (T)0 ? (T)0 : min_value,
669  max_value > (T)0 ? max_value : (T)0);
670  }
671 
680  T GetScaledValue() const
681  {
682  if (MANum<T>::Value == (T)0)
683  return (T)0;
684 
685  return MANum<T>::Value > 0 ?
688  }
689 
690  MAIntervalNum<T>& operator=(T new_value)
691  {
692  MANum<T>::operator=(new_value);
693  return *this;
694  }
695 
696  bool operator==(const T value) const
697  {
698  return MANum<T>::operator==(value);
699  }
700 
701  bool operator!=(const T value) const
702  {
703  return MANum<T>::operator!=(value);
704  }
705 
706  const MAIntervalNum<T> operator-(const T value) const
707  {
708  MAIntervalNum<T> TempVar;
709 
710  *static_cast<MANum<T>*>(&TempVar) = MANum<T>::operator-(value);
711  return TempVar;
712  }
713 
714  MAIntervalNum<T>& operator-=(const T value)
715  {
716  MANum<T>::operator-=(value);
717  return *this;
718  }
719 
720  const MAIntervalNum<T> operator+(const T value) const
721  {
722  MAIntervalNum<T> TempVar;
723 
724  *static_cast<MANum<T>*>(&TempVar) = MANum<T>::operator+(value);
725  return TempVar;
726  }
727 
728  MAIntervalNum<T>& operator+=(const T value)
729  {
730  MANum<T>::operator+=(value);
731  return *this;
732  }
733 
734  const MAIntervalNum<T> operator*(const T value) const
735  {
736  MAIntervalNum<T> TempVar;
737 
738  *static_cast<MANum<T>*>(&TempVar) = MANum<T>::operator*(value);
739  return TempVar;
740  }
741 
742  MAIntervalNum<T>& operator*=(const T value)
743  {
744  MANum<T>::operator*=(value);
745  return *this;
746  }
747 
748  const MAIntervalNum<T> operator/(const T value) const
749  {
750  MAIntervalNum<T> TempVar;
751 
752  *static_cast<MANum<T>*>(&TempVar) = MANum<T>::operator/(value);
753  return TempVar;
754  }
755 
756  MAIntervalNum<T>& operator/=(const T value)
757  {
758  MANum<T>::operator/=(value);
759  return *this;
760  }
761 };
762 
const MANum< T > operator-(const T value) const
Decrement (-) operator.
Definition: MANum.hpp:431
boost::shared_ptr< NewHighResValuesSignalType > NewHighResValuesSignal
New high resolution values change signal.
Definition: MANum.hpp:615
bool IsChanged() const
Check if the value is changed.
Definition: MANum.hpp:275
const MANum< T > operator/(const T value) const
Division (/) operator.
Definition: MANum.hpp:566
boost::shared_ptr< ValueChangeSignalType > ValueChangeSignal
Value change signal.
Definition: MANum.hpp:613
float GetMagnitude() const
Get the magnitude.
Definition: MANum.hpp:311
boost::shared_ptr< ValueChangeSignalType > & GetValueChangeSignal()
Get the value change signal.
Definition: MANum.hpp:84
MANum< T > & operator-=(const T value)
Subtraction assignment (-=) operator.
Definition: MANum.hpp:469
void SetBlockedNotifications(bool new_state)
Set the notifications to be blocked.
Definition: MANum.hpp:120
MANum(T value=(T) 0, T min_value=(T) 0, T max_value=(T) 1)
Class constructor.
Definition: MANum.hpp:62
float Magnitude
Magnitude.
Definition: MANum.hpp:611
bool IsInt16() const
Check if it can be stored in a 16 bit integer.
Definition: MANum.hpp:208
virtual void SetMinMax(T min_value, T max_value)
Set the minimal and maximal values.
Definition: MANum.hpp:235
MANum< T > & operator/=(const T value)
Division assignment (/=) operator.
Definition: MANum.hpp:580
const T & MCBound(const T &min, const T &value, const T &max)
Check a value bound according to a range.
Definition: MCDefs.hpp:527
MANum< T > & operator--()
Decrement (–) prefix operator.
Definition: MANum.hpp:443
bool BlockNotifications
Whenever the notifications are blocked.
Definition: MANum.hpp:617
const std::vector< T > & GetHighResolutionValues() const
Get high resolution values.
Definition: MANum.hpp:183
bool IsBlockedNotifications() const
Check if the notifications are blocked.
Definition: MANum.hpp:132
T GetMax() const
Get the maximal value.
Definition: MANum.hpp:263
This class represents a number with bound check.
bool Changed
The value changed.
Definition: MANum.hpp:607
int IsUchar() const
Check if it can be stored in an unsigned char.
Definition: MANum.hpp:196
T MaxValue
Maximal value.
Definition: MANum.hpp:605
MASignal< MANum< T > &, int > NewHighResValuesSignalType
High resolution value changes signal type.
Definition: MANum.hpp:51
bool operator==(const T value) const
Equality (==) operator.
Definition: MANum.hpp:403
T Value
Number value.
Definition: MANum.hpp:597
boost::shared_ptr< NewHighResValuesSignalType > & GetNewHighResValuesSignal()
Get the new high resolution values signal.
Definition: MANum.hpp:102
MANum< T > & operator=(const U &new_value)
Copy assignment operator.
Definition: MANum.hpp:376
void operator--(int)
Decrement (–) suffix operator.
Definition: MANum.hpp:455
std::vector< T > HighResolutionValues
High resolution values.
Definition: MANum.hpp:619
void SetMagnitude(float value)
Set the magnitude.
Definition: MANum.hpp:299
MANum< T > & operator+=(const T value)
Addition assignment (+=) operator.
Definition: MANum.hpp:522
bool IsInt32() const
Check if it can be stored in a 32 bit integer.
Definition: MANum.hpp:221
T MinValue
Minimal value.
Definition: MANum.hpp:603
T ValueChange
The value change.
Definition: MANum.hpp:609
T GetMin() const
Get the minimal value.
Definition: MANum.hpp:251
void SetHighResolutionValues(const std::vector< T > &new_highres_values)
Set high resolution values.
Definition: MANum.hpp:144
MASignal< MANum< T > & > ValueChangeSignalType
Value change signal type.
Definition: MANum.hpp:49
void SetHighResolutionValues(const std::vector< U > &new_highres_values)
Set high resolution values.
Definition: MANum.hpp:162
MANum< T > & operator*=(const T value)
Multiplication assignment (*=) operator.
Definition: MANum.hpp:551
const MANum< T > operator*(const T value) const
Multiply (*) operator.
Definition: MANum.hpp:537
const MANum< T > operator+(const T value) const
Increment (+) operator.
Definition: MANum.hpp:484
void operator++(int)
Increment (++) suffix operator.
Definition: MANum.hpp:508
T GetValueChange() const
The last value change difference.
Definition: MANum.hpp:287
bool operator!=(const T value) const
Inequality (!=) operator.
Definition: MANum.hpp:417
MANum< T > & operator=(const MANum< T > &other)
Copy assignment operator.
Definition: MANum.hpp:340
MANum< T > & operator++()
Increment (++) prefix operator.
Definition: MANum.hpp:496
float GetNormalizedValue() const
Get the normalized value by magnitude.
Definition: MANum.hpp:323