knowL: Knowledge Libraries
Loading...
Searching...
No Matches
Value.h
1#pragma once
2
3#include <QSharedDataPointer>
4
5#include <knowCore/Forward.h>
6
7#include "MetaType.h"
8#include "ReturnValue.h"
9
10namespace knowCore
11{
12 class Value
13 {
14 Value(const Uri& _datatype, const AbstractMetaTypeDefinition* _definition, void* _data);
15 Value(const Uri& _datatype, const Uri& _maindatatype, const AbstractMetaTypeDefinition* _definition, void* _data);
16 public:
20 Value();
21 Value(const Value& _rhs);
22 Value& operator=(const Value& _rhs);
23 ~Value();
24
29 template<typename _T_>
30 static inline Value fromValue(const _T_& _value);
35 static inline ReturnValue<Value> fromValue(const QVariant& _value);
40 template<typename _T_>
41 static inline ReturnValue<Value> fromValue(const Uri& _datatype, const _T_& _value, TypeCheckingMode _conversion = TypeCheckingMode::Safe);
50 static ReturnValue<Value> fromVariant(const Uri& _datatype, const QVariant& _value, TypeCheckingMode _conversion = TypeCheckingMode::Safe);
55 static ReturnValue<Value> fromVariant(const QVariant& _variant);
56
60 QVariant toVariant() const;
64 Uri datatype() const;
68 bool isEmpty() const;
74 bool operator<(const Value& _rhs) const;
78 bool operator==(const Value& _rhs) const;
82 bool operator!=(const Value& _rhs) const { return not (*this == _rhs); }
86 ReturnValue<bool> compare(const Value& _value, ComparisonOperators _operators) const;
87 ReturnValue<Value> convert(const Uri& _uri, TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
91 ReturnValue<Value> compute(const Value& _value, ArithmeticOperator _operator) const;
97 template<typename _T_>
98 inline ReturnValue<_T_> value(TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
104 template<typename _T_>
105 inline _T_ value(const _T_& _default, TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
109 template<typename _T_>
110 inline bool canConvert(TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
114 bool canConvert(const Uri& _uri, TypeCheckingMode _conversion = TypeCheckingMode::Safe) const;
115 template<typename _T_>
116 inline bool is() const;
117 ReturnValue<QByteArray> md5() const;
118 ReturnValue<QJsonValue> toJsonValue(const SerialisationContexts& _contexts = defaultSerialisationContext()) const;
119 static ReturnValue<Value> fromJsonValue(const Uri& _datatype, const QJsonValue& _value, const DeserialisationContexts& _context = defaultDeserialisationContext());
120 template<typename _T_>
121 static ReturnValue<_T_> fromJsonValue(const QJsonValue& _value, const DeserialisationContexts& _context = defaultDeserialisationContext());
122 ReturnValue<QCborValue> toCborValue(const SerialisationContexts& _contexts = defaultSerialisationContext()) const;
123 static ReturnValue<Value> fromCborValue(const Uri& _datatype, const QCborValue& _value, const DeserialisationContexts& _context = defaultDeserialisationContext());
124 ReturnValue<QString> toRdfLiteral(const SerialisationContexts& _contexts = defaultSerialisationContext()) const;
125 static ReturnValue<Value> fromRdfLiteral(const Uri& _datatype, const QString& _value, const DeserialisationContexts& _context = defaultDeserialisationContext());
126 ReturnValue<QString> printable() const;
127
131 ReturnValue<QJsonObject> toJsonObject(const SerialisationContexts& _contexts = defaultSerialisationContext()) const;
135 static ReturnValue<Value> fromJsonObject(const QJsonObject& _value, const DeserialisationContexts& _context = defaultDeserialisationContext());
139 ReturnValue<QCborMap> toCborMap(const SerialisationContexts& _contexts = defaultSerialisationContext()) const;
143 static ReturnValue<Value> fromCborMap(const QCborMap& _value, const DeserialisationContexts& _context = defaultDeserialisationContext());
144
153 private:
154 const AbstractMetaTypeDefinition* definition() const;
155 private:
156 // Access to metatype stuff
157 template<typename _T_>
158 static const AbstractMetaTypeDefinition* getDefinition()
160 static const AbstractMetaTypeDefinition* getDefinition(const Uri& _datatype);
161 static const AbstractMetaTypeDefinition* getDefinition(int _id);
162 const void* data() const;
163 template<typename _T_>
164 const AbstractTypeConversion* converterTo(TypeCheckingMode _conversion) const
165 { return converterTo(MetaTypeInformation<_T_>::uri(), _conversion); }
166 const AbstractTypeConversion* converterTo(const Uri& _datatype, TypeCheckingMode _conversion) const;
167 template<typename _T_>
168 const AbstractTypeConversion* converterFrom(TypeCheckingMode _conversion) const
169 { return converterFrom(MetaTypeInformation<_T_>::uri()); }
170 const AbstractTypeConversion* converterFrom(const Uri& _datatype, TypeCheckingMode _conversion) const;
171 template<typename _TFrom_, typename _TTo_>
172 static const AbstractTypeConversion *converterBetween(TypeCheckingMode _conversion)
173 { return converterBetween(MetaTypeInformation<_TFrom_>::uri(), MetaTypeInformation<_TTo_>::uri(), _conversion);}
174 static const AbstractTypeConversion* converterBetween(const Uri& _from, const Uri& _to, TypeCheckingMode _conversion);
175
176 static const AbstractTypeConversion* converter(const Uri& _from, const Uri& _to, TypeCheckingMode _conversion);
177 private:
178 struct Private;
179 QSharedDataPointer<Private> d;
180 };
181 uint qHash(const Value& key, uint seed = 0);
182
183 template<typename _T_>
184 inline Value Value::fromValue(const _T_& _value)
185 {
186 const AbstractMetaTypeDefinition* def = getDefinition<_T_>();
187 KNOWCORE_ASSERT(def);
188 return Value(def->uri(), def, def->duplicate(&_value));
189 }
190 template<typename _T_>
191 inline ReturnValue<Value> Value::fromValue(const Uri& _datatype, const _T_& _value, TypeCheckingMode _conversion)
192 {
193 const AbstractMetaTypeDefinition* def_1 = getDefinition<_T_>();
194 const AbstractMetaTypeDefinition* def_2 = getDefinition(_datatype);
195 if(def_1 != def_2)
196 {
197 const AbstractTypeConversion* converter = Value::converter(MetaTypeInformation<_T_>::uri(), _datatype, _conversion);
198 if(converter)
199 {
200 void* data = def_2->allocate();
201 KNOWCORE_RETURN_VALUE_TRY_VOID(converter->convert(&_value, data));
202 return kCrvSuccess(Value(_datatype, def_2, data));
203 }
204 return kCrvError("{0} is not alias of type '{1}' with uri '{2}' and no conversion from '{2}' to '{0}'.", _datatype, prettyTypename<_T_>(), MetaTypeInformation<_T_>::uri());
205 }
206 if(def_1)
207 {
208 return kCrvSuccess(Value(_datatype, def_1, def_1->duplicate(&_value)));
209 } else {
210 return kCrvError("Type '{}' with datatype '{}' is not defined!", prettyTypename<_T_>(), _datatype);
211 }
212 }
213 template<>
214 inline ReturnValue<Value> Value::fromValue<knowCore::Value>(const Uri& _datatype, const knowCore::Value& _value, TypeCheckingMode _conversion)
215 {
216 return _value.convert(_datatype, _conversion);
217 }
218 inline ReturnValue<Value> Value::fromValue(const QVariant& _value)
219 {
220 return fromVariant(_value);
221 }
222 template<>
223 inline ReturnValue<Value> Value::fromValue<QVariant>(const Uri& _datatype, const QVariant& _value, TypeCheckingMode _conversion)
224 {
225 return fromVariant(_datatype, _value, _conversion);
226 }
227
228 template<typename _T_>
229 inline ReturnValue<_T_> Value::value(TypeCheckingMode _conversion) const
230 {
231 if(MetaTypeInformation<_T_>::uri() == datatype() or getDefinition<_T_>() == definition())
232 {
233 return kCrvSuccess(_T_(*reinterpret_cast<const _T_*>(data())));
234 }
235 // First: try to convert directly
236 if(const AbstractTypeConversion* converter = converterTo<_T_>(_conversion))
237 {
238 _T_ r;
239 converter->convert(data(), &r);
240 return kCrvSuccess(r);
241 } // Second: some types can be converted to a value (mostly usefull for knowRDF::Literal) and then from that value to _T_
242 else if(const AbstractTypeConversion* converter = converterTo<Value>(_conversion))
243 {
244 Value val;
245 KNOWCORE_RETURN_VALUE_TRY_VOID(converter->convert(data(), &val));
246 return val.value<_T_>();
247 }
248 // Third some types have custom converters from Value (mostly knowRDF::Literal)
249 else if(const AbstractTypeConversion* converter = converterBetween<knowCore::Value, _T_>(_conversion))
250 {
251 _T_ val;
252 KNOWCORE_RETURN_VALUE_TRY_VOID(converter->convert(this, &val));
253 return kCrvSuccess(val);
254 }
255 return kCrvError("cannot convert from '{}' to '{}'", datatype(), MetaTypeInformation<_T_>::uri());
256 }
257 template<typename _T_>
258 inline _T_ Value::value(const _T_& _default, TypeCheckingMode _conversion) const
259 {
260 auto const& [s, v, m] = value<_T_>(_conversion);
261 return s ? v : _default;
262 }
263 template<typename _T_>
264 inline bool Value::canConvert(TypeCheckingMode _conversion) const
265 {
266 return canConvert(MetaTypeInformation<_T_>::uri(), _conversion);
267 }
268 template<typename _T_>
269 inline bool Value::is() const
270 {
271 return definition()->uri() == MetaTypeInformation<_T_>::uri();
272 }
273 template<typename _T_>
274 inline ReturnValue<_T_> Value::fromJsonValue(const QJsonValue& _value, const DeserialisationContexts& _context)
275 {
276 KNOWCORE_RETURN_VALUE_TRY(val, fromJsonValue(MetaTypeInformation<_T_>::uri(), _value, _context));
277 return val.template value<_T_>();
278 }
279
294 template<typename _T_>
296 {
297 public:
298 ValueCast(const knowCore::Value& _val, TypeCheckingMode _conversion = TypeCheckingMode::Safe)
299 {
300 auto const& [s, t, m] = _val.value<_T_>(_conversion);
301 m_success = s;
302 m_t = t;
303 }
304 operator bool() { return m_success; }
305 const _T_& value() const {
306 KNOWCORE_ASSERT(m_success);
307 return m_t;
308 }
309 _T_& value() {
310 KNOWCORE_ASSERT(m_success);
311 return m_t;
312 }
313 operator const _T_&() const {
314 return value();
315 }
316 _T_* operator->() { return &value(); }
317 _T_* operator->() const { return &value(); }
318 private:
319 bool m_success;
320 _T_ m_t;
321 };
337 template<typename _T_>
339 {
340 public:
341 ValueIs(const knowCore::Value& _val)
342 {
344 {
345 m_success = true;
346 m_t = _val.value<_T_>().expectSuccess();
347 } else {
348 m_success = false;
349 }
350 }
351 operator bool() { return m_success; }
352 const _T_& value() const {
353 KNOWCORE_ASSERT(m_success);
354 return m_t;
355 }
356 _T_& value() {
357 KNOWCORE_ASSERT(m_success);
358 return m_t;
359 }
360 operator const _T_&() const {
361 return value();
362 }
363 _T_* operator->() { return &value(); }
364 _T_* operator->() const { return &value(); }
365 private:
366 bool m_success;
367 _T_ m_t;
368 };
369}
370
371KNOWCORE_CORE_DECLARE_FORMATTER(knowCore::Value)
372{
373 auto const [success, value, message] = p.printable();
374 if(success)
375 {
376 return format_to(ctx.out(),
377 "{}({})",
378 p.datatype(),
379 value);
380 } else {
381 return format_to(ctx.out(),
382 "{}(error: '{}')", p.datatype(), message);
383 }
384}
385
386#include <knowCore/MetaType.h>
387KNOWCORE_DECLARE_FULL_METATYPE_NO_DEFINITION(knowCore, Value)
Definition MetaType.h:184
Definition MetaType.h:236
Definition MetaType.h:114
Definition MetaType.h:58
Definition ReturnValue.h:29
Definition MetaType.h:145
Definition Uri.h:14
Definition Value.h:296
Definition Value.h:339
Definition Value.h:13
static ReturnValue< Value > fromCborMap(const QCborMap &_value, const DeserialisationContexts &_context=defaultDeserialisationContext())
Definition Value.cpp:580
ReturnValue< QCborMap > toCborMap(const SerialisationContexts &_contexts=defaultSerialisationContext()) const
Definition Value.cpp:572
bool isEmpty() const
Definition Value.cpp:209
static ReturnValue< Value > fromJsonObject(const QJsonObject &_value, const DeserialisationContexts &_context=defaultDeserialisationContext())
Definition Value.cpp:567
Uri datatype() const
Definition Value.cpp:199
ReturnValue< Value > compute(const Value &_value, ArithmeticOperator _operator) const
Definition Value.cpp:368
static Value fromValue(const _T_ &_value)
Definition Value.h:184
ReturnValue< bool > compare(const Value &_value, ComparisonOperators _operators) const
Definition Value.cpp:299
static ReturnValue< Value > fromVariant(const Uri &_datatype, const QVariant &_value, TypeCheckingMode _conversion=TypeCheckingMode::Safe)
Definition Value.cpp:140
ReturnValue< _T_ > value(TypeCheckingMode _conversion=TypeCheckingMode::Safe) const
Definition Value.h:229
bool operator!=(const Value &_rhs) const
Definition Value.h:82
ReturnValue< QJsonObject > toJsonObject(const SerialisationContexts &_contexts=defaultSerialisationContext()) const
Definition Value.cpp:559
Value()
Definition Value.cpp:112
bool operator<(const Value &_rhs) const
Definition Value.cpp:381
ReturnValue< ValueHash > toHash() const
Definition Value.cpp:237
QVariant toVariant() const
Definition Value.cpp:219
bool operator==(const Value &_rhs) const
Definition Value.cpp:393
ReturnValue< ValueList > toList() const
Definition Value.cpp:232
bool canConvert(TypeCheckingMode _conversion=TypeCheckingMode::Safe) const
Definition Value.h:264