SEScalar.hxx
1 /* Distributed under the Apache License, Version 2.0.
2  See accompanying NOTICE file for details.*/
3 
4 #include "cdm/CommonDefs.h"
5 #include "cdm/utils/GeneralMath.h"
6 
7 template<typename Unit>
9 {
10 
11 }
12 
13 template<typename Unit>
15 {
17  m_unit = nullptr;
18 }
19 
20 template<typename Unit>
22 {
24  m_unit = nullptr;
25 }
26 
27 template<typename Unit>
29 {
30  if (!SEScalar::IsValid())
31  return false;
32  if (m_unit == nullptr)
33  return false;
34  return true;
35 }
36 
37 template<typename Unit>
39 {
40  const SEScalarQuantity<Unit>* q = dynamic_cast<const SEScalarQuantity<Unit>*>(&s);
41  if (q == nullptr)
42  throw CommonDataModelException("SEScalarQuantity<Unit>::Set: Set method called with differnt scalar quantity type");
43  return this->Set(*q);
44 }
45 template<typename Unit>
47 {
48  if (m_readOnly)
49  throw CommonDataModelException("SEScalarQuantity<Unit>::Set: Scalar is marked read-only");
50  if (!s.IsValid())
51  return false;
52  m_value = s.m_value;
53  m_isnan = false;
54  m_isinf = false;
55  m_unit = s.m_unit;
56  if (!IsNumber(m_value))
57  {
58  m_isnan = std::isnan(m_value);
59  m_isinf = std::isinf(m_value);
60  }
61  return true;
62 }
63 
64 template<typename Unit>
66 {
67  const SEScalarQuantity<Unit>* q = dynamic_cast<const SEScalarQuantity<Unit>*>(&s);
68  if (q == nullptr)
69  throw CommonDataModelException("SEScalarQuantity<Unit>::Copy: Set method called with differnt scalar quantity type");
70  this->Copy(*q);
71 }
72 template<typename Unit>
74 {
75  SEScalar::Copy(s);
76  m_unit = s.m_unit;
77 }
78 
79 template<typename Unit>
81 {
82  const SEScalarQuantity<Unit>* q = dynamic_cast<const SEScalarQuantity<Unit>*>(&s);
83  if (q == nullptr)
84  throw CommonDataModelException("SEScalarQuantity<Unit>::Force: Set method called with differnt scalar quantity type");
85  return this->Force(*q);
86 }
87 template<typename Unit>
89 {
90  if (!s.IsValid())
91  return false;
92  m_value = s.m_value;
93  m_isnan = false;
94  m_isinf = false;
95  m_unit = s.m_unit;
96  if (!IsNumber(m_value))
97  {
98  m_isnan = std::isnan(m_value);
99  m_isinf = std::isinf(m_value);
100  }
101  return true;
102 }
103 
104 template<typename Unit>
105 double SEScalarQuantity<Unit>::GetValue(const Unit& unit) const
106 {
107  if (m_isnan)
108  throw CommonDataModelException("SEScalarQuantity<Unit>::GetValue of " + unit.GetString() + " is NaN");
109  if (m_isinf)
110  return m_value;
111  if (m_value == 0)
112  return m_value;
113  if (m_unit == &unit)
114  return m_value;
115  return Convert(m_value, *m_unit, unit);
116 }
117 
118 template<typename Unit>
119 double SEScalarQuantity<Unit>::GetValue(const Unit& unit, int decimal_places) const
120 {
121  return SEScalar::Truncate(GetValue(unit), decimal_places);
122 }
123 
124 template<typename Unit>
126 {
127  const Unit* u = dynamic_cast<const Unit*>(&unit);
128  if (u == nullptr)
129  throw CommonDataModelException("SEScalarQuantity<Unit>::GetValue: Provided unit is not of proper quantity type");
130  return this->GetValue(*u);
131 }
132 
133 template<typename Unit>
134 double SEScalarQuantity<Unit>::GetValue(const CCompoundUnit& unit, int decimal_places) const
135 {
136  return SEScalar::Truncate(GetValue(unit), decimal_places);
137 }
138 
139 template<typename Unit>
141 {
142  return m_unit != nullptr;
143 }
144 template<typename Unit>
146 {
147  return m_unit;
148 }
149 
150 template<typename Unit>
151 void SEScalarQuantity<Unit>::SetValue(double d, const Unit& unit)
152 {
153  if (m_readOnly)
154  throw CommonDataModelException("SEScalarQuantity<Unit>::SetValue: Scalar is marked read-only");
155  m_value = d;
156  m_isnan = false;
157  m_isinf = false;
158  m_unit = &unit;
159  if (!IsNumber(m_value))
160  {
161  m_isnan = std::isnan(m_value);
162  m_isinf = std::isinf(m_value);
163  }
164 }
165 template<typename Unit>
166 void SEScalarQuantity<Unit>::ForceValue(double d, const Unit& unit)
167 {
168  m_value = d;
169  m_isnan = false;
170  m_isinf = false;
171  m_unit = &unit;
172  if (!IsNumber(m_value))
173  {
174  m_isnan = std::isnan(m_value);
175  m_isinf = std::isinf(m_value);
176  }
177  m_unit = &unit;
178 }
179 
180 template<typename Unit>
182 {
183  const Unit* u = dynamic_cast<const Unit*>(&unit);
184  if (u == nullptr)
185  throw CommonDataModelException("SEScalarQuantity<Unit>::SetValue: Provided unit is not of proper quantity type");
186  this->SetValue(d, *u);
187 }
188 template<typename Unit>
190 {
191  const Unit* u = dynamic_cast<const Unit*>(&unit);
192  if (u == nullptr)
193  throw CommonDataModelException("SEScalarQuantity<Unit>::ForceValue: Provided unit is not of proper quantity type");
194  this->ForceValue(d, *u);
195 }
196 
197 template<typename Unit>
199 {
200  if (!s.IsValid())
201  this->Invalidate();
202  else
203  return this->Increment(s.m_value, *s.m_unit);
204  return m_value;
205 }
206 
207 template<typename Unit>
208 double SEScalarQuantity<Unit>::Increment(double d, const Unit& unit)
209 {
210  if (!IsValid())
211  {
212  this->SetValue(d, unit);
213  return d;
214  }
215  this->SetValue(m_value + Convert(d, unit, *m_unit), *m_unit);
216  return Convert(m_value, *m_unit, unit);
217 }
218 
219 template<typename Unit>
221 {
222  const Unit* u = dynamic_cast<const Unit*>(&unit);
223  if (u == nullptr)
224  throw CommonDataModelException("SEScalarQuantity<Unit>::Increment: Provided unit is not of proper quantity type");
225  return this->Increment(d, *u);
226 }
227 
228 template<typename Unit>
229 double SEScalarQuantity<Unit>::ForceIncrement(double d, const Unit& unit)
230 {
231  if (!IsValid())
232  {
233  this->ForceValue(d, unit);
234  return d;
235  }
236  this->ForceValue(m_value + Convert(d, unit, *m_unit), *m_unit);
237  return Convert(m_value, *m_unit, unit);
238 }
239 
240 template<typename Unit>
242 {
243  const Unit* u = dynamic_cast<const Unit*>(&unit);
244  if (u == nullptr)
245  throw CommonDataModelException("Provided unit is not of proper quantity type");
246  return this->ForceIncrement(d, *u);
247 }
248 
249 template<typename Unit>
251 {
252  if (m_unit == nullptr)
253  return false;
254  if (m_isnan && to.m_isnan)
255  return true;
256  if (m_isnan || to.m_isnan)
257  return false;
258  if (m_isinf && to.m_isinf)
259  return true;
260  if (m_isinf || to.m_isinf)
261  return false;
262  double t = to.GetValue(*m_unit);
263  return std::abs(GeneralMath::PercentDifference(m_value, t)) <= 1e-15;
264 }
265 
266 template<typename Unit>
267 const CCompoundUnit* SEScalarQuantity<Unit>::GetCompoundUnit(const std::string& unit) const
268 {
269  return &Unit::GetCompoundUnit(unit);
270 }
271 
272 template<typename Unit>
274 {
275  if (m_isnan || m_isinf)
276  return pulse::cdm::to_string(m_value);
277  else
278  return pulse::cdm::to_string(m_value) + "(" + m_unit->GetString() + ")";
279 }
280 template<typename Unit>
281 void SEScalarQuantity<Unit>::ToString(std::ostream& str) const
282 {
283  if (m_isnan || m_isinf)
284  str << m_value << std::flush;
285  else
286  str << m_value << "(" << *m_unit << ")" << std::flush;
287 }
288 
Definition: CompoundUnit.h:40
static double PercentDifference(double expected, double calculated)
Definition: GeneralMath.cpp:218
Definition: SEScalar.h:19
bool m_isnan
Definition: SEScalar.h:24
bool m_isinf
Definition: SEScalar.h:25
static double Truncate(double value, int decimal_places)
Definition: SEScalar.cpp:255
virtual void ForceInvalidate()
Definition: SEScalar.cpp:94
bool IsValid() const override
Definition: SEScalar.cpp:101
void Copy(const SEScalar &s)
Definition: SEScalar.cpp:76
void Invalidate() override
Definition: SEScalar.cpp:85
double m_value
Definition: SEScalar.h:22
Definition: SEScalar.h:208
bool Force(const SEScalar &s) override
Definition: SEScalar.hxx:80
double GetValue() const =delete
void ForceValue(double d, const CCompoundUnit &unit) override
Definition: SEScalar.hxx:189
void Invalidate() override
Definition: SEScalar.hxx:14
bool IsValid() const override
Definition: SEScalar.hxx:28
void ForceInvalidate() override
Definition: SEScalar.hxx:21
double GetValue(const CCompoundUnit &unit) const override
Definition: SEScalar.hxx:125
const Unit * GetUnit() const override
Definition: SEScalar.hxx:145
const Unit * m_unit
Definition: SEScalar.h:271
bool HasUnit() const override
Definition: SEScalar.hxx:140
const CCompoundUnit * GetCompoundUnit(const std::string &unit) const override
Definition: SEScalar.hxx:267
bool Set(const SEScalar &s) override
Definition: SEScalar.hxx:38
std::string ToString() const override
Definition: SEScalar.hxx:273
void Copy(const SEScalar &s) override
Definition: SEScalar.hxx:65
void SetValue(double d, const CCompoundUnit &unit) override
Definition: SEScalar.hxx:181
double Increment(double d, const CCompoundUnit &unit) override
Definition: SEScalar.hxx:220
virtual ~SEScalarQuantity()
Definition: SEScalar.hxx:8
bool Equals(const SEScalar &to) const =delete
double ForceIncrement(double d, const CCompoundUnit &unit) override
Definition: SEScalar.hxx:241
CDM_DECL std::string to_string(float f)
Definition: Logger.cpp:22
Definition: CommonDefs.h:127

Distributed under the Apache License, Version 2.0.

See accompanying NOTICE file for details.