cpp-common/bt2/value.hpp: move static assertion (wrong place)
[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-iterator.hpp"
22 #include "borrowed-object.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, "Not available with `bt2::ConstBoolValue`.");
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 _ThisCommonValue::operator=(val);
413 return *this;
414 }
415
416 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
417 {
418 return CommonUnsignedIntegerValue<const bt_value> {*this};
419 }
420
421 CommonUnsignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
422 {
423 static_assert(!std::is_const<LibObjT>::value,
424 "Not available with `bt2::ConstUnsignedIntegerValue`.");
425
426 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
427 return *this;
428 }
429
430 Value value() const noexcept
431 {
432 return bt_value_integer_unsigned_get(this->libObjPtr());
433 }
434
435 operator Value() const noexcept
436 {
437 return this->value();
438 }
439
440 Shared shared() const noexcept
441 {
442 return Shared::createWithRef(*this);
443 }
444 };
445
446 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
447 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
448
449 namespace internal {
450
451 struct UnsignedIntegerValueTypeDescr
452 {
453 using Const = ConstUnsignedIntegerValue;
454 using NonConst = UnsignedIntegerValue;
455 };
456
457 template <>
458 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
459 {
460 };
461
462 template <>
463 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
464 {
465 };
466
467 } /* namespace internal */
468
469 template <typename LibObjT>
470 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
471 {
472 private:
473 using typename CommonValue<LibObjT>::_LibObjPtr;
474 using typename CommonValue<LibObjT>::_ThisCommonValue;
475
476 public:
477 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
478 using Value = std::int64_t;
479
480 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
481 _ThisCommonValue {libObjPtr}
482 {
483 BT_ASSERT_DBG(this->isSignedInteger());
484 }
485
486 static Shared create(const Value rawVal = 0)
487 {
488 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
489
490 internal::validateCreatedObjPtr(libObjPtr);
491 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
492 }
493
494 template <typename OtherLibObjT>
495 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
496 _ThisCommonValue {val}
497 {
498 }
499
500 template <typename OtherLibObjT>
501 CommonSignedIntegerValue<LibObjT>
502 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
503 {
504 _ThisCommonValue::operator=(val);
505 return *this;
506 }
507
508 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
509 {
510 return CommonSignedIntegerValue<const bt_value> {*this};
511 }
512
513 CommonSignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
514 {
515 static_assert(!std::is_const<LibObjT>::value,
516 "Not available with `bt2::ConstSignedIntegerValue`.");
517
518 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
519 return *this;
520 }
521
522 Value value() const noexcept
523 {
524 return bt_value_integer_signed_get(this->libObjPtr());
525 }
526
527 operator Value() const noexcept
528 {
529 return this->value();
530 }
531
532 Shared shared() const noexcept
533 {
534 return Shared::createWithRef(*this);
535 }
536 };
537
538 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
539 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
540
541 namespace internal {
542
543 struct SignedIntegerValueTypeDescr
544 {
545 using Const = ConstSignedIntegerValue;
546 using NonConst = SignedIntegerValue;
547 };
548
549 template <>
550 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
551 {
552 };
553
554 template <>
555 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
556 {
557 };
558
559 } /* namespace internal */
560
561 template <typename LibObjT>
562 class CommonRealValue final : public CommonValue<LibObjT>
563 {
564 private:
565 using typename CommonValue<LibObjT>::_LibObjPtr;
566 using typename CommonValue<LibObjT>::_ThisCommonValue;
567
568 public:
569 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
570 using Value = double;
571
572 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
573 {
574 BT_ASSERT_DBG(this->isReal());
575 }
576
577 static Shared create(const Value rawVal = 0)
578 {
579 const auto libObjPtr = bt_value_real_create_init(rawVal);
580
581 internal::validateCreatedObjPtr(libObjPtr);
582 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
583 }
584
585 template <typename OtherLibObjT>
586 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
587 {
588 }
589
590 template <typename OtherLibObjT>
591 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT> val) noexcept
592 {
593 _ThisCommonValue::operator=(val);
594 return *this;
595 }
596
597 CommonRealValue<const bt_value> asConst() const noexcept
598 {
599 return CommonRealValue<const bt_value> {*this};
600 }
601
602 CommonRealValue<LibObjT> operator=(const Value rawVal) const noexcept
603 {
604 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstRealValue`.");
605
606 bt_value_real_set(this->libObjPtr(), rawVal);
607 return *this;
608 }
609
610 Value value() const noexcept
611 {
612 return bt_value_real_get(this->libObjPtr());
613 }
614
615 operator Value() const noexcept
616 {
617 return this->value();
618 }
619
620 Shared shared() const noexcept
621 {
622 return Shared::createWithRef(*this);
623 }
624 };
625
626 using RealValue = CommonRealValue<bt_value>;
627 using ConstRealValue = CommonRealValue<const bt_value>;
628
629 namespace internal {
630
631 struct RealValueTypeDescr
632 {
633 using Const = ConstRealValue;
634 using NonConst = RealValue;
635 };
636
637 template <>
638 struct TypeDescr<RealValue> : public RealValueTypeDescr
639 {
640 };
641
642 template <>
643 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
644 {
645 };
646
647 } /* namespace internal */
648
649 template <typename LibObjT>
650 class CommonStringValue final : public CommonValue<LibObjT>
651 {
652 private:
653 using typename CommonValue<LibObjT>::_LibObjPtr;
654 using typename CommonValue<LibObjT>::_ThisCommonValue;
655
656 public:
657 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
658
659 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
660 {
661 BT_ASSERT_DBG(this->isString());
662 }
663
664 static Shared create(const char * const rawVal = "")
665 {
666 const auto libObjPtr = bt_value_string_create_init(rawVal);
667
668 internal::validateCreatedObjPtr(libObjPtr);
669 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
670 }
671
672 static Shared create(const std::string& rawVal)
673 {
674 return CommonStringValue::create(rawVal.data());
675 }
676
677 template <typename OtherLibObjT>
678 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
679 {
680 }
681
682 template <typename OtherLibObjT>
683 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT> val) noexcept
684 {
685 _ThisCommonValue::operator=(val);
686 return *this;
687 }
688
689 CommonStringValue<const bt_value> asConst() const noexcept
690 {
691 return CommonStringValue<const bt_value> {*this};
692 }
693
694 CommonStringValue<LibObjT> operator=(const char * const rawVal) const
695 {
696 static_assert(!std::is_const<LibObjT>::value,
697 "Not available with `bt2::ConstStringValue`.");
698
699 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
700
701 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
702 throw MemoryError {};
703 }
704
705 return *this;
706 }
707
708 CommonStringValue<LibObjT> operator=(const std::string& rawVal) const noexcept
709 {
710 return *this = rawVal.data();
711 }
712
713 bpstd::string_view value() const noexcept
714 {
715 return bt_value_string_get(this->libObjPtr());
716 }
717
718 Shared shared() const noexcept
719 {
720 return Shared::createWithRef(*this);
721 }
722 };
723
724 using StringValue = CommonStringValue<bt_value>;
725 using ConstStringValue = CommonStringValue<const bt_value>;
726
727 namespace internal {
728
729 struct StringValueTypeDescr
730 {
731 using Const = ConstStringValue;
732 using NonConst = StringValue;
733 };
734
735 template <>
736 struct TypeDescr<StringValue> : public StringValueTypeDescr
737 {
738 };
739
740 template <>
741 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
742 {
743 };
744
745 template <typename LibObjT>
746 struct CommonArrayValueSpec;
747
748 /* Functions specific to mutable array values */
749 template <>
750 struct CommonArrayValueSpec<bt_value> final
751 {
752 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
753 {
754 return bt_value_array_borrow_element_by_index(libValPtr, index);
755 }
756 };
757
758 /* Functions specific to constant array values */
759 template <>
760 struct CommonArrayValueSpec<const bt_value> final
761 {
762 static const bt_value *elementByIndex(const bt_value * const libValPtr,
763 const std::uint64_t index) noexcept
764 {
765 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
766 }
767 };
768
769 } /* namespace internal */
770
771 template <typename LibObjT>
772 class CommonArrayValue final : public CommonValue<LibObjT>
773 {
774 private:
775 using typename CommonValue<LibObjT>::_LibObjPtr;
776 using typename CommonValue<LibObjT>::_ThisCommonValue;
777
778 public:
779 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
780 using Iterator = BorrowedObjectIterator<CommonArrayValue<LibObjT>>;
781
782 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
783 {
784 BT_ASSERT_DBG(this->isArray());
785 }
786
787 static Shared create()
788 {
789 const auto libObjPtr = bt_value_array_create();
790
791 internal::validateCreatedObjPtr(libObjPtr);
792 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
793 }
794
795 template <typename OtherLibObjT>
796 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
797 {
798 }
799
800 template <typename OtherLibObjT>
801 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
802 {
803 _ThisCommonValue::operator=(val);
804 return *this;
805 }
806
807 CommonArrayValue<const bt_value> asConst() const noexcept
808 {
809 return CommonArrayValue<const bt_value> {*this};
810 }
811
812 std::uint64_t length() const noexcept
813 {
814 return bt_value_array_get_length(this->libObjPtr());
815 }
816
817 Iterator begin() const noexcept
818 {
819 return Iterator {*this, 0};
820 }
821
822 Iterator end() const noexcept
823 {
824 return Iterator {*this, this->length()};
825 }
826
827 bool isEmpty() const noexcept
828 {
829 return this->length() == 0;
830 }
831
832 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
833 {
834 return CommonValue<LibObjT> {
835 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
836 }
837
838 void append(const Value val) const
839 {
840 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
841
842 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
843
844 this->_handleAppendLibStatus(status);
845 }
846
847 void append(const bool rawVal) const
848 {
849 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
850
851 const auto status =
852 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
853
854 this->_handleAppendLibStatus(status);
855 }
856
857 void append(const std::uint64_t rawVal) const
858 {
859 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
860
861 const auto status =
862 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
863
864 this->_handleAppendLibStatus(status);
865 }
866
867 void append(const std::int64_t rawVal) const
868 {
869 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
870
871 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
872
873 this->_handleAppendLibStatus(status);
874 }
875
876 void append(const double rawVal) const
877 {
878 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
879
880 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
881
882 this->_handleAppendLibStatus(status);
883 }
884
885 void append(const char * const rawVal) const
886 {
887 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
888
889 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
890
891 this->_handleAppendLibStatus(status);
892 }
893
894 void append(const std::string& rawVal) const
895 {
896 this->append(rawVal.data());
897 }
898
899 CommonArrayValue<bt_value> appendEmptyArray() const;
900 CommonMapValue<bt_value> appendEmptyMap() const;
901
902 void operator+=(const Value val) const
903 {
904 this->append(val);
905 }
906
907 void operator+=(const bool rawVal) const
908 {
909 this->append(rawVal);
910 }
911
912 void operator+=(const std::uint64_t rawVal) const
913 {
914 this->append(rawVal);
915 }
916
917 void operator+=(const std::int64_t rawVal) const
918 {
919 this->append(rawVal);
920 }
921
922 void operator+=(const double rawVal) const
923 {
924 this->append(rawVal);
925 }
926
927 void operator+=(const char * const rawVal) const
928 {
929 this->append(rawVal);
930 }
931
932 void operator+=(const std::string& rawVal) const
933 {
934 this->append(rawVal);
935 }
936
937 Shared shared() const noexcept
938 {
939 return Shared::createWithRef(*this);
940 }
941
942 private:
943 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
944 {
945 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
946 throw MemoryError {};
947 }
948 }
949 };
950
951 using ArrayValue = CommonArrayValue<bt_value>;
952 using ConstArrayValue = CommonArrayValue<const bt_value>;
953
954 namespace internal {
955
956 struct ArrayValueTypeDescr
957 {
958 using Const = ConstArrayValue;
959 using NonConst = ArrayValue;
960 };
961
962 template <>
963 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
964 {
965 };
966
967 template <>
968 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
969 {
970 };
971
972 /*
973 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
974 *
975 * First argument is the entry's key, second is its value.
976 */
977 template <typename ObjT>
978 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
979
980 /*
981 * Template of a function to be passed to bt_value_map_foreach_entry()
982 * for bt_value_map_foreach_entry_const() which calls a user function.
983 *
984 * `userData` is casted to a `const` pointer to
985 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
986 *
987 * This function catches any exception which the user function throws
988 * and returns the `ErrorStatus` value. If there's no execption, this
989 * function returns the `OkStatus` value.
990 */
991 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
992 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
993 void * const userData)
994 {
995 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
996
997 try {
998 userFunc(key, ObjT {libObjPtr});
999 } catch (...) {
1000 return static_cast<LibStatusT>(ErrorStatus);
1001 }
1002
1003 return static_cast<LibStatusT>(OkStatus);
1004 }
1005
1006 template <typename LibObjT>
1007 struct CommonMapValueSpec;
1008
1009 /* Functions specific to mutable map values */
1010 template <>
1011 struct CommonMapValueSpec<bt_value> final
1012 {
1013 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1014 {
1015 return bt_value_map_borrow_entry_value(libValPtr, key);
1016 }
1017
1018 static void forEach(bt_value * const libValPtr,
1019 const CommonMapValueForEachUserFunc<Value>& func)
1020 {
1021 const auto status = bt_value_map_foreach_entry(
1022 libValPtr,
1023 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1024 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1025 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1026 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1027
1028 switch (status) {
1029 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1030 return;
1031 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1032 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1033 throw Error {};
1034 default:
1035 bt_common_abort();
1036 }
1037 }
1038 };
1039
1040 /* Functions specific to constant map values */
1041 template <>
1042 struct CommonMapValueSpec<const bt_value> final
1043 {
1044 static const bt_value *entryByKey(const bt_value * const libValPtr,
1045 const char * const key) noexcept
1046 {
1047 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1048 }
1049
1050 static void forEach(const bt_value * const libValPtr,
1051 const CommonMapValueForEachUserFunc<ConstValue>& func)
1052 {
1053 const auto status = bt_value_map_foreach_entry_const(
1054 libValPtr,
1055 mapValueForEachLibFunc<ConstValue, const bt_value,
1056 bt_value_map_foreach_entry_const_func_status,
1057 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1058 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1059 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1060
1061 switch (status) {
1062 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1063 return;
1064 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1065 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1066 throw Error {};
1067 default:
1068 bt_common_abort();
1069 }
1070 }
1071 };
1072
1073 } /* namespace internal */
1074
1075 template <typename LibObjT>
1076 class CommonMapValue final : public CommonValue<LibObjT>
1077 {
1078 private:
1079 using typename CommonValue<LibObjT>::_LibObjPtr;
1080 using typename CommonValue<LibObjT>::_ThisCommonValue;
1081
1082 public:
1083 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1084
1085 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1086 {
1087 BT_ASSERT_DBG(this->isMap());
1088 }
1089
1090 static Shared create()
1091 {
1092 const auto libObjPtr = bt_value_map_create();
1093
1094 internal::validateCreatedObjPtr(libObjPtr);
1095 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1096 }
1097
1098 template <typename OtherLibObjT>
1099 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1100 {
1101 }
1102
1103 template <typename OtherLibObjT>
1104 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1105 {
1106 _ThisCommonValue::operator=(val);
1107 return *this;
1108 }
1109
1110 CommonMapValue<const bt_value> asConst() const noexcept
1111 {
1112 return CommonMapValue<const bt_value> {*this};
1113 }
1114
1115 std::uint64_t length() const noexcept
1116 {
1117 return bt_value_map_get_size(this->libObjPtr());
1118 }
1119
1120 bool isEmpty() const noexcept
1121 {
1122 return this->length() == 0;
1123 }
1124
1125 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) const noexcept
1126 {
1127 const auto libObjPtr =
1128 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1129
1130 if (!libObjPtr) {
1131 return nonstd::nullopt;
1132 }
1133
1134 return CommonValue<LibObjT> {libObjPtr};
1135 }
1136
1137 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) const noexcept
1138 {
1139 return (*this)[key.data()];
1140 }
1141
1142 bool hasEntry(const char * const key) const noexcept
1143 {
1144 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1145 }
1146
1147 bool hasEntry(const std::string& key) const noexcept
1148 {
1149 return this->hasEntry(key.data());
1150 }
1151
1152 void insert(const char * const key, const Value val) const
1153 {
1154 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1155
1156 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1157
1158 this->_handleInsertLibStatus(status);
1159 }
1160
1161 void insert(const std::string& key, const Value val) const
1162 {
1163 this->insert(key.data(), val);
1164 }
1165
1166 void insert(const char * const key, const bool rawVal) const
1167 {
1168 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1169
1170 const auto status =
1171 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1172
1173 this->_handleInsertLibStatus(status);
1174 }
1175
1176 void insert(const std::string& key, const bool rawVal) const
1177 {
1178 this->insert(key.data(), rawVal);
1179 }
1180
1181 void insert(const char * const key, const std::uint64_t rawVal) const
1182 {
1183 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1184
1185 const auto status =
1186 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1187
1188 this->_handleInsertLibStatus(status);
1189 }
1190
1191 void insert(const std::string& key, const std::uint64_t rawVal) const
1192 {
1193 this->insert(key.data(), rawVal);
1194 }
1195
1196 void insert(const char * const key, const std::int64_t rawVal) const
1197 {
1198 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1199
1200 const auto status =
1201 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1202
1203 this->_handleInsertLibStatus(status);
1204 }
1205
1206 void insert(const std::string& key, const std::int64_t rawVal) const
1207 {
1208 this->insert(key.data(), rawVal);
1209 }
1210
1211 void insert(const char * const key, const double rawVal) const
1212 {
1213 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1214
1215 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1216
1217 this->_handleInsertLibStatus(status);
1218 }
1219
1220 void insert(const std::string& key, const double rawVal) const
1221 {
1222 this->insert(key.data(), rawVal);
1223 }
1224
1225 void insert(const char * const key, const char * const rawVal) const
1226 {
1227 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1228
1229 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1230
1231 this->_handleInsertLibStatus(status);
1232 }
1233
1234 void insert(const char * const key, const std::string& rawVal) const
1235 {
1236 this->insert(key, rawVal.data());
1237 }
1238
1239 void insert(const std::string& key, const char * const rawVal) const
1240 {
1241 this->insert(key.data(), rawVal);
1242 }
1243
1244 void insert(const std::string& key, const std::string& rawVal) const
1245 {
1246 this->insert(key.data(), rawVal.data());
1247 }
1248
1249 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
1250 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
1251 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
1252 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
1253
1254 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1255 {
1256 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1257 }
1258
1259 Shared shared() const noexcept
1260 {
1261 return Shared::createWithRef(*this);
1262 }
1263
1264 private:
1265 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1266 {
1267 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1268 throw MemoryError {};
1269 }
1270 }
1271 };
1272
1273 using MapValue = CommonMapValue<bt_value>;
1274 using ConstMapValue = CommonMapValue<const bt_value>;
1275
1276 namespace internal {
1277
1278 struct MapValueTypeDescr
1279 {
1280 using Const = ConstMapValue;
1281 using NonConst = MapValue;
1282 };
1283
1284 template <>
1285 struct TypeDescr<MapValue> : public MapValueTypeDescr
1286 {
1287 };
1288
1289 template <>
1290 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1291 {
1292 };
1293
1294 } /* namespace internal */
1295
1296 template <typename LibObjT>
1297 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1298 {
1299 BT_ASSERT_DBG(this->isNull());
1300 return CommonNullValue<LibObjT> {this->libObjPtr()};
1301 }
1302
1303 template <typename LibObjT>
1304 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1305 {
1306 BT_ASSERT_DBG(this->isBool());
1307 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1308 }
1309
1310 template <typename LibObjT>
1311 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1312 {
1313 BT_ASSERT_DBG(this->isSignedInteger());
1314 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1315 }
1316
1317 template <typename LibObjT>
1318 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1319 {
1320 BT_ASSERT_DBG(this->isUnsignedInteger());
1321 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1322 }
1323
1324 template <typename LibObjT>
1325 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1326 {
1327 BT_ASSERT_DBG(this->isReal());
1328 return CommonRealValue<LibObjT> {this->libObjPtr()};
1329 }
1330
1331 template <typename LibObjT>
1332 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1333 {
1334 BT_ASSERT_DBG(this->isString());
1335 return CommonStringValue<LibObjT> {this->libObjPtr()};
1336 }
1337
1338 template <typename LibObjT>
1339 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1340 {
1341 BT_ASSERT_DBG(this->isArray());
1342 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1343 }
1344
1345 template <typename LibObjT>
1346 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1347 {
1348 BT_ASSERT_DBG(this->isMap());
1349 return CommonMapValue<LibObjT> {this->libObjPtr()};
1350 }
1351
1352 template <typename LibObjT>
1353 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1354 {
1355 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1356
1357 bt_value *libElemPtr;
1358 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1359
1360 this->_handleAppendLibStatus(status);
1361 return ArrayValue {libElemPtr};
1362 }
1363
1364 template <typename LibObjT>
1365 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1366 {
1367 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1368
1369 bt_value *libElemPtr;
1370 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1371
1372 this->_handleAppendLibStatus(status);
1373 return MapValue {libElemPtr};
1374 }
1375
1376 template <typename LibObjT>
1377 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key) const
1378 {
1379 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1380
1381 bt_value *libEntryPtr;
1382 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1383
1384 this->_handleInsertLibStatus(status);
1385 return ArrayValue {libEntryPtr};
1386 }
1387
1388 template <typename LibObjT>
1389 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key) const
1390 {
1391 return this->insertEmptyArray(key.data());
1392 }
1393
1394 template <typename LibObjT>
1395 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key) const
1396 {
1397 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1398
1399 bt_value *libEntryPtr;
1400 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1401
1402 this->_handleInsertLibStatus(status);
1403 return MapValue {libEntryPtr};
1404 }
1405
1406 template <typename LibObjT>
1407 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key) const
1408 {
1409 return this->insertEmptyMap(key.data());
1410 }
1411
1412 inline BoolValue::Shared createValue(const bool rawVal)
1413 {
1414 return BoolValue::create(rawVal);
1415 }
1416
1417 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1418 {
1419 return UnsignedIntegerValue::create(rawVal);
1420 }
1421
1422 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1423 {
1424 return SignedIntegerValue::create(rawVal);
1425 }
1426
1427 inline RealValue::Shared createValue(const double rawVal)
1428 {
1429 return RealValue::create(rawVal);
1430 }
1431
1432 inline StringValue::Shared createValue(const char * const rawVal)
1433 {
1434 return StringValue::create(rawVal);
1435 }
1436
1437 inline StringValue::Shared createValue(const std::string& rawVal)
1438 {
1439 return StringValue::create(rawVal);
1440 }
1441
1442 } /* namespace bt2 */
1443
1444 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */
This page took 0.05786 seconds and 5 git commands to generate.