knowL: Knowledge Libraries
Loading...
Searching...
No Matches
QuantityValue.h
1#pragma once
2
3#include <QCborMap>
4#include <QCryptographicHash>
5#include <QJsonObject>
6
7#include "BigNumber.h"
8#include "NamedTypes.h"
9#include "Unit.h"
10#include "Value.h"
11
12namespace knowCore
13{
20 template<typename _T_>
22 {
23 template<typename _TOther_>
24 struct Constructor;
25 public:
26 QuantityValue() {}
27 QuantityValue(const _T_& _value, const Unit& _unit);
29 template<typename _TOther_, typename _TUri_>
30 requires(not std::is_base_of_v<Value, _TOther_> and knowCore::Uris::IsUriDefinitionV<_TUri_>)
31 static cres_qresult<QuantityValue> create(const _TOther_& _value, const _TUri_& _unit_uri)
32 {
33 return create(_value, knowCore::Uri(_unit_uri));
34 }
35 template<typename _TOther_>
36 requires(not std::is_base_of_v<Value, _TOther_>)
37 static cres_qresult<QuantityValue> create(const _TOther_& _value,
38 const knowCore::Uri& _unit_uri);
39 static cres_qresult<QuantityValue> create(const Value& _value, const knowCore::Uri& _unit_uri);
40 template<typename _TOther_>
41 requires(not std::is_base_of_v<Value, _TOther_>)
42 static cres_qresult<QuantityValue> create(const _TOther_& _value, const QString& _unit_uri)
43 = delete;
44 static cres_qresult<QuantityValue> create(const Value& _value, const QString& _unit_uri)
45 = delete;
46 template<typename _TOther_>
47 requires(not std::is_base_of_v<Value, _TOther_>)
48 static cres_qresult<QuantityValue> create(const _TOther_& _value, const Symbol& _unit_symbol);
49 static cres_qresult<QuantityValue> create(const Value& _value, const Symbol& _unit_symbol);
50
54 Unit unit() const { return m_unit; }
58 _T_ value() const { return m_value; }
59
63 cres_qresult<QuantityValue> operator+(const QuantityValue& _rhs) const;
67 cres_qresult<QuantityValue> operator-(const QuantityValue& _rhs) const;
71 cres_qresult<QuantityValue> operator/(const QuantityValue& _rhs) const;
75 cres_qresult<QuantityValue> operator*(const QuantityValue& _rhs) const;
79 QuantityValue operator/(const _T_& _rhs) const;
83 QuantityValue operator*(const _T_& _rhs) const;
84
89 bool operator==(const QuantityValue& _rhs) const;
93 cres_qresult<bool> operator<(const QuantityValue& _rhs) const;
94
98 cres_qresult<QByteArray> md5() const;
102 cres_qresult<QJsonValue> toJsonValue(const SerialisationContexts& _contexts
103 = defaultSerialisationContext()) const;
107 static cres_qresult<QuantityValue> fromJsonValue(const QJsonValue& _value,
108 const DeserialisationContexts& _context
109 = defaultDeserialisationContext());
113 cres_qresult<QCborValue> toCborValue(const SerialisationContexts& _contexts
114 = defaultSerialisationContext()) const;
118 static cres_qresult<QuantityValue> fromCborValue(const QCborValue& _value,
119 const DeserialisationContexts& _context
120 = defaultDeserialisationContext());
124 cres_qresult<QString> toRdfLiteral(const SerialisationContexts& _contexts
125 = defaultSerialisationContext()) const;
129 static cres_qresult<QuantityValue> fromRdfLiteral(const QString& _value,
130 const DeserialisationContexts& _context
131 = defaultDeserialisationContext());
135 cres_qresult<QString> printable() const;
136 private:
137 cres_qresult<_T_> cast_rhs(const QuantityValue& _rhs) const;
138 _T_ m_value;
139 Unit m_unit;
140 };
144 template<typename _T_>
145 QuantityValue<_T_> operator*(const _T_& _lhs, const QuantityValue<_T_>& _rhs);
146
147 // BEGIN Specialized constructors
148 template<>
149 template<typename _TOther_>
151 {
152 static cres_qresult<BigNumber> construct(const _TOther_& _v)
153 requires(not std::is_same_v<_TOther_, QString>)
154 {
155 return cres_success(BigNumber(_v));
156 }
157 static cres_qresult<BigNumber> construct(const QString& _v)
158 requires(std::is_same_v<_TOther_, QString>)
159 {
160 return BigNumber::fromString(_v);
161 }
162 };
163 // END Specialized constructors
164
165 // BEGIN implementation
166 template<typename _T_>
167 inline QuantityValue<_T_>::QuantityValue(const _T_& _value, const Unit& _unit)
168 : m_value(_value), m_unit(_unit)
169 {
170 }
171
172 template<typename _T_>
173 template<typename _TOther_>
174 requires(not std::is_base_of_v<Value, _TOther_>)
175 inline cres_qresult<QuantityValue<_T_>> QuantityValue<_T_>::create(const _TOther_& _value,
176 const knowCore::Uri& _unit_uri)
177 {
178 cres_try(Unit unit, Unit::byUri(_unit_uri));
179 return cres_success(QuantityValue(_value, unit));
180 }
181
182 template<typename _T_>
183 inline cres_qresult<QuantityValue<_T_>> QuantityValue<_T_>::create(const knowCore::Value& _value,
184 const knowCore::Uri& _unit_uri)
185 {
186 cres_try(_T_ value, _value.value<_T_>());
187 return create(value, _unit_uri);
188 }
189
190 template<typename _T_>
191 template<typename _TOther_>
192 requires(not std::is_base_of_v<Value, _TOther_>)
193 inline cres_qresult<QuantityValue<_T_>> QuantityValue<_T_>::create(const _TOther_& _value,
194 const Symbol& _unit_symbol)
195 {
196 cres_try(Unit unit, Unit::bySymbol(_unit_symbol));
197 cres_try(_T_ value, Constructor<_TOther_>::construct(_value));
198 return cres_success(QuantityValue(value, unit));
199 }
200
201 template<typename _T_>
202 inline cres_qresult<QuantityValue<_T_>> QuantityValue<_T_>::create(const Value& _value,
203 const Symbol& _unit_symbol)
204 {
205 cres_try(_T_ value, _value.value<_T_>());
206 return create(value, _unit_symbol);
207 }
208
209 template<typename _T_>
210 inline cres_qresult<_T_> QuantityValue<_T_>::cast_rhs(const QuantityValue& _rhs) const
211 {
212 if(_rhs.unit().base() == unit().base())
213 {
214 return cres_success(_rhs.value() * _rhs.unit().scale() / unit().scale());
215 }
216 else
217 {
218 return cres_failure("Cannot operate on incompatible units: {} is not compatible with {}",
219 unit(), _rhs.unit());
220 }
221 }
222
223 template<typename _T_>
224 inline cres_qresult<QuantityValue<_T_>>
226 {
227 cres_try(_T_ rhsv, cast_rhs(_rhs));
228 return cres_success<QuantityValue<_T_>>({value() + rhsv, unit()});
229 }
230 template<typename _T_>
231 inline cres_qresult<QuantityValue<_T_>>
233 {
234 cres_try(_T_ rhsv, cast_rhs(_rhs));
235 return cres_success<QuantityValue<_T_>>({value() - rhsv, unit()});
236 }
237 template<typename _T_>
238 inline cres_qresult<QuantityValue<_T_>>
240 {
241 if(unit().base() == _rhs.unit().base())
242 {
243 cres_try(_T_ rhsv, cast_rhs(_rhs));
244 return cres_success<QuantityValue<_T_>>({value() / rhsv, Unit::empty()});
245 }
246 else
247 {
248 cres_try(Unit runit, unit() / _rhs.unit());
249 return cres_success<QuantityValue<_T_>>({value() / _rhs.value(), runit});
250 }
251 }
252 template<typename _T_>
253 inline cres_qresult<QuantityValue<_T_>>
255 {
256 if(unit().base() == _rhs.unit().base())
257 {
258 cres_try(_T_ rhsv, cast_rhs(_rhs));
259 cres_try(Unit runit, unit() * unit());
260 return cres_success<QuantityValue<_T_>>({value() * rhsv, runit});
261 }
262 else
263 {
264 cres_try(Unit runit, unit() * _rhs.unit());
265 return cres_success<QuantityValue<_T_>>({value() * _rhs.value(), runit});
266 }
267 }
268
269 template<typename _T_>
271 {
272 return QuantityValue<_T_>{value() / _rhs, unit()};
273 }
274
275 template<typename _T_>
277 {
278 return QuantityValue<_T_>{value() * _rhs, unit()};
279 }
280
281 template<typename _T_>
282 QuantityValue<_T_> operator*(const _T_& _lhs, const QuantityValue<_T_>& _rhs)
283 {
284 return _rhs * _lhs;
285 }
286
287 template<typename _T_>
289 {
290 return value() == _rhs.value() and unit() == _rhs.unit();
291 }
292
293 template<typename _T_>
294 cres_qresult<bool> QuantityValue<_T_>::operator<(const QuantityValue& _rhs) const
295 {
296 cres_try(_T_ rhsv, cast_rhs(_rhs));
297 return cres_success(value() < rhsv);
298 }
299
300 template<typename _T_>
301 inline cres_qresult<QByteArray> QuantityValue<_T_>::md5() const
302 {
303 QCryptographicHash hash(QCryptographicHash::Md5);
304 cres_try(QByteArray value_md5, MetaTypeInformation<_T_>::md5(m_value));
305 hash.addData(value_md5);
306 hash.addData(unit().symbol().toUtf8());
307 return cres_success(hash.result());
308 }
309
310#define __KNOWCORE_VALUE_KEY QString("value")
311#define __KNOWCORE_UNIT_KEY QString("unit")
312
313 template<typename _T_>
314 inline cres_qresult<QJsonValue>
316 {
317 QJsonObject object;
318 cres_try(object[__KNOWCORE_VALUE_KEY],
320 object[__KNOWCORE_UNIT_KEY] = unit().symbol();
321 return cres_success(object);
322 }
323
324 template<typename _T_>
325 inline cres_qresult<QuantityValue<_T_>>
326 QuantityValue<_T_>::fromJsonValue(const QJsonValue& _value,
327 const DeserialisationContexts& _context)
328 {
329 if(_value.isObject())
330 {
331 QJsonObject object = _value.toObject();
333 object.value(__KNOWCORE_VALUE_KEY), _context));
334 cres_try(Unit unit, Unit::bySymbol(object.value(__KNOWCORE_UNIT_KEY).toString()));
335 return cres_success<QuantityValue<_T_>>({value, unit});
336 }
337 else
338 {
339 return cres_failure("Expected object got {}", _value);
340 }
341 }
342
343 template<typename _T_>
344 inline cres_qresult<QCborValue>
346 {
347 QCborMap object;
348 cres_try(object[__KNOWCORE_VALUE_KEY],
350 object[__KNOWCORE_UNIT_KEY] = unit().symbol();
351 return cres_success(object);
352 }
353
354 template<typename _T_>
355 inline cres_qresult<QuantityValue<_T_>>
356 QuantityValue<_T_>::fromCborValue(const QCborValue& _value,
357 const DeserialisationContexts& _context)
358 {
359 if(_value.isMap())
360 {
361 QCborMap object = _value.toMap();
363 object.value(__KNOWCORE_VALUE_KEY), _context));
364 cres_try(Unit unit, Unit::bySymbol(object.value(__KNOWCORE_UNIT_KEY).toString()));
365 return cres_success<QuantityValue<_T_>>({value, unit});
366 }
367 else
368 {
369 return cres_failure("Expected object got {}", _value);
370 }
371 }
372
373 template<typename _T_>
374 inline cres_qresult<QString>
376 {
377 cres_try(QString str, MetaTypeInformation<_T_>::toRdfLiteral(value(), _contexts));
378 return cres_success(str + " " + m_unit.symbol());
379 }
380
381 template<typename _T_>
382 inline cres_qresult<QuantityValue<_T_>>
384 const DeserialisationContexts& _context)
385 {
386 QStringList splited = _value.split(" ", KNOWCORE_QT_SKIP_EMPTY_PART);
387 if(splited.size() == 0)
388 {
389 return cres_failure("Empty literal");
390 }
391 Unit u = Unit::empty();
392 if(splited.size() == 2)
393 {
394 cres_try(u, Unit::bySymbol(splited[1]));
395 }
396 cres_try(_T_ value, MetaTypeInformation<_T_>::fromRdfLiteral(splited[0], _context));
397 return cres_success<QuantityValue<_T_>>({value, u});
398 }
399
400 template<typename _T_>
401 inline cres_qresult<QString> QuantityValue<_T_>::printable() const
402 {
403 return toRdfLiteral();
404 }
405
406#undef __KNOWCORE_UNIT_KEY
407#undef __KNOWCORE_VALUE_KEY
408
409 // END implementation
410} // namespace knowCore
411
412#include "MetaType.h"
413KNOWCORE_DECLARE_FULL_METATYPE(knowCore, QuantityNumber);
414
415template<typename _T_>
416struct std::formatter<knowCore::QuantityValue<_T_>> : public clog_format::base_formatter
417{
418 template<typename FormatContext>
419 auto format(knowCore::QuantityValue<_T_> const& p,
420 FormatContext& ctx) const -> decltype(ctx.out())
421 {
422 return format_to(ctx.out(), "({} {})", p.value(), p.unit());
423 }
424};
Class that can contains large numeric value.
Definition BigNumber.h:51
Definition MetaType.h:126
Definition MetaType.h:66
Definition QuantityValue.h:22
static cres_qresult< QuantityValue > fromRdfLiteral(const QString &_value, const DeserialisationContexts &_context=defaultDeserialisationContext())
Definition QuantityValue.h:383
cres_qresult< QuantityValue > operator*(const QuantityValue &_rhs) const
Definition QuantityValue.h:254
cres_qresult< QuantityValue > operator+(const QuantityValue &_rhs) const
Definition QuantityValue.h:225
Unit unit() const
Definition QuantityValue.h:54
cres_qresult< QByteArray > md5() const
Definition QuantityValue.h:301
cres_qresult< QString > printable() const
Definition QuantityValue.h:401
bool operator==(const QuantityValue &_rhs) const
Definition QuantityValue.h:288
cres_qresult< QCborValue > toCborValue(const SerialisationContexts &_contexts=defaultSerialisationContext()) const
Definition QuantityValue.h:345
static cres_qresult< QuantityValue > fromJsonValue(const QJsonValue &_value, const DeserialisationContexts &_context=defaultDeserialisationContext())
Definition QuantityValue.h:326
_T_ value() const
Definition QuantityValue.h:58
cres_qresult< QString > toRdfLiteral(const SerialisationContexts &_contexts=defaultSerialisationContext()) const
Definition QuantityValue.h:375
cres_qresult< QuantityValue > operator-(const QuantityValue &_rhs) const
Definition QuantityValue.h:232
cres_qresult< QuantityValue > operator/(const QuantityValue &_rhs) const
Definition QuantityValue.h:239
static cres_qresult< QuantityValue > fromCborValue(const QCborValue &_value, const DeserialisationContexts &_context=defaultDeserialisationContext())
Definition QuantityValue.h:356
cres_qresult< QJsonValue > toJsonValue(const SerialisationContexts &_contexts=defaultSerialisationContext()) const
Definition QuantityValue.h:315
cres_qresult< bool > operator<(const QuantityValue &_rhs) const
Definition QuantityValue.h:294
Definition MetaType.h:159
Definition Unit.h:17
Unit base() const
Definition Unit.cpp:251
static cres_qresult< Unit > byUri(const knowCore::Uri &_symbol)
Definition Unit.cpp:401
QString symbol() const
Definition Unit.cpp:245
static cres_qresult< Unit > bySymbol(const QString &_symbol)
Definition Unit.cpp:377
Definition Uri.h:15
Definition Value.h:21
cres_qresult< _T_ > value(TypeCheckingMode _conversion=TypeCheckingMode::Safe) const
Definition Value.h:353
Definition QuantityValue.h:151