Ilwis-Objects  1.0
GIS and Remote Sensing framework for data access and processing
 All Classes Functions Enumerations Pages
valuerange.h
1 #ifndef VALUERANGE_H
2 #define VALUERANGE_H
3 
4 #include <QString>
5 #include <typeinfo>
6 #include "kernel.h"
7 #include "range.h"
8 
9 namespace Ilwis {
10 template<class T=double> class ValueRange : public Range
11 {
12 public:
13  ValueRange() : _min(0), _max(-1) {}
14  ValueRange(T mi, T ma) : _min(mi), _max(ma) {}
15  ValueRange(const ValueRange<T> &vr)
16  {
17  _min = vr.min();
18  _max = vr.max();
19  }
20 
21  bool isValid() const
22  {
23  return _min <= _max ;
24  }
25 
26  bool contains(T v, bool inclusive = true) const
27  {
28  if (!isValid())
29  return false;
30  if ( inclusive)
31  return v >= _min && v <= _max;
32  return v > _min && v < _max;
33  }
34  T max() const
35  {
36  return _max;
37  }
38  T min() const
39  {
40  return _min;
41  }
42  void setMin(T v)
43  {
44  _min = v;
45  }
46 
47  void setMax(T v)
48  {
49  _max = v;
50  }
51 
52  ValueRange& operator+=(T v)
53  {
54  if ( !isValid())
55  _min = _max = v;
56  else {
57  if ( v > _max )
58  _max = v;
59  if ( v < _min)
60  _min = v;
61  }
62  return *this;
63  }
64 
65  bool operator==(const ValueRange& vr) {
66  return vr.max() == max() && vr.min() == min();
67  }
68 
69  QString toString() const { return "";}
70  void set(const ValueRange<T>& vr)
71  {
72  _min = vr.min();
73  _max = vr.max();
74  }
75 
76 
77  IlwisTypes findBaseType() const {
78  QString t = kernel()->demangle(typeid(T).name());
79  bool intType = t == "int" || t == "char" || t == "long" || t == "long long" || t == "short" ||
80  t == "unsigned int" || t == "unsigned char" || t == "unsigned long" || t == "unsigned short";
81  return intType ? itINT64 : itDOUBLE;
82  }
83 
84  IlwisTypes determineType() const{
85  IlwisTypes vt = findBaseType();
86  if ( vt == itINT64) { // integer part
87  bool sig = min() < 0;
88  if ( max() <=128 && sig)
89  vt = itINT8;
90  else if ( max() <= 255 && !sig)
91  vt = itUINT8;
92  else if ( max() <= 32768 && sig)
93  vt = itINT16;
94  else if ( max() <= 65536 && !sig)
95  vt = itUINT32;
96  else if ( max() <= 2147483647 && sig)
97  vt = itINT32;
98  else if ( max() <= 4294967296 && !sig)
99  vt = itUINT32;
100  else
101  vt = itINT64; // unlikely but anyway
102  } else { // real part
103  int signif1 = std::max(significantDigits(min()), significantDigits(max()));
104  if ( signif1 > 6)
105  vt = itDOUBLE;
106  else
107  vt = itFLOAT;
108  }
109  return vt;
110  }
111 
112 private:
113  T _min;
114  T _max;
115 
116  long significantDigits(double m1) const{
117  if ( fabs(m1) > 1e30)
118  return 100;
119 
120  QString s = QString::number(m1);
121  for(int i=s.size() - 1; i != 0; --i ) {
122  QChar c = s[i];
123  if ( c != '0') {
124  if ( s.indexOf(".") > 0) // '.' is not counted for significant numbers
125  return i;
126  return i -1;
127  }
128  }
129  return s.size();
130  }
131 
132 
133 };
134 }
135 
136 #endif // VALUERANGE_H