knowL: Knowledge Libraries
Loading...
Searching...
No Matches
Value.h
1#pragma once
2
3#include <clog_qt>
4#include <cres_qt>
5
6#include <QSharedDataPointer>
7
8#include <cstddef>
9#include <knowCore/Forward.h>
10
11#include "MetaType.h"
12
13namespace knowCore
14{
15 namespace details
16 {
17 template<typename _T_>
18 struct Value_value;
19 }
20 class Value
21 {
22 template<typename _T_>
23 friend struct details::Value_value;
24 Value(const Uri& _datatype, const AbstractMetaTypeDefinition* _definition, void* _data);
25 Value(const Uri& _datatype, const Uri& _maindatatype,
26 const AbstractMetaTypeDefinition* _definition, void* _data);
27 public:
31 Value();
32 Value(const Value& _rhs);
33 Value& operator=(const Value& _rhs);
34 ~Value();
35
40 template<typename _T_>
41 static inline Value fromValue(const _T_& _value);
46 static inline cres_qresult<Value> fromValue(const QVariant& _value);
52 template<typename _T_>
53 static inline cres_qresult<Value> fromValue(const Uri& _datatype, const _T_& _value,
54 TypeCheckingMode _conversion
55 = TypeCheckingMode::Safe);
64 static cres_qresult<Value> fromVariant(const Uri& _datatype, const QVariant& _value,
65 TypeCheckingMode _conversion = TypeCheckingMode::Safe);
70 static cres_qresult<Value> fromVariant(const QVariant& _variant);
77 static cres_qresult<Value> parseVariant(const QVariant& _value);
81 QVariant toVariant() const;
85 Uri datatype() const;
89 bool isEmpty() const;
95 bool operator<(const Value& _rhs) const;
99 bool operator==(const Value& _rhs) const;
103 bool operator!=(const Value& _rhs) const { return not(*this == _rhs); }
107 cres_qresult<bool> compare(const Value& _value, ComparisonOperators _operators) const;
108 cres_qresult<Value> convert(const Uri& _uri,
109 TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
113 cres_qresult<Value> compute(const Value& _value, ArithmeticOperator _operator) const;
119 template<typename _T_>
120 inline cres_qresult<_T_> value(TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
128 template<typename _T_>
129 inline _T_ value(const _T_& _default,
130 TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
134 template<typename _T_>
135 inline bool canConvert(TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
139 bool canConvert(const Uri& _uri, TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
140 template<typename _T_>
141 inline bool is() const;
142 cres_qresult<QByteArray> md5() const;
143 cres_qresult<QJsonValue> toJsonValue(const SerialisationContexts& _contexts
144 = defaultSerialisationContext()) const;
145 static cres_qresult<Value> fromJsonValue(const Uri& _datatype, const QJsonValue& _value,
146 const DeserialisationContexts& _context
147 = defaultDeserialisationContext());
148 template<typename _T_>
149 static cres_qresult<_T_> fromJsonValue(const QJsonValue& _value,
150 const DeserialisationContexts& _context
151 = defaultDeserialisationContext());
152 cres_qresult<QCborValue> toCborValue(const SerialisationContexts& _contexts
153 = defaultSerialisationContext()) const;
154 static cres_qresult<Value> fromCborValue(const Uri& _datatype, const QCborValue& _value,
155 const DeserialisationContexts& _context
156 = defaultDeserialisationContext());
157 cres_qresult<QString> toRdfLiteral(const SerialisationContexts& _contexts
158 = defaultSerialisationContext()) const;
159 static cres_qresult<Value> fromRdfLiteral(const Uri& _datatype, const QString& _value,
160 const DeserialisationContexts& _context
161 = defaultDeserialisationContext());
162 cres_qresult<QString> printable() const;
163
167 cres_qresult<QJsonObject> toJsonObject(const SerialisationContexts& _contexts
168 = defaultSerialisationContext()) const;
173 static cres_qresult<Value> fromJsonObject(const QJsonObject& _value,
174 const DeserialisationContexts& _context
175 = defaultDeserialisationContext());
179 cres_qresult<QCborMap> toCborMap(const SerialisationContexts& _contexts
180 = defaultSerialisationContext()) const;
185 static cres_qresult<Value> fromCborMap(const QCborMap& _value,
186 const DeserialisationContexts& _context
187 = defaultDeserialisationContext());
188
192 cres_qresult<ValueList> toList() const;
196 cres_qresult<ValueHash> toHash() const;
197 private:
198 const AbstractMetaTypeDefinition* definition() const;
199 private:
200 // Access to metatype stuff
201 template<typename _T_>
202 static const AbstractMetaTypeDefinition* getDefinition()
203 {
205 }
206 static const AbstractMetaTypeDefinition* getDefinition(const Uri& _datatype);
207 static const AbstractMetaTypeDefinition* getDefinition(int _id);
208 const void* data() const;
209 template<typename _T_>
210 const AbstractTypeConversion* converterTo(TypeCheckingMode _conversion) const
211 {
212 return converterTo(MetaTypeInformation<_T_>::uri(), _conversion);
213 }
214 const AbstractTypeConversion* converterTo(const Uri& _datatype,
215 TypeCheckingMode _conversion) const;
216 template<typename _T_>
217 const AbstractTypeConversion* converterFrom(TypeCheckingMode _conversion) const
218 {
219 return converterFrom(MetaTypeInformation<_T_>::uri());
220 }
221 const AbstractTypeConversion* converterFrom(const Uri& _datatype,
222 TypeCheckingMode _conversion) const;
223 template<typename _TFrom_, typename _TTo_>
224 static const AbstractTypeConversion* converterBetween(TypeCheckingMode _conversion)
225 {
226 return converterBetween(MetaTypeInformation<_TFrom_>::uri(),
227 MetaTypeInformation<_TTo_>::uri(), _conversion);
228 }
229 static const AbstractTypeConversion* converterBetween(const Uri& _from, const Uri& _to,
230 TypeCheckingMode _conversion);
231
232 static const AbstractTypeConversion* converter(const Uri& _from, const Uri& _to,
233 TypeCheckingMode _conversion);
234 private:
235 struct Private;
236 QSharedDataPointer<Private> d;
237 };
238 uint qHash(const Value& key, std::size_t seed = 0);
239
240 template<typename _T_>
241 inline Value Value::fromValue(const _T_& _value)
242 {
243 const AbstractMetaTypeDefinition* def = getDefinition<_T_>();
244 clog_assert(def);
245 return Value(def->uri(), def, def->duplicate(&_value));
246 }
247 template<typename _T_>
248 inline cres_qresult<Value> Value::fromValue(const Uri& _datatype, const _T_& _value,
249 TypeCheckingMode _conversion)
250 {
251 const AbstractMetaTypeDefinition* def_1 = getDefinition<_T_>();
252 const AbstractMetaTypeDefinition* def_2 = getDefinition(_datatype);
253 if(def_1 != def_2)
254 {
255 const AbstractTypeConversion* converter
256 = Value::converter(MetaTypeInformation<_T_>::uri(), _datatype, _conversion);
257 if(converter)
258 {
259 void* data = def_2->allocate();
260 cres_try(cres_ignore, converter->convert(&_value, data), );
261 return cres_success(Value(_datatype, def_2, data));
262 }
263 return cres_failure(
264 "{0} is not alias of type '{1}' with uri '{2}' and no conversion from '{2}' to '{0}'.",
265 _datatype, prettyTypename<_T_>(), MetaTypeInformation<_T_>::uri());
266 }
267 if(def_1)
268 {
269 return cres_success(Value(_datatype, def_1, def_1->duplicate(&_value)));
270 }
271 else
272 {
273 return cres_failure("Type '{}' with datatype '{}' is not defined!", prettyTypename<_T_>(),
274 _datatype);
275 }
276 }
277 template<>
278 inline cres_qresult<Value> Value::fromValue<knowCore::Value>(const Uri& _datatype,
279 const knowCore::Value& _value,
280 TypeCheckingMode _conversion)
281 {
282 return _value.convert(_datatype, _conversion);
283 }
284 inline cres_qresult<Value> Value::fromValue(const QVariant& _value)
285 {
286 return fromVariant(_value);
287 }
288 template<>
289 inline cres_qresult<Value> Value::fromValue<QVariant>(const Uri& _datatype,
290 const QVariant& _value,
291 TypeCheckingMode _conversion)
292 {
293 return fromVariant(_datatype, _value, _conversion);
294 }
295
296 namespace details
297 {
298 template<typename _T_>
300 {
301 static cres_qresult<_T_> value(const Value* _self, TypeCheckingMode _conversion)
302 {
304 or _self->getDefinition<_T_>() == _self->definition())
305 {
306 return cres_success(_T_(*reinterpret_cast<const _T_*>(_self->data())));
307 }
308 // First: try to convert directly
309 if(const AbstractTypeConversion* converter = _self->converterTo<_T_>(_conversion))
310 {
311 _T_ r;
312 cres_try(cres_ignore, converter->convert(_self->data(), &r));
313 return cres_success(r);
314 } // Second: some types can be converted to a value (mostly usefull for knowRDF::Literal)
315 // and then from that value to _T_
316 else if(const AbstractTypeConversion* converter = _self->converterTo<Value>(_conversion))
317 {
318 Value val;
319 cres_try(cres_ignore, converter->convert(_self->data(), &val));
320 return val.value<_T_>();
321 }
322 // Third some types have custom converters from Value (mostly knowRDF::Literal)
323 else if(const AbstractTypeConversion* converter
324 = _self->converterBetween<knowCore::Value, _T_>(_conversion))
325 {
326 _T_ val;
327 cres_try(cres_ignore, converter->convert(_self, &val));
328 return cres_success(val);
329 }
330 return cres_failure("cannot convert from '{}' to '{}'", _self->datatype(),
332 }
333 };
334 template<typename _T_>
335 struct Value_value<std::optional<_T_>>
336 {
337 static cres_qresult<std::optional<_T_>> value(const Value* _self,
338 TypeCheckingMode _conversion)
339 {
340 if(_self->isEmpty())
341 {
342 return cres_success<std::optional<_T_>>(std::nullopt);
343 }
344 else
345 {
346 return _self->value<_T_>();
347 }
348 }
349 };
350 } // namespace details
351
352 template<typename _T_>
353 inline cres_qresult<_T_> Value::value(TypeCheckingMode _conversion) const
354 {
355 return details::Value_value<_T_>::value(this, _conversion);
356 }
357 template<typename _T_>
358 inline _T_ Value::value(const _T_& _default, TypeCheckingMode _conversion) const
359 {
360 auto const& [s, v, m] = value<_T_>(_conversion);
361 return s ? v.value() : _default;
362 }
363 template<typename _T_>
364 inline bool Value::canConvert(TypeCheckingMode _conversion) const
365 {
366 return canConvert(MetaTypeInformation<_T_>::uri(), _conversion);
367 }
368 template<typename _T_>
369 inline bool Value::is() const
370 {
371 return definition()->uri() == MetaTypeInformation<_T_>::uri();
372 }
373 template<typename _T_>
374 inline cres_qresult<_T_> Value::fromJsonValue(const QJsonValue& _value,
375 const DeserialisationContexts& _context)
376 {
377 cres_try(knowCore::Value val, fromJsonValue(MetaTypeInformation<_T_>::uri(), _value, _context));
378 return val.template value<_T_>();
379 }
380
395 template<typename _T_>
397 {
398 public:
399 ValueCast(const knowCore::Value& _val, TypeCheckingMode _conversion = TypeCheckingMode::Safe)
400 {
401 auto const& [s, t, m] = _val.value<_T_>(_conversion);
402 m_success = s;
403 m_t = t;
404 }
405 operator bool() { return m_success; }
406 const _T_& value() const
407 {
408 clog_assert(m_success);
409 return m_t.value();
410 }
411 _T_& value()
412 {
413 clog_assert(m_success);
414 return m_t.value();
415 }
416 operator const _T_&() const { return value(); }
417 _T_* operator->() { return &value(); }
418 _T_* operator->() const { return &value(); }
419 _T_&& moveValue()
420 {
421 clog_assert(m_success);
422 return std::move(m_t.value());
423 }
424 private:
425 bool m_success;
426 std::optional<_T_> m_t;
427 };
443 template<typename _T_>
445 {
446 public:
447 ValueIs(const knowCore::Value& _val)
448 {
450 {
451 m_success = true;
452 m_t = _val.value<_T_>().expect_success();
453 }
454 else
455 {
456 m_success = false;
457 }
458 }
459 operator bool() { return m_success; }
460 const _T_& value() const
461 {
462 clog_assert(m_success);
463 return m_t;
464 }
465 _T_& value()
466 {
467 clog_assert(m_success);
468 return m_t;
469 }
470 operator const _T_&() const { return value(); }
471 _T_* operator->() { return &value(); }
472 _T_* operator->() const { return &value(); }
473 _T_&& moveValue() { return std::move(m_t); }
474 private:
475 bool m_success;
476 _T_ m_t;
477 };
478} // namespace knowCore
479
480clog_format_declare_formatter(knowCore::Value)
481{
482 auto const [success, value, message] = p.printable();
483 if(success)
484 {
485 return format_to(ctx.out(), "{}({})", p.datatype(), value.value());
486 }
487 else
488 {
489 return format_to(ctx.out(), "{}(error: '{}')", p.datatype(), message.value());
490 }
491}
492
493template<typename _T_>
494inline cres_qresult<_T_> cres_success(knowCore::ValueCast<_T_>& _t)
495{
496 return cres_success(_t.moveValue());
497}
498
499template<typename _T_>
500inline cres_qresult<_T_> cres_success(knowCore::ValueIs<_T_>& _t)
501{
502 return cres_success(_t.moveValue());
503}
504
505#include <knowCore/MetaType.h>
506KNOWCORE_DECLARE_FULL_METATYPE_NO_DEFINITION(knowCore, Value);
Definition MetaType.h:200
Definition MetaType.h:264
Definition MetaType.h:126
Definition MetaType.h:66
Definition MetaType.h:159
Definition Uri.h:15
Definition Value.h:397
Definition Value.h:445
Definition Value.h:21
bool isEmpty() const
Definition Value.cpp:234
cres_qresult< ValueList > toList() const
Definition Value.cpp:254
cres_qresult< Value > compute(const Value &_value, ArithmeticOperator _operator) const
Definition Value.cpp:396
Uri datatype() const
Definition Value.cpp:230
static cres_qresult< Value > fromVariant(const Uri &_datatype, const QVariant &_value, TypeCheckingMode _conversion=TypeCheckingMode::Safe)
Definition Value.cpp:135
cres_qresult< QCborMap > toCborMap(const SerialisationContexts &_contexts=defaultSerialisationContext()) const
Definition Value.cpp:629
cres_qresult< ValueHash > toHash() const
Definition Value.cpp:256
cres_qresult< bool > compare(const Value &_value, ComparisonOperators _operators) const
Definition Value.cpp:316
static cres_qresult< Value > fromCborMap(const QCborMap &_value, const DeserialisationContexts &_context=defaultDeserialisationContext())
Definition Value.cpp:637
cres_qresult< QJsonObject > toJsonObject(const SerialisationContexts &_contexts=defaultSerialisationContext()) const
Definition Value.cpp:615
static Value fromValue(const _T_ &_value)
Definition Value.h:241
bool operator!=(const Value &_rhs) const
Definition Value.h:103
cres_qresult< _T_ > value(TypeCheckingMode _conversion=TypeCheckingMode::Safe) const
Definition Value.h:353
Value()
Definition Value.cpp:111
bool operator<(const Value &_rhs) const
Definition Value.cpp:413
static cres_qresult< Value > fromJsonObject(const QJsonObject &_value, const DeserialisationContexts &_context=defaultDeserialisationContext())
Definition Value.cpp:623
QVariant toVariant() const
Definition Value.cpp:238
bool operator==(const Value &_rhs) const
Definition Value.cpp:427
static cres_qresult< Value > parseVariant(const QVariant &_value)
Definition Value.cpp:214
bool canConvert(TypeCheckingMode _conversion=TypeCheckingMode::Safe) const
Definition Value.h:364
Definition Value.h:300