cpp-common/bt2: add asConst() methods
[babeltrace.git] / src / cpp-common / bt2 / value.hpp
1 /*
2 * Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 #ifndef BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
9
10 #include <cstdint>
11 #include <functional>
12 #include <type_traits>
13
14 #include <babeltrace2/babeltrace.h>
15
16 #include "common/assert.h"
17 #include "common/common.h"
18 #include "cpp-common/optional.hpp"
19 #include "cpp-common/string_view.hpp"
20
21 #include "borrowed-object.hpp"
22 #include "common-iterator.hpp"
23 #include "exc.hpp"
24 #include "internal/utils.hpp"
25 #include "shared-object.hpp"
26
27 namespace bt2 {
28 namespace internal {
29
30 struct ValueRefFuncs final
31 {
32 static void get(const bt_value * const libObjPtr) noexcept
33 {
34 bt_value_get_ref(libObjPtr);
35 }
36
37 static void put(const bt_value * const libObjPtr) noexcept
38 {
39 bt_value_put_ref(libObjPtr);
40 }
41 };
42
43 } /* namespace internal */
44
45 template <typename ObjT, typename LibObjT>
46 using SharedValue = SharedObject<ObjT, LibObjT, internal::ValueRefFuncs>;
47
48 template <typename LibObjT>
49 class CommonNullValue;
50
51 template <typename LibObjT>
52 class CommonBoolValue;
53
54 template <typename LibObjT>
55 class CommonUnsignedIntegerValue;
56
57 template <typename LibObjT>
58 class CommonSignedIntegerValue;
59
60 template <typename LibObjT>
61 class CommonRealValue;
62
63 template <typename LibObjT>
64 class CommonStringValue;
65
66 template <typename LibObjT>
67 class CommonArrayValue;
68
69 template <typename LibObjT>
70 class CommonMapValue;
71
72 enum class ValueType
73 {
74 NUL = BT_VALUE_TYPE_NULL,
75 BOOL = BT_VALUE_TYPE_BOOL,
76 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
77 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
78 REAL = BT_VALUE_TYPE_REAL,
79 STRING = BT_VALUE_TYPE_STRING,
80 ARRAY = BT_VALUE_TYPE_ARRAY,
81 MAP = BT_VALUE_TYPE_MAP,
82 };
83
84 template <typename LibObjT>
85 class CommonValue : public BorrowedObject<LibObjT>
86 {
87 private:
88 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
89
90 protected:
91 using typename BorrowedObject<LibObjT>::_LibObjPtr;
92 using _ThisCommonValue = CommonValue<LibObjT>;
93
94 public:
95 using Shared = SharedValue<CommonValue<LibObjT>, LibObjT>;
96
97 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
98 {
99 }
100
101 template <typename OtherLibObjT>
102 CommonValue(const CommonValue<OtherLibObjT> val) noexcept : _ThisBorrowedObject {val}
103 {
104 }
105
106 template <typename OtherLibObjT>
107 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT> val) noexcept
108 {
109 _ThisBorrowedObject::operator=(val);
110 return *this;
111 }
112
113 CommonValue<const bt_value> asConst() const noexcept
114 {
115 return CommonValue<const bt_value> {*this};
116 }
117
118 ValueType type() const noexcept
119 {
120 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
121 }
122
123 bool isNull() const noexcept
124 {
125 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
126 }
127
128 bool isBool() const noexcept
129 {
130 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
131 }
132
133 bool isInteger() const noexcept
134 {
135 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
136 }
137
138 bool isUnsignedInteger() const noexcept
139 {
140 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
141 }
142
143 bool isSignedInteger() const noexcept
144 {
145 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
146 }
147
148 bool isReal() const noexcept
149 {
150 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
151 }
152
153 bool isString() const noexcept
154 {
155 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
156 }
157
158 bool isArray() const noexcept
159 {
160 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
161 }
162
163 bool isMap() const noexcept
164 {
165 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
166 }
167
168 template <typename OtherLibObjT>
169 bool operator==(const CommonValue<OtherLibObjT> other) const noexcept
170 {
171 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
172 }
173
174 template <typename OtherLibObjT>
175 bool operator!=(const CommonValue<OtherLibObjT> other) const noexcept
176 {
177 return !(*this == other);
178 }
179
180 Shared shared() const noexcept
181 {
182 return Shared::createWithRef(*this);
183 }
184
185 template <typename ValueT>
186 ValueT as() const noexcept
187 {
188 return ValueT {this->libObjPtr()};
189 }
190
191 CommonNullValue<LibObjT> asNull() const noexcept;
192 CommonBoolValue<LibObjT> asBool() const noexcept;
193 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
194 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
195 CommonRealValue<LibObjT> asReal() const noexcept;
196 CommonStringValue<LibObjT> asString() const noexcept;
197 CommonArrayValue<LibObjT> asArray() const noexcept;
198 CommonMapValue<LibObjT> asMap() const noexcept;
199
200 protected:
201 bool _libTypeIs(const bt_value_type type) const noexcept
202 {
203 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
204 }
205 };
206
207 using Value = CommonValue<bt_value>;
208 using ConstValue = CommonValue<const bt_value>;
209
210 namespace internal {
211
212 struct ValueTypeDescr
213 {
214 using Const = ConstValue;
215 using NonConst = Value;
216 };
217
218 template <>
219 struct TypeDescr<Value> : public ValueTypeDescr
220 {
221 };
222
223 template <>
224 struct TypeDescr<ConstValue> : public ValueTypeDescr
225 {
226 };
227
228 } /* namespace internal */
229
230 template <typename LibObjT>
231 class CommonNullValue final : public CommonValue<LibObjT>
232 {
233 private:
234 using typename CommonValue<LibObjT>::_ThisCommonValue;
235
236 public:
237 using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
238
239 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
240 {
241 }
242
243 template <typename OtherLibObjT>
244 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
245 {
246 }
247
248 template <typename OtherLibObjT>
249 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT> val) noexcept
250 {
251 _ThisCommonValue::operator=(val);
252 return *this;
253 }
254
255 CommonNullValue<const bt_value> asConst() const noexcept
256 {
257 return CommonNullValue<const bt_value> {*this};
258 }
259
260 Shared shared() const noexcept
261 {
262 return Shared::createWithRef(*this);
263 }
264 };
265
266 using NullValue = CommonNullValue<bt_value>;
267 using ConstNullValue = CommonNullValue<const bt_value>;
268
269 namespace internal {
270
271 struct NullValueTypeDescr
272 {
273 using Const = ConstNullValue;
274 using NonConst = NullValue;
275 };
276
277 template <>
278 struct TypeDescr<NullValue> : public NullValueTypeDescr
279 {
280 };
281
282 template <>
283 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
284 {
285 };
286
287 } /* namespace internal */
288
289 template <typename LibObjT>
290 class CommonBoolValue final : public CommonValue<LibObjT>
291 {
292 private:
293 using typename CommonValue<LibObjT>::_LibObjPtr;
294 using typename CommonValue<LibObjT>::_ThisCommonValue;
295
296 public:
297 using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
298 using Value = bool;
299
300 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
301 {
302 BT_ASSERT_DBG(this->isBool());
303 }
304
305 template <typename OtherLibObjT>
306 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
307 {
308 }
309
310 static Shared create(const Value rawVal = false)
311 {
312 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
313
314 internal::validateCreatedObjPtr(libObjPtr);
315 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
316 }
317
318 template <typename OtherLibObjT>
319 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
320 {
321 _ThisCommonValue::operator=(val);
322 return *this;
323 }
324
325 CommonBoolValue<const bt_value> asConst() const noexcept
326 {
327 return CommonBoolValue<const bt_value> {*this};
328 }
329
330 CommonBoolValue<LibObjT> operator=(const Value rawVal) const noexcept
331 {
332 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
333
334 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(rawVal));
335 return *this;
336 }
337
338 Value value() const noexcept
339 {
340 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
341 }
342
343 operator Value() const noexcept
344 {
345 return this->value();
346 }
347
348 Shared shared() const noexcept
349 {
350 return Shared::createWithRef(*this);
351 }
352 };
353
354 using BoolValue = CommonBoolValue<bt_value>;
355 using ConstBoolValue = CommonBoolValue<const bt_value>;
356
357 namespace internal {
358
359 struct BoolValueTypeDescr
360 {
361 using Const = ConstBoolValue;
362 using NonConst = BoolValue;
363 };
364
365 template <>
366 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
367 {
368 };
369
370 template <>
371 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
372 {
373 };
374
375 } /* namespace internal */
376
377 template <typename LibObjT>
378 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
379 {
380 private:
381 using typename CommonValue<LibObjT>::_LibObjPtr;
382 using typename CommonValue<LibObjT>::_ThisCommonValue;
383
384 public:
385 using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
386 using Value = std::uint64_t;
387
388 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
389 _ThisCommonValue {libObjPtr}
390 {
391 BT_ASSERT_DBG(this->isUnsignedInteger());
392 }
393
394 static Shared create(const Value rawVal = 0)
395 {
396 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
397
398 internal::validateCreatedObjPtr(libObjPtr);
399 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
400 }
401
402 template <typename OtherLibObjT>
403 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
404 _ThisCommonValue {val}
405 {
406 }
407
408 template <typename OtherLibObjT>
409 CommonUnsignedIntegerValue<LibObjT>&
410 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
411 {
412 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
413
414 _ThisCommonValue::operator=(val);
415 return *this;
416 }
417
418 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
419 {
420 return CommonUnsignedIntegerValue<const bt_value> {*this};
421 }
422
423 CommonUnsignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
424 {
425 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
426 return *this;
427 }
428
429 Value value() const noexcept
430 {
431 return bt_value_integer_unsigned_get(this->libObjPtr());
432 }
433
434 operator Value() const noexcept
435 {
436 return this->value();
437 }
438
439 Shared shared() const noexcept
440 {
441 return Shared::createWithRef(*this);
442 }
443 };
444
445 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
446 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
447
448 namespace internal {
449
450 struct UnsignedIntegerValueTypeDescr
451 {
452 using Const = ConstUnsignedIntegerValue;
453 using NonConst = UnsignedIntegerValue;
454 };
455
456 template <>
457 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
458 {
459 };
460
461 template <>
462 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
463 {
464 };
465
466 } /* namespace internal */
467
468 template <typename LibObjT>
469 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
470 {
471 private:
472 using typename CommonValue<LibObjT>::_LibObjPtr;
473 using typename CommonValue<LibObjT>::_ThisCommonValue;
474
475 public:
476 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
477 using Value = std::int64_t;
478
479 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
480 _ThisCommonValue {libObjPtr}
481 {
482 BT_ASSERT_DBG(this->isSignedInteger());
483 }
484
485 static Shared create(const Value rawVal = 0)
486 {
487 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
488
489 internal::validateCreatedObjPtr(libObjPtr);
490 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
491 }
492
493 template <typename OtherLibObjT>
494 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
495 _ThisCommonValue {val}
496 {
497 }
498
499 template <typename OtherLibObjT>
500 CommonSignedIntegerValue<LibObjT>
501 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
502 {
503 _ThisCommonValue::operator=(val);
504 return *this;
505 }
506
507 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
508 {
509 return CommonSignedIntegerValue<const bt_value> {*this};
510 }
511
512 CommonSignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
513 {
514 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
515
516 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
517 return *this;
518 }
519
520 Value value() const noexcept
521 {
522 return bt_value_integer_signed_get(this->libObjPtr());
523 }
524
525 operator Value() const noexcept
526 {
527 return this->value();
528 }
529
530 Shared shared() const noexcept
531 {
532 return Shared::createWithRef(*this);
533 }
534 };
535
536 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
537 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
538
539 namespace internal {
540
541 struct SignedIntegerValueTypeDescr
542 {
543 using Const = ConstSignedIntegerValue;
544 using NonConst = SignedIntegerValue;
545 };
546
547 template <>
548 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
549 {
550 };
551
552 template <>
553 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
554 {
555 };
556
557 } /* namespace internal */
558
559 template <typename LibObjT>
560 class CommonRealValue final : public CommonValue<LibObjT>
561 {
562 private:
563 using typename CommonValue<LibObjT>::_LibObjPtr;
564 using typename CommonValue<LibObjT>::_ThisCommonValue;
565
566 public:
567 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
568 using Value = double;
569
570 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
571 {
572 BT_ASSERT_DBG(this->isReal());
573 }
574
575 static Shared create(const Value rawVal = 0)
576 {
577 const auto libObjPtr = bt_value_real_create_init(rawVal);
578
579 internal::validateCreatedObjPtr(libObjPtr);
580 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
581 }
582
583 template <typename OtherLibObjT>
584 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
585 {
586 }
587
588 template <typename OtherLibObjT>
589 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT> val) noexcept
590 {
591 _ThisCommonValue::operator=(val);
592 return *this;
593 }
594
595 CommonRealValue<const bt_value> asConst() const noexcept
596 {
597 return CommonRealValue<const bt_value> {*this};
598 }
599
600 CommonRealValue<LibObjT> operator=(const Value rawVal) const noexcept
601 {
602 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
603
604 bt_value_real_set(this->libObjPtr(), rawVal);
605 return *this;
606 }
607
608 Value value() const noexcept
609 {
610 return bt_value_real_get(this->libObjPtr());
611 }
612
613 operator Value() const noexcept
614 {
615 return this->value();
616 }
617
618 Shared shared() const noexcept
619 {
620 return Shared::createWithRef(*this);
621 }
622 };
623
624 using RealValue = CommonRealValue<bt_value>;
625 using ConstRealValue = CommonRealValue<const bt_value>;
626
627 namespace internal {
628
629 struct RealValueTypeDescr
630 {
631 using Const = ConstRealValue;
632 using NonConst = RealValue;
633 };
634
635 template <>
636 struct TypeDescr<RealValue> : public RealValueTypeDescr
637 {
638 };
639
640 template <>
641 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
642 {
643 };
644
645 } /* namespace internal */
646
647 template <typename LibObjT>
648 class CommonStringValue final : public CommonValue<LibObjT>
649 {
650 private:
651 using typename CommonValue<LibObjT>::_LibObjPtr;
652 using typename CommonValue<LibObjT>::_ThisCommonValue;
653
654 public:
655 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
656
657 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
658 {
659 BT_ASSERT_DBG(this->isString());
660 }
661
662 static Shared create(const char * const rawVal = "")
663 {
664 const auto libObjPtr = bt_value_string_create_init(rawVal);
665
666 internal::validateCreatedObjPtr(libObjPtr);
667 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
668 }
669
670 static Shared create(const std::string& rawVal)
671 {
672 return CommonStringValue::create(rawVal.data());
673 }
674
675 template <typename OtherLibObjT>
676 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
677 {
678 }
679
680 template <typename OtherLibObjT>
681 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT> val) noexcept
682 {
683 _ThisCommonValue::operator=(val);
684 return *this;
685 }
686
687 CommonStringValue<const bt_value> asConst() const noexcept
688 {
689 return CommonStringValue<const bt_value> {*this};
690 }
691
692 CommonStringValue<LibObjT> operator=(const char * const rawVal) const
693 {
694 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
695
696 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
697
698 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
699 throw MemoryError {};
700 }
701
702 return *this;
703 }
704
705 CommonStringValue<LibObjT> operator=(const std::string& rawVal) const noexcept
706 {
707 return *this = rawVal.data();
708 }
709
710 bpstd::string_view value() const noexcept
711 {
712 return bt_value_string_get(this->libObjPtr());
713 }
714
715 Shared shared() const noexcept
716 {
717 return Shared::createWithRef(*this);
718 }
719 };
720
721 using StringValue = CommonStringValue<bt_value>;
722 using ConstStringValue = CommonStringValue<const bt_value>;
723
724 namespace internal {
725
726 struct StringValueTypeDescr
727 {
728 using Const = ConstStringValue;
729 using NonConst = StringValue;
730 };
731
732 template <>
733 struct TypeDescr<StringValue> : public StringValueTypeDescr
734 {
735 };
736
737 template <>
738 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
739 {
740 };
741
742 template <typename LibObjT>
743 struct CommonArrayValueSpec;
744
745 /* Functions specific to mutable array values */
746 template <>
747 struct CommonArrayValueSpec<bt_value> final
748 {
749 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
750 {
751 return bt_value_array_borrow_element_by_index(libValPtr, index);
752 }
753 };
754
755 /* Functions specific to constant array values */
756 template <>
757 struct CommonArrayValueSpec<const bt_value> final
758 {
759 static const bt_value *elementByIndex(const bt_value * const libValPtr,
760 const std::uint64_t index) noexcept
761 {
762 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
763 }
764 };
765
766 } /* namespace internal */
767
768 template <typename LibObjT>
769 class CommonArrayValue final : public CommonValue<LibObjT>
770 {
771 private:
772 using typename CommonValue<LibObjT>::_LibObjPtr;
773 using typename CommonValue<LibObjT>::_ThisCommonValue;
774
775 public:
776 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
777 using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
778
779 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
780 {
781 BT_ASSERT_DBG(this->isArray());
782 }
783
784 static Shared create()
785 {
786 const auto libObjPtr = bt_value_array_create();
787
788 internal::validateCreatedObjPtr(libObjPtr);
789 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
790 }
791
792 template <typename OtherLibObjT>
793 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
794 {
795 }
796
797 template <typename OtherLibObjT>
798 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
799 {
800 _ThisCommonValue::operator=(val);
801 return *this;
802 }
803
804 CommonArrayValue<const bt_value> asConst() const noexcept
805 {
806 return CommonArrayValue<const bt_value> {*this};
807 }
808
809 std::uint64_t length() const noexcept
810 {
811 return bt_value_array_get_length(this->libObjPtr());
812 }
813
814 Iterator begin() const noexcept
815 {
816 return Iterator {*this, 0};
817 }
818
819 Iterator end() const noexcept
820 {
821 return Iterator {*this, this->length()};
822 }
823
824 bool isEmpty() const noexcept
825 {
826 return this->length() == 0;
827 }
828
829 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
830 {
831 return CommonValue<LibObjT> {
832 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
833 }
834
835 void append(const Value val) const
836 {
837 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
838
839 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
840
841 this->_handleAppendLibStatus(status);
842 }
843
844 void append(const bool rawVal) const
845 {
846 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
847
848 const auto status =
849 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
850
851 this->_handleAppendLibStatus(status);
852 }
853
854 void append(const std::uint64_t rawVal) const
855 {
856 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
857
858 const auto status =
859 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
860
861 this->_handleAppendLibStatus(status);
862 }
863
864 void append(const std::int64_t rawVal) const
865 {
866 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
867
868 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
869
870 this->_handleAppendLibStatus(status);
871 }
872
873 void append(const double rawVal) const
874 {
875 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
876
877 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
878
879 this->_handleAppendLibStatus(status);
880 }
881
882 void append(const char * const rawVal) const
883 {
884 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
885
886 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
887
888 this->_handleAppendLibStatus(status);
889 }
890
891 void append(const std::string& rawVal) const
892 {
893 this->append(rawVal.data());
894 }
895
896 CommonArrayValue<bt_value> appendEmptyArray() const;
897 CommonMapValue<bt_value> appendEmptyMap() const;
898
899 void operator+=(const Value val) const
900 {
901 this->append(val);
902 }
903
904 void operator+=(const bool rawVal) const
905 {
906 this->append(rawVal);
907 }
908
909 void operator+=(const std::uint64_t rawVal) const
910 {
911 this->append(rawVal);
912 }
913
914 void operator+=(const std::int64_t rawVal) const
915 {
916 this->append(rawVal);
917 }
918
919 void operator+=(const double rawVal) const
920 {
921 this->append(rawVal);
922 }
923
924 void operator+=(const char * const rawVal) const
925 {
926 this->append(rawVal);
927 }
928
929 void operator+=(const std::string& rawVal) const
930 {
931 this->append(rawVal);
932 }
933
934 Shared shared() const noexcept
935 {
936 return Shared::createWithRef(*this);
937 }
938
939 private:
940 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
941 {
942 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
943 throw MemoryError {};
944 }
945 }
946 };
947
948 using ArrayValue = CommonArrayValue<bt_value>;
949 using ConstArrayValue = CommonArrayValue<const bt_value>;
950
951 namespace internal {
952
953 struct ArrayValueTypeDescr
954 {
955 using Const = ConstArrayValue;
956 using NonConst = ArrayValue;
957 };
958
959 template <>
960 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
961 {
962 };
963
964 template <>
965 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
966 {
967 };
968
969 /*
970 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
971 *
972 * First argument is the entry's key, second is its value.
973 */
974 template <typename ObjT>
975 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
976
977 /*
978 * Template of a function to be passed to bt_value_map_foreach_entry()
979 * for bt_value_map_foreach_entry_const() which calls a user function.
980 *
981 * `userData` is casted to a `const` pointer to
982 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
983 *
984 * This function catches any exception which the user function throws
985 * and returns the `ErrorStatus` value. If there's no execption, this
986 * function returns the `OkStatus` value.
987 */
988 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
989 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
990 void * const userData)
991 {
992 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
993
994 try {
995 userFunc(key, ObjT {libObjPtr});
996 } catch (...) {
997 return static_cast<LibStatusT>(ErrorStatus);
998 }
999
1000 return static_cast<LibStatusT>(OkStatus);
1001 }
1002
1003 template <typename LibObjT>
1004 struct CommonMapValueSpec;
1005
1006 /* Functions specific to mutable map values */
1007 template <>
1008 struct CommonMapValueSpec<bt_value> final
1009 {
1010 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1011 {
1012 return bt_value_map_borrow_entry_value(libValPtr, key);
1013 }
1014
1015 static void forEach(bt_value * const libValPtr,
1016 const CommonMapValueForEachUserFunc<Value>& func)
1017 {
1018 const auto status = bt_value_map_foreach_entry(
1019 libValPtr,
1020 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1021 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1022 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1023 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1024
1025 switch (status) {
1026 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1027 return;
1028 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1029 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1030 throw Error {};
1031 default:
1032 bt_common_abort();
1033 }
1034 }
1035 };
1036
1037 /* Functions specific to constant map values */
1038 template <>
1039 struct CommonMapValueSpec<const bt_value> final
1040 {
1041 static const bt_value *entryByKey(const bt_value * const libValPtr,
1042 const char * const key) noexcept
1043 {
1044 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1045 }
1046
1047 static void forEach(const bt_value * const libValPtr,
1048 const CommonMapValueForEachUserFunc<ConstValue>& func)
1049 {
1050 const auto status = bt_value_map_foreach_entry_const(
1051 libValPtr,
1052 mapValueForEachLibFunc<ConstValue, const bt_value,
1053 bt_value_map_foreach_entry_const_func_status,
1054 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1055 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1056 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1057
1058 switch (status) {
1059 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1060 return;
1061 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1062 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1063 throw Error {};
1064 default:
1065 bt_common_abort();
1066 }
1067 }
1068 };
1069
1070 } /* namespace internal */
1071
1072 template <typename LibObjT>
1073 class CommonMapValue final : public CommonValue<LibObjT>
1074 {
1075 private:
1076 using typename CommonValue<LibObjT>::_LibObjPtr;
1077 using typename CommonValue<LibObjT>::_ThisCommonValue;
1078
1079 public:
1080 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1081
1082 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1083 {
1084 BT_ASSERT_DBG(this->isMap());
1085 }
1086
1087 static Shared create()
1088 {
1089 const auto libObjPtr = bt_value_map_create();
1090
1091 internal::validateCreatedObjPtr(libObjPtr);
1092 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1093 }
1094
1095 template <typename OtherLibObjT>
1096 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1097 {
1098 }
1099
1100 template <typename OtherLibObjT>
1101 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1102 {
1103 _ThisCommonValue::operator=(val);
1104 return *this;
1105 }
1106
1107 CommonMapValue<const bt_value> asConst() const noexcept
1108 {
1109 return CommonMapValue<const bt_value> {*this};
1110 }
1111
1112 std::uint64_t length() const noexcept
1113 {
1114 return bt_value_map_get_size(this->libObjPtr());
1115 }
1116
1117 bool isEmpty() const noexcept
1118 {
1119 return this->length() == 0;
1120 }
1121
1122 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) const noexcept
1123 {
1124 const auto libObjPtr =
1125 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1126
1127 if (!libObjPtr) {
1128 return nonstd::nullopt;
1129 }
1130
1131 return CommonValue<LibObjT> {libObjPtr};
1132 }
1133
1134 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) const noexcept
1135 {
1136 return (*this)[key.data()];
1137 }
1138
1139 bool hasEntry(const char * const key) const noexcept
1140 {
1141 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1142 }
1143
1144 bool hasEntry(const std::string& key) const noexcept
1145 {
1146 return this->hasEntry(key.data());
1147 }
1148
1149 void insert(const char * const key, const Value val) const
1150 {
1151 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1152
1153 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1154
1155 this->_handleInsertLibStatus(status);
1156 }
1157
1158 void insert(const std::string& key, const Value val) const
1159 {
1160 this->insert(key.data(), val);
1161 }
1162
1163 void insert(const char * const key, const bool rawVal) const
1164 {
1165 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1166
1167 const auto status =
1168 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1169
1170 this->_handleInsertLibStatus(status);
1171 }
1172
1173 void insert(const std::string& key, const bool rawVal) const
1174 {
1175 this->insert(key.data(), rawVal);
1176 }
1177
1178 void insert(const char * const key, const std::uint64_t rawVal) const
1179 {
1180 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1181
1182 const auto status =
1183 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1184
1185 this->_handleInsertLibStatus(status);
1186 }
1187
1188 void insert(const std::string& key, const std::uint64_t rawVal) const
1189 {
1190 this->insert(key.data(), rawVal);
1191 }
1192
1193 void insert(const char * const key, const std::int64_t rawVal) const
1194 {
1195 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1196
1197 const auto status =
1198 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1199
1200 this->_handleInsertLibStatus(status);
1201 }
1202
1203 void insert(const std::string& key, const std::int64_t rawVal) const
1204 {
1205 this->insert(key.data(), rawVal);
1206 }
1207
1208 void insert(const char * const key, const double rawVal) const
1209 {
1210 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1211
1212 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1213
1214 this->_handleInsertLibStatus(status);
1215 }
1216
1217 void insert(const std::string& key, const double rawVal) const
1218 {
1219 this->insert(key.data(), rawVal);
1220 }
1221
1222 void insert(const char * const key, const char * const rawVal) const
1223 {
1224 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1225
1226 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1227
1228 this->_handleInsertLibStatus(status);
1229 }
1230
1231 void insert(const char * const key, const std::string& rawVal) const
1232 {
1233 this->insert(key, rawVal.data());
1234 }
1235
1236 void insert(const std::string& key, const char * const rawVal) const
1237 {
1238 this->insert(key.data(), rawVal);
1239 }
1240
1241 void insert(const std::string& key, const std::string& rawVal) const
1242 {
1243 this->insert(key.data(), rawVal.data());
1244 }
1245
1246 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
1247 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
1248 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
1249 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
1250
1251 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1252 {
1253 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1254 }
1255
1256 Shared shared() const noexcept
1257 {
1258 return Shared::createWithRef(*this);
1259 }
1260
1261 private:
1262 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1263 {
1264 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1265 throw MemoryError {};
1266 }
1267 }
1268 };
1269
1270 using MapValue = CommonMapValue<bt_value>;
1271 using ConstMapValue = CommonMapValue<const bt_value>;
1272
1273 namespace internal {
1274
1275 struct MapValueTypeDescr
1276 {
1277 using Const = ConstMapValue;
1278 using NonConst = MapValue;
1279 };
1280
1281 template <>
1282 struct TypeDescr<MapValue> : public MapValueTypeDescr
1283 {
1284 };
1285
1286 template <>
1287 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1288 {
1289 };
1290
1291 } /* namespace internal */
1292
1293 template <typename LibObjT>
1294 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1295 {
1296 BT_ASSERT_DBG(this->isNull());
1297 return CommonNullValue<LibObjT> {this->libObjPtr()};
1298 }
1299
1300 template <typename LibObjT>
1301 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1302 {
1303 BT_ASSERT_DBG(this->isBool());
1304 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1305 }
1306
1307 template <typename LibObjT>
1308 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1309 {
1310 BT_ASSERT_DBG(this->isSignedInteger());
1311 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1312 }
1313
1314 template <typename LibObjT>
1315 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1316 {
1317 BT_ASSERT_DBG(this->isUnsignedInteger());
1318 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1319 }
1320
1321 template <typename LibObjT>
1322 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1323 {
1324 BT_ASSERT_DBG(this->isReal());
1325 return CommonRealValue<LibObjT> {this->libObjPtr()};
1326 }
1327
1328 template <typename LibObjT>
1329 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1330 {
1331 BT_ASSERT_DBG(this->isString());
1332 return CommonStringValue<LibObjT> {this->libObjPtr()};
1333 }
1334
1335 template <typename LibObjT>
1336 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1337 {
1338 BT_ASSERT_DBG(this->isArray());
1339 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1340 }
1341
1342 template <typename LibObjT>
1343 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1344 {
1345 BT_ASSERT_DBG(this->isMap());
1346 return CommonMapValue<LibObjT> {this->libObjPtr()};
1347 }
1348
1349 template <typename LibObjT>
1350 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1351 {
1352 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1353
1354 bt_value *libElemPtr;
1355 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1356
1357 this->_handleAppendLibStatus(status);
1358 return ArrayValue {libElemPtr};
1359 }
1360
1361 template <typename LibObjT>
1362 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1363 {
1364 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1365
1366 bt_value *libElemPtr;
1367 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1368
1369 this->_handleAppendLibStatus(status);
1370 return MapValue {libElemPtr};
1371 }
1372
1373 template <typename LibObjT>
1374 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key) const
1375 {
1376 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1377
1378 bt_value *libEntryPtr;
1379 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1380
1381 this->_handleInsertLibStatus(status);
1382 return ArrayValue {libEntryPtr};
1383 }
1384
1385 template <typename LibObjT>
1386 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key) const
1387 {
1388 return this->insertEmptyArray(key.data());
1389 }
1390
1391 template <typename LibObjT>
1392 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key) const
1393 {
1394 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1395
1396 bt_value *libEntryPtr;
1397 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1398
1399 this->_handleInsertLibStatus(status);
1400 return MapValue {libEntryPtr};
1401 }
1402
1403 template <typename LibObjT>
1404 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key) const
1405 {
1406 return this->insertEmptyMap(key.data());
1407 }
1408
1409 inline BoolValue::Shared createValue(const bool rawVal)
1410 {
1411 return BoolValue::create(rawVal);
1412 }
1413
1414 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1415 {
1416 return UnsignedIntegerValue::create(rawVal);
1417 }
1418
1419 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1420 {
1421 return SignedIntegerValue::create(rawVal);
1422 }
1423
1424 inline RealValue::Shared createValue(const double rawVal)
1425 {
1426 return RealValue::create(rawVal);
1427 }
1428
1429 inline StringValue::Shared createValue(const char * const rawVal)
1430 {
1431 return StringValue::create(rawVal);
1432 }
1433
1434 inline StringValue::Shared createValue(const std::string& rawVal)
1435 {
1436 return StringValue::create(rawVal);
1437 }
1438
1439 } /* namespace bt2 */
1440
1441 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */
This page took 0.069267 seconds and 5 git commands to generate.