Add C++ interface for the libbabeltrace2 `bt_field` API
[babeltrace.git] / src / cpp-common / bt2 / field.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_FIELD_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_FIELD_HPP
9
10 #include <type_traits>
11 #include <cstdint>
12 #include <babeltrace2/babeltrace.h>
13
14 #include "common/assert.h"
15 #include "internal/borrowed-obj.hpp"
16 #include "cpp-common/optional.hpp"
17 #include "cpp-common/string_view.hpp"
18 #include "field-class.hpp"
19
20 namespace bt2 {
21
22 template <typename LibObjT>
23 class CommonBoolField;
24
25 template <typename LibObjT>
26 class CommonBitArrayField;
27
28 template <typename LibObjT>
29 class CommonUnsignedIntegerField;
30
31 template <typename LibObjT>
32 class CommonSignedIntegerField;
33
34 template <typename LibObjT>
35 class CommonUnsignedEnumerationField;
36
37 template <typename LibObjT>
38 class CommonSignedEnumerationField;
39
40 template <typename LibObjT>
41 class CommonSinglePrecisionRealField;
42
43 template <typename LibObjT>
44 class CommonDoublePrecisionRealField;
45
46 template <typename LibObjT>
47 class CommonStringField;
48
49 template <typename LibObjT>
50 class CommonStructureField;
51
52 template <typename LibObjT>
53 class CommonArrayField;
54
55 template <typename LibObjT>
56 class CommonDynamicArrayField;
57
58 template <typename LibObjT>
59 class CommonOptionField;
60
61 template <typename LibObjT>
62 class CommonVariantField;
63
64 namespace internal {
65
66 template <typename LibObjT>
67 struct CommonFieldSpec;
68
69 // Functions specific to mutable fields
70 template <>
71 struct CommonFieldSpec<bt_field> final
72 {
73 static bt_field_class *cls(bt_field * const libObjPtr) noexcept
74 {
75 return bt_field_borrow_class(libObjPtr);
76 }
77 };
78
79 // Functions specific to constant fields
80 template <>
81 struct CommonFieldSpec<const bt_field> final
82 {
83 static const bt_field_class *cls(const bt_field * const libObjPtr) noexcept
84 {
85 return bt_field_borrow_class_const(libObjPtr);
86 }
87 };
88
89 } // namespace internal
90
91 template <typename LibObjT>
92 class CommonField : public internal::BorrowedObj<LibObjT>
93 {
94 private:
95 using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
96
97 protected:
98 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
99 using _ThisCommonField = CommonField<LibObjT>;
100
101 public:
102 using Class =
103 typename std::conditional<std::is_const<LibObjT>::value, ConstFieldClass, FieldClass>::type;
104
105 explicit CommonField(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
106 {
107 }
108
109 template <typename OtherLibObjT>
110 CommonField(const CommonField<OtherLibObjT>& val) noexcept : _ThisBorrowedObj {val}
111 {
112 }
113
114 template <typename OtherLibObjT>
115 _ThisCommonField& operator=(const CommonField<OtherLibObjT>& val) noexcept
116 {
117 _ThisBorrowedObj::operator=(val);
118 return *this;
119 }
120
121 FieldClassType classType() const noexcept
122 {
123 return static_cast<FieldClassType>(bt_field_get_class_type(this->_libObjPtr()));
124 }
125
126 ConstFieldClass cls() const noexcept
127 {
128 return ConstFieldClass {internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
129 }
130
131 Class cls() noexcept
132 {
133 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
134 }
135
136 bool isBool() const noexcept
137 {
138 return this->cls().isBool();
139 }
140
141 bool isBitArray() const noexcept
142 {
143 return this->cls().isBitArray();
144 }
145
146 bool isUnsignedInteger() const noexcept
147 {
148 return this->cls().isUnsignedInteger();
149 }
150
151 bool isSignedInteger() const noexcept
152 {
153 return this->cls().isSignedInteger();
154 }
155
156 bool isUnsignedEnumeration() const noexcept
157 {
158 return this->cls().isUnsignedEnumeration();
159 }
160
161 bool isSignedEnumeration() const noexcept
162 {
163 return this->cls().isSignedEnumeration();
164 }
165
166 bool isSinglePrecisionReal() const noexcept
167 {
168 return this->cls().isSinglePrecisionReal();
169 }
170
171 bool isDoublePrecisionReal() const noexcept
172 {
173 return this->cls().isDoublePrecisionReal();
174 }
175
176 bool isString() const noexcept
177 {
178 return this->cls().isString();
179 }
180
181 bool isStructure() const noexcept
182 {
183 return this->cls().isStructure();
184 }
185
186 bool isArray() const noexcept
187 {
188 return this->cls().isArray();
189 }
190
191 bool isDynamicArray() const noexcept
192 {
193 return this->cls().isDynamicArray();
194 }
195
196 bool isOption() const noexcept
197 {
198 return this->cls().isOption();
199 }
200
201 bool isVariant() const noexcept
202 {
203 return this->cls().isVariant();
204 }
205
206 CommonBoolField<LibObjT> asBool() const noexcept;
207 CommonBitArrayField<LibObjT> asBitArray() const noexcept;
208 CommonUnsignedIntegerField<LibObjT> asUnsignedInteger() const noexcept;
209 CommonSignedIntegerField<LibObjT> asSignedInteger() const noexcept;
210 CommonUnsignedEnumerationField<LibObjT> asUnsignedEnumeration() const noexcept;
211 CommonSignedEnumerationField<LibObjT> asSignedEnumeration() const noexcept;
212 CommonSinglePrecisionRealField<LibObjT> asSinglePrecisionReal() const noexcept;
213 CommonDoublePrecisionRealField<LibObjT> asDoublePrecisionReal() const noexcept;
214 CommonStringField<LibObjT> asString() const noexcept;
215 CommonStructureField<LibObjT> asStructure() const noexcept;
216 CommonArrayField<LibObjT> asArray() const noexcept;
217 CommonDynamicArrayField<LibObjT> asDynamicArray() const noexcept;
218 CommonOptionField<LibObjT> asOption() const noexcept;
219 CommonVariantField<LibObjT> asVariant() const noexcept;
220 };
221
222 using Field = CommonField<bt_field>;
223 using ConstField = CommonField<const bt_field>;
224
225 template <typename LibObjT>
226 class CommonBoolField final : public CommonField<LibObjT>
227 {
228 private:
229 using typename CommonField<LibObjT>::_LibObjPtr;
230 using typename CommonField<LibObjT>::_ThisCommonField;
231
232 public:
233 using Value = bool;
234
235 explicit CommonBoolField(const _LibObjPtr libObjPtr) noexcept : _ThisCommonField {libObjPtr}
236 {
237 BT_ASSERT_DBG(this->isBool());
238 }
239
240 template <typename OtherLibObjT>
241 CommonBoolField(const CommonBoolField<OtherLibObjT>& val) noexcept : _ThisCommonField {val}
242 {
243 }
244
245 template <typename OtherLibObjT>
246 CommonBoolField<LibObjT>& operator=(const CommonBoolField<OtherLibObjT>& val) noexcept
247 {
248 _ThisCommonField::operator=(val);
249 return *this;
250 }
251
252 CommonBoolField<LibObjT>& operator=(const Value val) noexcept
253 {
254 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
255
256 bt_field_bool_set_value(this->_libObjPtr(), static_cast<bt_bool>(val));
257 return *this;
258 }
259
260 Value value() const noexcept
261 {
262 return static_cast<Value>(bt_field_bool_get_value(this->_libObjPtr()));
263 }
264
265 operator Value() const noexcept
266 {
267 return this->value();
268 }
269 };
270
271 using BoolField = CommonBoolField<bt_field>;
272 using ConstBoolField = CommonBoolField<const bt_field>;
273
274 template <typename LibObjT>
275 class CommonBitArrayField final : public CommonField<LibObjT>
276 {
277 private:
278 using typename CommonField<LibObjT>::_LibObjPtr;
279 using typename CommonField<LibObjT>::_ThisCommonField;
280
281 public:
282 using Class = typename std::conditional<std::is_const<LibObjT>::value, ConstBitArrayFieldClass,
283 BitArrayFieldClass>::type;
284
285 explicit CommonBitArrayField(const _LibObjPtr libObjPtr) noexcept : _ThisCommonField {libObjPtr}
286 {
287 BT_ASSERT_DBG(this->isBitArray());
288 }
289
290 template <typename OtherLibObjT>
291 CommonBitArrayField(const CommonBitArrayField<OtherLibObjT>& val) noexcept :
292 _ThisCommonField {val}
293 {
294 }
295
296 template <typename OtherLibObjT>
297 CommonBitArrayField<LibObjT>& operator=(const CommonBitArrayField<OtherLibObjT>& val) noexcept
298 {
299 _ThisCommonField::operator=(val);
300 return *this;
301 }
302
303 ConstBitArrayFieldClass cls() const noexcept
304 {
305 return ConstBitArrayFieldClass {
306 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
307 }
308
309 Class cls() noexcept
310 {
311 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
312 }
313
314 CommonBitArrayField<LibObjT>& operator=(const std::uint64_t bits) noexcept
315 {
316 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
317
318 bt_field_bit_array_set_value_as_integer(this->_libObjPtr(), bits);
319 return *this;
320 }
321
322 std::uint64_t valueAsInteger() const noexcept
323 {
324 return bt_field_bit_array_get_value_as_integer(this->_libObjPtr());
325 }
326
327 bool bitValue(const std::uint64_t index) const noexcept
328 {
329 BT_ASSERT_DBG(index < this->cls().length());
330 return static_cast<bool>(this->valueAsInteger() & (1ULL << index));
331 }
332 };
333
334 using BitArrayField = CommonBitArrayField<bt_field>;
335 using ConstBitArrayField = CommonBitArrayField<const bt_field>;
336
337 template <typename LibObjT>
338 class CommonUnsignedIntegerField final : public CommonField<LibObjT>
339 {
340 private:
341 using typename CommonField<LibObjT>::_ThisCommonField;
342
343 protected:
344 using typename CommonField<LibObjT>::_LibObjPtr;
345 using _ThisCommonUnsignedIntegerField = CommonUnsignedIntegerField<LibObjT>;
346
347 public:
348 using Value = std::uint64_t;
349
350 using Class = typename std::conditional<std::is_const<LibObjT>::value, ConstIntegerFieldClass,
351 IntegerFieldClass>::type;
352
353 explicit CommonUnsignedIntegerField(const _LibObjPtr libObjPtr) noexcept :
354 _ThisCommonField {libObjPtr}
355 {
356 BT_ASSERT_DBG(this->isUnsignedInteger());
357 }
358
359 template <typename OtherLibObjT>
360 CommonUnsignedIntegerField(const CommonUnsignedIntegerField<OtherLibObjT>& val) noexcept :
361 _ThisCommonField {val}
362 {
363 }
364
365 template <typename OtherLibObjT>
366 _ThisCommonUnsignedIntegerField&
367 operator=(const CommonUnsignedIntegerField<OtherLibObjT>& val) noexcept
368 {
369 _ThisCommonField::operator=(val);
370 return *this;
371 }
372
373 ConstIntegerFieldClass cls() const noexcept
374 {
375 return ConstIntegerFieldClass {
376 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
377 }
378
379 Class cls() noexcept
380 {
381 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
382 }
383
384 CommonUnsignedIntegerField<LibObjT>& operator=(const Value val) noexcept
385 {
386 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
387
388 bt_field_integer_unsigned_set_value(this->_libObjPtr(), val);
389 return *this;
390 }
391
392 Value value() const noexcept
393 {
394 return bt_field_integer_unsigned_get_value(this->_libObjPtr());
395 }
396
397 operator Value() const noexcept
398 {
399 return this->value();
400 }
401 };
402
403 using UnsignedIntegerField = CommonUnsignedIntegerField<bt_field>;
404 using ConstUnsignedIntegerField = CommonUnsignedIntegerField<const bt_field>;
405
406 template <typename LibObjT>
407 class CommonSignedIntegerField final : public CommonField<LibObjT>
408 {
409 private:
410 using typename CommonField<LibObjT>::_ThisCommonField;
411
412 protected:
413 using typename CommonField<LibObjT>::_LibObjPtr;
414 using _ThisCommonSignedIntegerField = CommonSignedIntegerField<LibObjT>;
415
416 public:
417 using Value = std::uint64_t;
418
419 using Class = typename std::conditional<std::is_const<LibObjT>::value, ConstIntegerFieldClass,
420 IntegerFieldClass>::type;
421
422 explicit CommonSignedIntegerField(const _LibObjPtr libObjPtr) noexcept :
423 _ThisCommonField {libObjPtr}
424 {
425 BT_ASSERT_DBG(this->isSignedInteger());
426 }
427
428 template <typename OtherLibObjT>
429 CommonSignedIntegerField(const CommonSignedIntegerField<OtherLibObjT>& val) noexcept :
430 _ThisCommonField {val}
431 {
432 }
433
434 template <typename OtherLibObjT>
435 _ThisCommonSignedIntegerField&
436 operator=(const CommonSignedIntegerField<OtherLibObjT>& val) noexcept
437 {
438 _ThisCommonField::operator=(val);
439 return *this;
440 }
441
442 ConstIntegerFieldClass cls() const noexcept
443 {
444 return ConstIntegerFieldClass {
445 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
446 }
447
448 Class cls() noexcept
449 {
450 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
451 }
452
453 CommonSignedIntegerField<LibObjT>& operator=(const Value val) noexcept
454 {
455 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
456
457 bt_field_integer_signed_set_value(this->_libObjPtr(), val);
458 return *this;
459 }
460
461 Value value() const noexcept
462 {
463 return bt_field_integer_signed_get_value(this->_libObjPtr());
464 }
465
466 operator Value() const noexcept
467 {
468 return this->value();
469 }
470 };
471
472 using SignedIntegerField = CommonSignedIntegerField<bt_field>;
473 using ConstSignedIntegerField = CommonSignedIntegerField<const bt_field>;
474
475 class EnumerationFieldClassMappingLabels
476 {
477 public:
478 explicit EnumerationFieldClassMappingLabels(
479 const bt_field_class_enumeration_mapping_label_array labels, const std::uint64_t size) :
480 _mLabels {labels},
481 _mSize {size}
482 {
483 }
484
485 EnumerationFieldClassMappingLabels(const EnumerationFieldClassMappingLabels&) noexcept =
486 default;
487
488 EnumerationFieldClassMappingLabels&
489 operator=(const EnumerationFieldClassMappingLabels&) noexcept = default;
490
491 std::uint64_t size() const noexcept
492 {
493 return _mSize;
494 }
495
496 bpstd::string_view operator[](const std::uint64_t index) const noexcept
497 {
498 return _mLabels[index];
499 }
500
501 private:
502 bt_field_class_enumeration_mapping_label_array _mLabels;
503 std::uint64_t _mSize;
504 };
505
506 template <typename LibObjT>
507 class CommonUnsignedEnumerationField final : public CommonUnsignedIntegerField<LibObjT>
508 {
509 private:
510 using typename CommonUnsignedIntegerField<LibObjT>::_ThisCommonUnsignedIntegerField;
511 using typename CommonField<LibObjT>::_LibObjPtr;
512
513 public:
514 using Class =
515 typename std::conditional<std::is_const<LibObjT>::value, ConstUnsignedEnumerationFieldClass,
516 UnsignedEnumerationFieldClass>::type;
517
518 explicit CommonUnsignedEnumerationField(const _LibObjPtr libObjPtr) noexcept :
519 _ThisCommonUnsignedIntegerField {libObjPtr}
520 {
521 BT_ASSERT_DBG(this->isUnsignedEnumeration());
522 }
523
524 template <typename OtherLibObjT>
525 CommonUnsignedEnumerationField(const CommonUnsignedEnumerationField<OtherLibObjT>& val) noexcept
526 :
527 _ThisCommonUnsignedIntegerField {val}
528 {
529 }
530
531 template <typename OtherLibObjT>
532 CommonUnsignedEnumerationField<LibObjT>&
533 operator=(const CommonUnsignedEnumerationField<OtherLibObjT>& val) noexcept
534 {
535 _ThisCommonUnsignedIntegerField::operator=(val);
536 return *this;
537 }
538
539 ConstUnsignedEnumerationFieldClass cls() const noexcept
540 {
541 return ConstUnsignedEnumerationFieldClass {
542 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
543 }
544
545 Class cls() noexcept
546 {
547 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
548 }
549
550 EnumerationFieldClassMappingLabels labels() const
551 {
552 bt_field_class_enumeration_mapping_label_array labelArray;
553 std::uint64_t count;
554 const auto status = bt_field_enumeration_unsigned_get_mapping_labels(this->_libObjPtr(),
555 &labelArray, &count);
556
557 if (status == BT_FIELD_ENUMERATION_GET_MAPPING_LABELS_STATUS_MEMORY_ERROR) {
558 throw LibMemoryError {};
559 }
560
561 return EnumerationFieldClassMappingLabels {labelArray, count};
562 }
563 };
564
565 using UnsignedEnumerationField = CommonUnsignedEnumerationField<bt_field>;
566 using ConstUnsignedEnumerationField = CommonUnsignedEnumerationField<const bt_field>;
567
568 template <typename LibObjT>
569 class CommonSignedEnumerationField final : public CommonSignedIntegerField<LibObjT>
570 {
571 private:
572 using typename CommonSignedIntegerField<LibObjT>::_ThisCommonSignedIntegerField;
573 using typename CommonField<LibObjT>::_LibObjPtr;
574
575 public:
576 using Class =
577 typename std::conditional<std::is_const<LibObjT>::value, ConstSignedEnumerationFieldClass,
578 SignedEnumerationFieldClass>::type;
579
580 explicit CommonSignedEnumerationField(const _LibObjPtr libObjPtr) noexcept :
581 _ThisCommonSignedIntegerField {libObjPtr}
582 {
583 BT_ASSERT_DBG(this->isSignedEnumeration());
584 }
585
586 template <typename OtherLibObjT>
587 CommonSignedEnumerationField(const CommonSignedEnumerationField<OtherLibObjT>& val) noexcept :
588 _ThisCommonSignedIntegerField {val}
589 {
590 }
591
592 template <typename OtherLibObjT>
593 CommonSignedEnumerationField<LibObjT>&
594 operator=(const CommonSignedEnumerationField<OtherLibObjT>& val) noexcept
595 {
596 _ThisCommonSignedIntegerField::operator=(val);
597 return *this;
598 }
599
600 ConstSignedEnumerationFieldClass cls() const noexcept
601 {
602 return ConstSignedEnumerationFieldClass {
603 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
604 }
605
606 Class cls() noexcept
607 {
608 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
609 }
610
611 EnumerationFieldClassMappingLabels labels() const
612 {
613 bt_field_class_enumeration_mapping_label_array labelArray;
614 std::uint64_t count;
615 const auto status =
616 bt_field_enumeration_signed_get_mapping_labels(this->_libObjPtr(), &labelArray, &count);
617
618 if (status == BT_FIELD_ENUMERATION_GET_MAPPING_LABELS_STATUS_MEMORY_ERROR) {
619 throw LibMemoryError {};
620 }
621
622 return EnumerationFieldClassMappingLabels {labelArray, count};
623 }
624 };
625
626 using SignedEnumerationField = CommonSignedEnumerationField<bt_field>;
627 using ConstSignedEnumerationField = CommonSignedEnumerationField<const bt_field>;
628
629 template <typename LibObjT>
630 class CommonSinglePrecisionRealField final : public CommonField<LibObjT>
631 {
632 private:
633 using typename CommonField<LibObjT>::_LibObjPtr;
634 using typename CommonField<LibObjT>::_ThisCommonField;
635
636 public:
637 using Value = float;
638
639 explicit CommonSinglePrecisionRealField(const _LibObjPtr libObjPtr) noexcept :
640 _ThisCommonField {libObjPtr}
641 {
642 BT_ASSERT_DBG(this->isSinglePrecisionReal());
643 }
644
645 template <typename OtherLibObjT>
646 CommonSinglePrecisionRealField(const CommonSinglePrecisionRealField<OtherLibObjT>& val) noexcept
647 :
648 _ThisCommonField {val}
649 {
650 }
651
652 template <typename OtherLibObjT>
653 CommonSinglePrecisionRealField<LibObjT>&
654 operator=(const CommonSinglePrecisionRealField<OtherLibObjT>& val) noexcept
655 {
656 _ThisCommonField::operator=(val);
657 return *this;
658 }
659
660 CommonSinglePrecisionRealField<LibObjT>& operator=(const Value val) noexcept
661 {
662 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
663
664 bt_field_real_single_precision_set_value(this->_libObjPtr(), val);
665 return *this;
666 }
667
668 Value value() const noexcept
669 {
670 return bt_field_real_single_precision_get_value(this->_libObjPtr());
671 }
672
673 operator Value() const noexcept
674 {
675 return this->value();
676 }
677 };
678
679 using SinglePrecisionRealField = CommonSinglePrecisionRealField<bt_field>;
680 using ConstSinglePrecisionRealField = CommonSinglePrecisionRealField<const bt_field>;
681
682 template <typename LibObjT>
683 class CommonDoublePrecisionRealField final : public CommonField<LibObjT>
684 {
685 private:
686 using typename CommonField<LibObjT>::_LibObjPtr;
687 using typename CommonField<LibObjT>::_ThisCommonField;
688
689 public:
690 using Value = double;
691
692 explicit CommonDoublePrecisionRealField(const _LibObjPtr libObjPtr) noexcept :
693 _ThisCommonField {libObjPtr}
694 {
695 BT_ASSERT_DBG(this->isDoublePrecisionReal());
696 }
697
698 template <typename OtherLibObjT>
699 CommonDoublePrecisionRealField(const CommonDoublePrecisionRealField<OtherLibObjT>& val) noexcept
700 :
701 _ThisCommonField {val}
702 {
703 }
704
705 template <typename OtherLibObjT>
706 CommonDoublePrecisionRealField<LibObjT>&
707 operator=(const CommonDoublePrecisionRealField<OtherLibObjT>& val) noexcept
708 {
709 _ThisCommonField::operator=(val);
710 return *this;
711 }
712
713 CommonDoublePrecisionRealField<LibObjT>& operator=(const Value val) noexcept
714 {
715 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
716
717 bt_field_real_single_precision_set_value(this->_libObjPtr(), val);
718 return *this;
719 }
720
721 Value value() const noexcept
722 {
723 return bt_field_real_single_precision_get_value(this->_libObjPtr());
724 }
725
726 operator Value() const noexcept
727 {
728 return this->value();
729 }
730 };
731
732 using DoublePrecisionRealField = CommonDoublePrecisionRealField<bt_field>;
733 using ConstDoublePrecisionRealField = CommonDoublePrecisionRealField<const bt_field>;
734
735 template <typename LibObjT>
736 class CommonStringField final : public CommonField<LibObjT>
737 {
738 private:
739 using typename CommonField<LibObjT>::_LibObjPtr;
740 using typename CommonField<LibObjT>::_ThisCommonField;
741
742 public:
743 explicit CommonStringField(const _LibObjPtr libObjPtr) noexcept : _ThisCommonField {libObjPtr}
744 {
745 BT_ASSERT_DBG(this->isString());
746 }
747
748 template <typename OtherLibObjT>
749 CommonStringField(const CommonStringField<OtherLibObjT>& val) noexcept : _ThisCommonField {val}
750 {
751 }
752
753 template <typename OtherLibObjT>
754 CommonStringField<LibObjT>& operator=(const CommonStringField<OtherLibObjT>& val) noexcept
755 {
756 _ThisCommonField::operator=(val);
757 return *this;
758 }
759
760 CommonStringField<LibObjT>& operator=(const char * const val) noexcept
761 {
762 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
763
764 const auto status = bt_field_string_set_value(this->_libObjPtr(), val);
765
766 if (status == BT_FIELD_STRING_SET_VALUE_STATUS_MEMORY_ERROR) {
767 throw LibMemoryError {};
768 }
769
770 return *this;
771 }
772
773 CommonStringField<LibObjT>& operator=(const std::string& val) noexcept
774 {
775 return *this = val.data();
776 }
777
778 void clear() noexcept
779 {
780 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
781
782 bt_field_string_clear(this->_libObjPtr());
783 }
784
785 bpstd::string_view value() const noexcept
786 {
787 return bt_field_string_get_value(this->_libObjPtr());
788 }
789 };
790
791 using StringField = CommonStringField<bt_field>;
792 using ConstStringField = CommonStringField<const bt_field>;
793
794 namespace internal {
795
796 template <typename LibObjT>
797 struct CommonStructureFieldSpec;
798
799 // Functions specific to mutable structure fields
800 template <>
801 struct CommonStructureFieldSpec<bt_field> final
802 {
803 static bt_field *memberFieldByIndex(bt_field * const libObjPtr,
804 const std::uint64_t index) noexcept
805 {
806 return bt_field_structure_borrow_member_field_by_index(libObjPtr, index);
807 }
808
809 static bt_field *memberFieldByName(bt_field * const libObjPtr, const char * const name) noexcept
810 {
811 return bt_field_structure_borrow_member_field_by_name(libObjPtr, name);
812 }
813 };
814
815 // Functions specific to constant structure fields
816 template <>
817 struct CommonStructureFieldSpec<const bt_field> final
818 {
819 static const bt_field *memberFieldByIndex(const bt_field * const libObjPtr,
820 const std::uint64_t index) noexcept
821 {
822 return bt_field_structure_borrow_member_field_by_index_const(libObjPtr, index);
823 }
824
825 static const bt_field *memberFieldByName(const bt_field * const libObjPtr,
826 const char * const name) noexcept
827 {
828 return bt_field_structure_borrow_member_field_by_name_const(libObjPtr, name);
829 }
830 };
831
832 } // namespace internal
833
834 template <typename LibObjT>
835 class CommonStructureField final : public CommonField<LibObjT>
836 {
837 private:
838 using typename CommonField<LibObjT>::_LibObjPtr;
839 using typename CommonField<LibObjT>::_ThisCommonField;
840 using _Spec = internal::CommonStructureFieldSpec<LibObjT>;
841
842 public:
843 using Class = typename std::conditional<std::is_const<LibObjT>::value, ConstStructureFieldClass,
844 StructureFieldClass>::type;
845
846 explicit CommonStructureField(const _LibObjPtr libObjPtr) noexcept :
847 _ThisCommonField {libObjPtr}
848 {
849 BT_ASSERT_DBG(this->isStructure());
850 }
851
852 template <typename OtherLibObjT>
853 CommonStructureField(const CommonStructureField<OtherLibObjT>& val) noexcept :
854 _ThisCommonField {val}
855 {
856 }
857
858 template <typename OtherLibObjT>
859 CommonStructureField<LibObjT>& operator=(const CommonStructureField<OtherLibObjT>& val) noexcept
860 {
861 _ThisCommonField::operator=(val);
862 return *this;
863 }
864
865 ConstStructureFieldClass cls() const noexcept
866 {
867 return ConstStructureFieldClass {
868 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
869 }
870
871 Class cls() noexcept
872 {
873 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
874 }
875
876 std::uint64_t size() const noexcept
877 {
878 return this->cls().size();
879 }
880
881 ConstField operator[](const std::uint64_t index) const noexcept
882 {
883 return ConstField {internal::CommonStructureFieldSpec<const bt_field>::memberFieldByIndex(
884 this->_libObjPtr(), index)};
885 }
886
887 CommonField<LibObjT> operator[](const std::uint64_t index) noexcept
888 {
889 return CommonField<LibObjT> {_Spec::memberFieldByIndex(this->_libObjPtr(), index)};
890 }
891
892 nonstd::optional<ConstField> operator[](const char * const name) const noexcept
893 {
894 const auto libObjPtr =
895 internal::CommonStructureFieldSpec<const bt_field>::memberFieldByName(
896 this->_libObjPtr(), name);
897
898 if (libObjPtr) {
899 return ConstField {libObjPtr};
900 }
901
902 return nonstd::nullopt;
903 }
904
905 nonstd::optional<ConstField> operator[](const std::string& name) const noexcept
906 {
907 return (*this)[name.data()];
908 }
909
910 nonstd::optional<CommonField<LibObjT>> operator[](const char * const name) noexcept
911 {
912 const auto libObjPtr = _Spec::memberFieldByName(this->_libObjPtr(), name);
913
914 if (libObjPtr) {
915 return CommonField<LibObjT> {libObjPtr};
916 }
917
918 return nonstd::nullopt;
919 }
920
921 nonstd::optional<CommonField<LibObjT>> operator[](const std::string& name) noexcept
922 {
923 return (*this)[name.data()];
924 }
925 };
926
927 using StructureField = CommonStructureField<bt_field>;
928 using ConstStructureField = CommonStructureField<const bt_field>;
929
930 namespace internal {
931
932 template <typename LibObjT>
933 struct CommonArrayFieldSpec;
934
935 // Functions specific to mutable array fields
936 template <>
937 struct CommonArrayFieldSpec<bt_field> final
938 {
939 static bt_field *elementFieldByIndex(bt_field * const libObjPtr,
940 const std::uint64_t index) noexcept
941 {
942 return bt_field_array_borrow_element_field_by_index(libObjPtr, index);
943 }
944 };
945
946 // Functions specific to constant array fields
947 template <>
948 struct CommonArrayFieldSpec<const bt_field> final
949 {
950 static const bt_field *elementFieldByIndex(const bt_field * const libObjPtr,
951 const std::uint64_t index) noexcept
952 {
953 return bt_field_array_borrow_element_field_by_index_const(libObjPtr, index);
954 }
955 };
956
957 } // namespace internal
958
959 template <typename LibObjT>
960 class CommonArrayField : public CommonField<LibObjT>
961 {
962 private:
963 using typename CommonField<LibObjT>::_ThisCommonField;
964 using _Spec = internal::CommonArrayFieldSpec<LibObjT>;
965
966 protected:
967 using typename CommonField<LibObjT>::_LibObjPtr;
968 using _ThisCommonArrayField = CommonArrayField<LibObjT>;
969
970 public:
971 using Class = typename std::conditional<std::is_const<LibObjT>::value, ConstArrayFieldClass,
972 ArrayFieldClass>::type;
973
974 explicit CommonArrayField(const _LibObjPtr libObjPtr) noexcept : _ThisCommonField {libObjPtr}
975 {
976 BT_ASSERT_DBG(this->isArray());
977 }
978
979 template <typename OtherLibObjT>
980 CommonArrayField(const CommonArrayField<OtherLibObjT>& val) noexcept : _ThisCommonField {val}
981 {
982 }
983
984 template <typename OtherLibObjT>
985 _ThisCommonArrayField& operator=(const CommonArrayField<OtherLibObjT>& val) noexcept
986 {
987 _ThisCommonField::operator=(val);
988 return *this;
989 }
990
991 ConstArrayFieldClass cls() const noexcept
992 {
993 return ConstArrayFieldClass {
994 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
995 }
996
997 Class cls() noexcept
998 {
999 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
1000 }
1001
1002 std::uint64_t length() const noexcept
1003 {
1004 return bt_field_array_get_length(this->_libObjPtr());
1005 }
1006
1007 ConstField operator[](const std::uint64_t index) const noexcept
1008 {
1009 return ConstField {internal::CommonArrayFieldSpec<const bt_field>::elementFieldByIndex(
1010 this->_libObjPtr(), index)};
1011 }
1012
1013 CommonField<LibObjT> operator[](const std::uint64_t index) noexcept
1014 {
1015 return CommonField<LibObjT> {_Spec::elementFieldByIndex(this->_libObjPtr(), index)};
1016 }
1017 };
1018
1019 using ArrayField = CommonArrayField<bt_field>;
1020 using ConstArrayField = CommonArrayField<const bt_field>;
1021
1022 template <typename LibObjT>
1023 class CommonDynamicArrayField : public CommonArrayField<LibObjT>
1024 {
1025 private:
1026 using typename CommonField<LibObjT>::_LibObjPtr;
1027 using typename CommonArrayField<LibObjT>::_ThisCommonArrayField;
1028
1029 public:
1030 explicit CommonDynamicArrayField(const _LibObjPtr libObjPtr) noexcept :
1031 _ThisCommonArrayField {libObjPtr}
1032 {
1033 BT_ASSERT_DBG(this->isDynamicArray());
1034 }
1035
1036 template <typename OtherLibObjT>
1037 CommonDynamicArrayField(const CommonDynamicArrayField<OtherLibObjT>& val) noexcept :
1038 _ThisCommonArrayField {val}
1039 {
1040 }
1041
1042 template <typename OtherLibObjT>
1043 CommonDynamicArrayField<LibObjT>&
1044 operator=(const CommonDynamicArrayField<OtherLibObjT>& val) noexcept
1045 {
1046 _ThisCommonArrayField::operator=(val);
1047 return *this;
1048 }
1049
1050 std::uint64_t length() const noexcept
1051 {
1052 return _ThisCommonArrayField::length();
1053 }
1054
1055 void length(const std::uint64_t length)
1056 {
1057 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1058
1059 const auto status = bt_field_array_dynamic_set_length(this->_libObjPtr(), length);
1060
1061 if (status == BT_FIELD_DYNAMIC_ARRAY_SET_LENGTH_STATUS_MEMORY_ERROR) {
1062 throw LibMemoryError {};
1063 }
1064 }
1065 };
1066
1067 using DynamicArrayField = CommonDynamicArrayField<bt_field>;
1068 using ConstDynamicArrayField = CommonDynamicArrayField<const bt_field>;
1069
1070 namespace internal {
1071
1072 template <typename LibObjT>
1073 struct CommonOptionFieldSpec;
1074
1075 // Functions specific to mutable option fields
1076 template <>
1077 struct CommonOptionFieldSpec<bt_field> final
1078 {
1079 static bt_field *field(bt_field * const libObjPtr) noexcept
1080 {
1081 return bt_field_option_borrow_field(libObjPtr);
1082 }
1083 };
1084
1085 // Functions specific to constant option fields
1086 template <>
1087 struct CommonOptionFieldSpec<const bt_field> final
1088 {
1089 static const bt_field *field(const bt_field * const libObjPtr) noexcept
1090 {
1091 return bt_field_option_borrow_field_const(libObjPtr);
1092 }
1093 };
1094
1095 } // namespace internal
1096
1097 template <typename LibObjT>
1098 class CommonOptionField : public CommonField<LibObjT>
1099 {
1100 private:
1101 using typename CommonField<LibObjT>::_LibObjPtr;
1102 using typename CommonField<LibObjT>::_ThisCommonField;
1103 using _Spec = internal::CommonOptionFieldSpec<LibObjT>;
1104
1105 public:
1106 using Class = typename std::conditional<std::is_const<LibObjT>::value, ConstOptionFieldClass,
1107 OptionFieldClass>::type;
1108
1109 explicit CommonOptionField(const _LibObjPtr libObjPtr) noexcept : _ThisCommonField {libObjPtr}
1110 {
1111 BT_ASSERT_DBG(this->isOption());
1112 }
1113
1114 template <typename OtherLibObjT>
1115 CommonOptionField(const CommonOptionField<OtherLibObjT>& val) noexcept : _ThisCommonField {val}
1116 {
1117 }
1118
1119 template <typename OtherLibObjT>
1120 CommonOptionField<LibObjT>& operator=(const CommonOptionField<OtherLibObjT>& val) noexcept
1121 {
1122 _ThisCommonField::operator=(val);
1123 return *this;
1124 }
1125
1126 ConstOptionFieldClass cls() const noexcept
1127 {
1128 return ConstOptionFieldClass {
1129 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
1130 }
1131
1132 Class cls() noexcept
1133 {
1134 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
1135 }
1136
1137 void hasField(const bool hasField) noexcept
1138 {
1139 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1140
1141 bt_field_option_set_has_field(this->_libObjPtr(), static_cast<bt_bool>(hasField));
1142 }
1143
1144 bool hasField() const noexcept
1145 {
1146 return this->field();
1147 }
1148
1149 nonstd::optional<ConstField> field() const noexcept
1150 {
1151 const auto libObjPtr =
1152 internal::CommonOptionFieldSpec<const bt_field>::field(this->_libObjPtr());
1153
1154 if (libObjPtr) {
1155 return ConstField {libObjPtr};
1156 }
1157
1158 return nonstd::nullopt;
1159 }
1160
1161 nonstd::optional<CommonField<LibObjT>> field() noexcept
1162 {
1163 const auto libObjPtr = _Spec::field(this->_libObjPtr());
1164
1165 if (libObjPtr) {
1166 return CommonField<LibObjT> {libObjPtr};
1167 }
1168
1169 return nonstd::nullopt;
1170 }
1171 };
1172
1173 using OptionField = CommonOptionField<bt_field>;
1174 using ConstOptionField = CommonOptionField<const bt_field>;
1175
1176 namespace internal {
1177
1178 template <typename LibObjT>
1179 struct CommonVariantFieldSpec;
1180
1181 // Functions specific to mutable variant fields
1182 template <>
1183 struct CommonVariantFieldSpec<bt_field> final
1184 {
1185 static bt_field *selectedOptionField(bt_field * const libObjPtr) noexcept
1186 {
1187 return bt_field_variant_borrow_selected_option_field(libObjPtr);
1188 }
1189 };
1190
1191 // Functions specific to constant variant fields
1192 template <>
1193 struct CommonVariantFieldSpec<const bt_field> final
1194 {
1195 static const bt_field *selectedOptionField(const bt_field * const libObjPtr) noexcept
1196 {
1197 return bt_field_variant_borrow_selected_option_field_const(libObjPtr);
1198 }
1199 };
1200
1201 } // namespace internal
1202
1203 template <typename LibObjT>
1204 class CommonVariantField : public CommonField<LibObjT>
1205 {
1206 private:
1207 using typename CommonField<LibObjT>::_LibObjPtr;
1208 using typename CommonField<LibObjT>::_ThisCommonField;
1209 using _Spec = internal::CommonVariantFieldSpec<LibObjT>;
1210
1211 public:
1212 using Class = typename std::conditional<std::is_const<LibObjT>::value, ConstVariantFieldClass,
1213 VariantFieldClass>::type;
1214
1215 explicit CommonVariantField(const _LibObjPtr libObjPtr) noexcept : _ThisCommonField {libObjPtr}
1216 {
1217 BT_ASSERT_DBG(this->isVariant());
1218 }
1219
1220 template <typename OtherLibObjT>
1221 CommonVariantField(const CommonVariantField<OtherLibObjT>& val) noexcept :
1222 _ThisCommonField {val}
1223 {
1224 }
1225
1226 template <typename OtherLibObjT>
1227 CommonVariantField<LibObjT>& operator=(const CommonVariantField<OtherLibObjT>& val) noexcept
1228 {
1229 _ThisCommonField::operator=(val);
1230 return *this;
1231 }
1232
1233 ConstVariantFieldClass cls() const noexcept
1234 {
1235 return ConstVariantFieldClass {
1236 internal::CommonFieldSpec<const bt_field>::cls(this->_libObjPtr())};
1237 }
1238
1239 Class cls() noexcept
1240 {
1241 return Class {internal::CommonFieldSpec<LibObjT>::cls(this->_libObjPtr())};
1242 }
1243
1244 void selectOption(const std::uint64_t index) noexcept
1245 {
1246 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1247
1248 static_cast<void>(bt_field_variant_select_option_by_index(this->_libObjPtr(), index));
1249 }
1250
1251 ConstField selectedOptionField() const noexcept
1252 {
1253 return ConstField {internal::CommonVariantFieldSpec<const bt_field>::selectedOptionField(
1254 this->_libObjPtr())};
1255 }
1256
1257 CommonField<LibObjT> selectedOptionField() noexcept
1258 {
1259 return CommonField<LibObjT> {_Spec::selectedOptionField(this->_libObjPtr())};
1260 }
1261
1262 std::uint64_t selectedOptionIndex() const noexcept
1263 {
1264 return bt_field_variant_get_selected_option_index(this->_libObjPtr());
1265 }
1266 };
1267
1268 using VariantField = CommonVariantField<bt_field>;
1269 using ConstVariantField = CommonVariantField<const bt_field>;
1270
1271 template <typename LibObjT>
1272 CommonBoolField<LibObjT> CommonField<LibObjT>::asBool() const noexcept
1273 {
1274 BT_ASSERT_DBG(this->isBool());
1275 return CommonBoolField<LibObjT> {this->_libObjPtr()};
1276 }
1277
1278 template <typename LibObjT>
1279 CommonBitArrayField<LibObjT> CommonField<LibObjT>::asBitArray() const noexcept
1280 {
1281 BT_ASSERT_DBG(this->isBitArray());
1282 return CommonBitArrayField<LibObjT> {this->_libObjPtr()};
1283 }
1284
1285 template <typename LibObjT>
1286 CommonUnsignedIntegerField<LibObjT> CommonField<LibObjT>::asUnsignedInteger() const noexcept
1287 {
1288 BT_ASSERT_DBG(this->isUnsignedInteger());
1289 return CommonUnsignedIntegerField<LibObjT> {this->_libObjPtr()};
1290 }
1291
1292 template <typename LibObjT>
1293 CommonSignedIntegerField<LibObjT> CommonField<LibObjT>::asSignedInteger() const noexcept
1294 {
1295 BT_ASSERT_DBG(this->isSignedInteger());
1296 return CommonSignedIntegerField<LibObjT> {this->_libObjPtr()};
1297 }
1298
1299 template <typename LibObjT>
1300 CommonUnsignedEnumerationField<LibObjT> CommonField<LibObjT>::asUnsignedEnumeration() const noexcept
1301 {
1302 BT_ASSERT_DBG(this->isUnsignedEnumeration());
1303 return CommonUnsignedEnumerationField<LibObjT> {this->_libObjPtr()};
1304 }
1305
1306 template <typename LibObjT>
1307 CommonSignedEnumerationField<LibObjT> CommonField<LibObjT>::asSignedEnumeration() const noexcept
1308 {
1309 BT_ASSERT_DBG(this->isSignedEnumeration());
1310 return CommonSignedEnumerationField<LibObjT> {this->_libObjPtr()};
1311 }
1312
1313 template <typename LibObjT>
1314 CommonSinglePrecisionRealField<LibObjT> CommonField<LibObjT>::asSinglePrecisionReal() const noexcept
1315 {
1316 BT_ASSERT_DBG(this->isSinglePrecisionReal());
1317 return CommonSinglePrecisionRealField<LibObjT> {this->_libObjPtr()};
1318 }
1319
1320 template <typename LibObjT>
1321 CommonDoublePrecisionRealField<LibObjT> CommonField<LibObjT>::asDoublePrecisionReal() const noexcept
1322 {
1323 BT_ASSERT_DBG(this->isDoublePrecisionReal());
1324 return CommonDoublePrecisionRealField<LibObjT> {this->_libObjPtr()};
1325 }
1326
1327 template <typename LibObjT>
1328 CommonStringField<LibObjT> CommonField<LibObjT>::asString() const noexcept
1329 {
1330 BT_ASSERT_DBG(this->isString());
1331 return CommonStringField<LibObjT> {this->_libObjPtr()};
1332 }
1333
1334 template <typename LibObjT>
1335 CommonStructureField<LibObjT> CommonField<LibObjT>::asStructure() const noexcept
1336 {
1337 BT_ASSERT_DBG(this->isStructure());
1338 return CommonStructureField<LibObjT> {this->_libObjPtr()};
1339 }
1340
1341 template <typename LibObjT>
1342 CommonArrayField<LibObjT> CommonField<LibObjT>::asArray() const noexcept
1343 {
1344 BT_ASSERT_DBG(this->isArray());
1345 return CommonArrayField<LibObjT> {this->_libObjPtr()};
1346 }
1347
1348 template <typename LibObjT>
1349 CommonDynamicArrayField<LibObjT> CommonField<LibObjT>::asDynamicArray() const noexcept
1350 {
1351 BT_ASSERT_DBG(this->isDynamicArray());
1352 return CommonDynamicArrayField<LibObjT> {this->_libObjPtr()};
1353 }
1354
1355 template <typename LibObjT>
1356 CommonOptionField<LibObjT> CommonField<LibObjT>::asOption() const noexcept
1357 {
1358 BT_ASSERT_DBG(this->isOption());
1359 return CommonOptionField<LibObjT> {this->_libObjPtr()};
1360 }
1361
1362 template <typename LibObjT>
1363 CommonVariantField<LibObjT> CommonField<LibObjT>::asVariant() const noexcept
1364 {
1365 BT_ASSERT_DBG(this->isVariant());
1366 return CommonVariantField<LibObjT> {this->_libObjPtr()};
1367 }
1368
1369 } // namespace bt2
1370
1371 #endif // BABELTRACE_CPP_COMMON_BT2_FIELD_HPP
This page took 0.058462 seconds and 4 git commands to generate.