RTC Toolkit 5.0.0
Loading...
Searching...
No Matches
repositoryIf.ipp
Go to the documentation of this file.
1
13// Note this is a template implementation file and should not be included directly.
14// The typical header protection macro is not added to avoid it showing up in Doxygen API
15// documentation.
16#pragma once
17
19
20#include <fmt/format.h>
21
22#include <boost/container/vector.hpp>
23#include <boost/core/demangle.hpp>
24
25#include <cassert>
26#include <exception>
27#include <memory>
28#include <unordered_set>
29#include <utility>
30
32
33namespace detail {
34
35template <typename T>
43
48
54
57 bool recurse;
58 std::pair<RepositoryIf::PathList, RepositoryIf::PathList>& result;
60};
61
62template <typename T>
64 using ElementType = T;
65 using PrepareFunctionType = std::function<gsl::span<T>(const RepositoryIf::MetaData&)>;
67 // The following function is given by the caller to prepare the buffer to be filled.
68 // It can use the metadata available for the datapoint to resize the buffer object for
69 // example. This is called by the adapter just before filling the returned span with
70 // deserialised data.
72 std::optional<std::reference_wrapper<RepositoryIf::MetaData>> metadata;
74};
75
76template <typename T>
84
85template <typename T>
87 using ElementType = T;
89 gsl::span<T> data;
91 std::optional<std::reference_wrapper<RepositoryIf::MetaData>> output_metadata;
92 size_t offset;
94};
95
96template <typename T>
105
111
117
123
129
132 for (auto dimention : shape) {
134 }
135 return nelements;
136}
137
138template <typename T>
141 using BufferType = T;
142
144 using ElementType = std::remove_cv_t<T>;
145
147 using DataPointType = T;
148
150 static const bool USES_TEMP_BUFFER = false;
151
154
163 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
164 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
165 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
166 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
167 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
168 std::is_same_v<T, RtcDouble>,
169 "The scalar type is not supported.");
170 return {};
171 }
172
178 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
179 return {&buffer, 1};
180 }
181
187 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
188 return {&buffer, 1};
189 }
190
204 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
205 if (shape.size() == 0) {
206 // The shape is for a scalar, so confirm the buffer size is correct.
207 return true;
208 } else {
209 return false;
210 }
211 }
212
227 std::shared_ptr<TempBufferType>& temp_buffer,
228 size_t offset,
229 size_t count) = delete;
230
245 const std::shared_ptr<TempBufferType>& temp_buffer,
246 size_t offset,
247 size_t count) = delete;
248};
249
250template <>
251struct UserTypeHandler<std::string> {
252 using BufferType = std::string;
253 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
255 static const bool USES_TEMP_BUFFER = false;
257
259 return {buffer.size()};
260 }
261
262 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
263 return {buffer};
264 }
265
266 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
267 return {buffer};
268 }
269
270 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
271 if (shape.size() == 1) {
272 buffer.resize(shape[0]);
273 } else {
274 buffer.resize(GetNumOfElements(shape));
275 }
276 return true;
277 }
278};
279
280template <>
282 using BufferType = std::string_view;
283 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
285 static const bool USES_TEMP_BUFFER = false;
287
289 return {buffer.size()};
290 }
291
295 static gsl::span<ElementType> MakeSpan(BufferType& buffer) = delete;
296
297 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
298 return {buffer.data(), buffer.size()};
299 }
300
301 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
302 if (shape.size() == 1 and shape[0] == buffer.size()) {
303 // Cannot resize, but the shape and size is correct, so return true.
304 return true;
305 } else {
306 return false;
307 }
308 }
309};
310
311template <typename T, typename A>
312struct UserTypeHandler<std::vector<T, A>> {
313 using BufferType = std::vector<T, A>;
314 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
316 static const bool USES_TEMP_BUFFER = false;
318
320 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
321 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
322 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
323 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
324 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
325 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString> or
326 std::is_same_v<T, std::byte>,
327 "The vector type is not supported.");
328 return {buffer.size()};
329 }
330
331 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
332 return {buffer};
333 }
334
335 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
336 return {buffer};
337 }
338
339 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
340 if (shape.size() == 1) {
341 buffer.resize(shape[0]);
342 } else {
343 buffer.resize(GetNumOfElements(shape));
344 }
345 return true;
346 }
347};
348
349template <typename A>
350struct UserTypeHandler<std::vector<bool, A>> {
351 using BufferType = std::vector<bool, A>;
352 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
354 static const bool USES_TEMP_BUFFER = true;
355 using TempBufferType = boost::container::vector<bool>;
356
358 return {buffer.size()};
359 }
360
364 static gsl::span<ElementType> MakeSpan(BufferType& buffer) = delete;
365
369 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) = delete;
370
371 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
372 if (shape.size() == 1) {
373 buffer.resize(shape[0]);
374 } else {
375 buffer.resize(GetNumOfElements(shape));
376 }
377 return true;
378 }
379
381 std::shared_ptr<TempBufferType>& temp_buffer,
382 size_t offset,
383 size_t count) {
384 assert((buffer.size() >= offset + count) && ("The input buffer is too small."));
385 assert((temp_buffer->size() >= count) && ("The temporary buffer is too small."));
386 std::copy(buffer.begin() + offset, buffer.begin() + offset + count, temp_buffer->begin());
387 }
388
390 const std::shared_ptr<TempBufferType>& temp_buffer,
391 size_t offset,
392 size_t count) {
393 assert((buffer.size() >= offset + count) && ("The output buffer is too small."));
394 assert((temp_buffer->size() >= count) && ("The temporary buffer is too small."));
395 std::copy(temp_buffer->begin(), temp_buffer->begin() + count, buffer.begin() + offset);
396 }
397};
398
399template <typename T, typename A>
400struct UserTypeHandler<boost::container::vector<T, A>> {
401 using BufferType = boost::container::vector<T, A>;
402 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
404 static const bool USES_TEMP_BUFFER = false;
406
408 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
409 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
410 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
411 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
412 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
413 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString> or
414 std::is_same_v<T, std::byte>,
415 "The vector type is not supported.");
416 return {buffer.size()};
417 }
418
419 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
420 return {buffer};
421 }
422
423 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
424 return {buffer};
425 }
426
427 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
428 if (shape.size() == 1) {
429 buffer.resize(shape[0]);
430 } else {
431 buffer.resize(GetNumOfElements(shape));
432 }
433 return true;
434 }
435};
436
437template <typename T, decltype(gsl::dynamic_extent) N>
438struct UserTypeHandler<gsl::span<T, N>> {
439 using BufferType = gsl::span<T, N>;
440 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
442 static const bool USES_TEMP_BUFFER = false;
444
446 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
447 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
448 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
449 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
450 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
451 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString> or
452 std::is_same_v<T, std::byte>,
453 "The vector type is not supported.");
454 return {buffer.size()};
455 }
456
457 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
458 return {buffer};
459 }
460
461 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
462 return {buffer};
463 }
464
465 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
466 if (shape.size() == 1 and shape[0] == buffer.size()) {
467 // Cannot resize, but the shape and size is correct, so return true.
468 return true;
469 } else {
470 return false;
471 }
472 }
473};
474
475template <decltype(gsl::dynamic_extent) N>
476struct UserTypeHandler<gsl::span<char, N>> {
477 using BufferType = gsl::span<char, N>;
478 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
480 static const bool USES_TEMP_BUFFER = false;
482
484 return {buffer.size()};
485 }
486
487 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
488 return {buffer};
489 }
490
491 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
492 return {buffer};
493 }
494
495 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
496 return false;
497 }
498};
499
500template <typename T, typename A>
503 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
505 static const bool USES_TEMP_BUFFER = false;
507
509 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
510 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
511 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
512 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
513 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
514 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString>,
515 "The matrix type is not supported.");
516 return {buffer.GetNrows(), buffer.GetNcols()};
517 }
518
519 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
520 return {buffer.data(), GetNumOfElements(GetShape(buffer))};
521 }
522
523 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
524 return {buffer.data(), buffer.GetNrows() * buffer.GetNcols()};
525 }
526
527 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
528 if (shape.size() == 2) {
529 buffer.resize(shape[0], shape[1]);
530 } else {
531 buffer.resize(1, GetNumOfElements(shape));
532 }
533 return true;
534 }
535};
536
537template <typename A>
540 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
542 static const bool USES_TEMP_BUFFER = true;
543 using TempBufferType = boost::container::vector<bool>;
544
546 return {buffer.GetNrows(), buffer.GetNcols()};
547 }
548
552 static gsl::span<ElementType> MakeSpan(BufferType& buffer) = delete;
553
557 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) = delete;
558
559 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
560 if (shape.size() == 2) {
561 buffer.resize(shape[0], shape[1]);
562 } else {
563 buffer.resize(1, GetNumOfElements(shape));
564 }
565 return true;
566 }
567
569 std::shared_ptr<TempBufferType>& temp_buffer,
570 size_t offset,
571 size_t count) {
572 assert((buffer.size() >= offset + count) && ("The input buffer is too small."));
573 assert((temp_buffer->size() >= count) && ("The temporary buffer is too small."));
574 std::copy(buffer.begin() + offset, buffer.begin() + offset + count, temp_buffer->begin());
575 }
576
578 const std::shared_ptr<TempBufferType>& temp_buffer,
579 size_t offset,
580 size_t count) {
581 assert((buffer.size() >= offset + count) && ("The output buffer is too small."));
582 assert((temp_buffer->size() >= count) && ("The temporary buffer is too small."));
583 std::copy(temp_buffer->begin(), temp_buffer->begin() + count, buffer.begin() + offset);
584 }
585};
586
587template <typename T>
590 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
592 static const bool USES_TEMP_BUFFER = false;
594
596 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
597 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
598 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
599 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
600 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
601 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString>,
602 "The matrix type is not supported.");
603 return {buffer.GetNrows(), buffer.GetNcols()};
604 }
605
606 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
607 return {buffer.data(), GetNumOfElements(GetShape(buffer))};
608 }
609
610 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
611 return {buffer.data(), buffer.GetNrows() * buffer.GetNcols()};
612 }
613
614 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
615 if (shape.size() == 2 and shape[0] == buffer.GetNrows() and shape[1] == buffer.GetNcols()) {
616 // Cannot resize, but the shape and size is correct, so return true.
617 return true;
618 } else {
619 return false;
620 }
621 }
622};
623
624template <typename T, std::size_t N>
625struct UserTypeHandler<std::array<T, N>> {
626 using BufferType = std::array<T, N>;
627 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
629 static const bool USES_TEMP_BUFFER = false;
631
633 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
634 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
635 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
636 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
637 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
638 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString> or
639 std::is_same_v<T, std::byte>,
640 "The array type is not supported.");
641 return {buffer.size()};
642 }
643
644 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
645 return {buffer};
646 }
647
648 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
649 return {buffer};
650 }
651
652 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
653 if (shape.size() == 1 and shape[0] == buffer.size()) {
654 // Cannot resize, but the shape and size is correct, so return true.
655 return true;
656 } else {
657 return false;
658 }
659 }
660};
661
662template <std::size_t N>
663struct UserTypeHandler<std::array<char, N>> {
664 using BufferType = std::array<char, N>;
665 using ElementType = std::remove_cv_t<typename BufferType::value_type>;
667 static const bool USES_TEMP_BUFFER = false;
669
671 return {buffer.size()};
672 }
673
674 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
675 return {buffer};
676 }
677
678 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
679 return {buffer};
680 }
681
682 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
683 if (shape.size() == 1 and shape[0] == buffer.size()) {
684 // Cannot resize, but the shape and size is correct, so return true.
685 return true;
686 } else {
687 return false;
688 }
689 }
690};
691
692template <typename T, std::size_t N, std::size_t M>
693struct UserTypeHandler<std::array<std::array<T, M>, N>> {
694 using BufferType = std::array<std::array<T, M>, N>;
695 using ElementType = std::remove_cv_t<T>;
697 static const bool USES_TEMP_BUFFER = false;
699
701 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
702 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
703 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
704 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
705 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
706 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString>,
707 "The array type is not supported.");
708 return {N, M};
709 }
710
711 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
712 static_assert(sizeof(BufferType) == sizeof(ElementType) * N * M);
713 ElementType* begin = &buffer[0][0];
714 return {begin, N * M};
715 }
716
717 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
718 static_assert(sizeof(BufferType) == sizeof(ElementType) * N * M);
719 const ElementType* begin = &buffer[0][0];
720 return {begin, N * M};
721 }
722
723 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
724 if (shape.size() == 2 and shape[0] == N and shape[1] == M) {
725 // Cannot resize, but the shape and size is correct, so return true.
726 return true;
727 } else {
728 return false;
729 }
730 }
731};
732
736template <typename T, std::size_t N>
737struct UserTypeHandler<T[N]> {
738 using BufferType = T[N];
739 using ElementType = std::remove_cv_t<T>;
741 static const bool USES_TEMP_BUFFER = false;
743
745 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
746 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
747 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
748 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
749 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
750 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString> or
751 std::is_same_v<T, std::byte>,
752 "The array type is not supported.");
753 return {N};
754 }
755
756 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
757 return {buffer};
758 }
759
760 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
761 return {buffer};
762 }
763
764 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
765 if (shape.size() == 1 and shape[0] == N) {
766 // Cannot resize, but the shape and size is correct, so return true.
767 return true;
768 } else {
769 return false;
770 }
771 }
772};
773
774template <std::size_t N>
776 using BufferType = char[N];
779 static const bool USES_TEMP_BUFFER = false;
781
783 return {N};
784 }
785
786 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
787 return {buffer};
788 }
789
790 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
791 return {buffer};
792 }
793
794 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
795 if (shape.size() == 1 and shape[0] == N) {
796 // Cannot resize, but the shape and size is correct, so return true.
797 return true;
798 } else {
799 return false;
800 }
801 }
802};
803
807template <typename T, std::size_t N, std::size_t M>
808struct UserTypeHandler<T[N][M]> {
809 using BufferType = T[N][M];
810 using ElementType = std::remove_cv_t<T>;
812 static const bool USES_TEMP_BUFFER = false;
814
816 static_assert(std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or
817 std::is_same_v<T, RtcInt16> or std::is_same_v<T, RtcInt32> or
818 std::is_same_v<T, RtcInt64> or std::is_same_v<T, RtcUInt8> or
819 std::is_same_v<T, RtcUInt16> or std::is_same_v<T, RtcUInt32> or
820 std::is_same_v<T, RtcUInt64> or std::is_same_v<T, RtcFloat> or
821 std::is_same_v<T, RtcDouble> or std::is_same_v<T, RtcString>,
822 "The array type is not supported.");
823 return {N, M};
824 }
825
826 static gsl::span<ElementType> MakeSpan(BufferType& buffer) {
827 static_assert(sizeof(BufferType) == sizeof(ElementType) * N * M);
828 return {&buffer[0][0], N * M};
829 }
830
831 static gsl::span<const ElementType> MakeSpan(const BufferType& buffer) {
832 static_assert(sizeof(BufferType) == sizeof(ElementType) * N * M);
833 return {&buffer[0][0], N * M};
834 }
835
836 static bool ResizeBuffer(BufferType& buffer, const RtcVectorUInt64& shape) {
837 if (shape.size() == 2 and shape[0] == N and shape[1] == M) {
838 // Cannot resize, but the shape and size is correct, so return true.
839 return true;
840 } else {
841 return false;
842 }
843 }
844};
845
846} // namespace detail
847
848namespace {
849
856inline bool TypeIsAllowedForValue(const std::type_info& type) {
857 static const std::unordered_set<std::type_index> valid_types = {
858 // Void values are acceptable and represent null values, e.g. equivalent to Python None.
859 std::type_index(typeid(void)),
860 std::type_index(typeid(RtcBool)),
861 std::type_index(typeid(RtcInt8)),
862 std::type_index(typeid(RtcInt16)),
863 std::type_index(typeid(RtcInt32)),
864 std::type_index(typeid(RtcInt64)),
865 std::type_index(typeid(RtcUInt8)),
866 std::type_index(typeid(RtcUInt16)),
867 std::type_index(typeid(RtcUInt32)),
868 std::type_index(typeid(RtcUInt64)),
869 std::type_index(typeid(RtcFloat)),
870 std::type_index(typeid(RtcDouble)),
871 std::type_index(typeid(RtcString)),
872 std::type_index(typeid(RtcBinary)),
873 std::type_index(typeid(RtcVectorUInt64)),
874 // The following is the type actually stored in the std::any object.
875 std::type_index(typeid(std::reference_wrapper<const std::type_info>)),
876 std::type_index(typeid(RepositoryIf::Timestamp)),
877 std::type_index(typeid(DataPointPath)),
878 std::type_index(typeid(std::set<DataPointPath>))};
879
880#if __cplusplus >= 202002L
881 return valid_types.contains(std::type_index(type));
882#else
883 return valid_types.find(std::type_index(type)) != valid_types.end();
884#endif
885}
886
894inline const std::type_info& GetMetaDataReservedKeyType(const std::string& key) {
895 static const std::map<std::string, const std::type_info&> reserved_key_types = {
896 {"type", typeid(std::reference_wrapper<const std::type_info>)},
897 {"shape", typeid(RtcVectorUInt64)},
898 {"timestamp", typeid(RepositoryIf::Timestamp)},
899 {"sequence_id", typeid(RtcUInt64)},
900 {"symlink_target", typeid(DataPointPath)},
901 {"symlinks", typeid(std::set<DataPointPath>)},
902 };
903 auto iter = reserved_key_types.find(key);
904 if (iter != reserved_key_types.end()) {
905 return iter->second;
906 } else {
907 return typeid(void);
908 }
909}
910
922inline void CheckMetaDataTypeForReservedKeys(const std::string& key, const std::type_info& type) {
923 const std::type_info& type_expected = GetMetaDataReservedKeyType(key);
924 // Note that if "type" is void, i.e. a null value is being assigned, this is accepted as OK.
925 if (type_expected != typeid(void) and type != typeid(void) and type_expected != type) {
926 throw CII_MAKE_EXCEPTION(RepositoryIf::MetaData::TypeMismatch, key, type, type_expected);
927 }
928}
929
938inline void CheckMetaDataValueType(const std::string& key, const std::type_info& type) {
939 const std::type_info& type_expected = GetMetaDataReservedKeyType(key);
940 if (type_expected != typeid(void)) {
941 // Dealing with a reserved key. Therefore check that the type being assigned is the one that
942 // is expected for such a key. Note that "type" being effectively a null value is OK.
943 if (type != typeid(void) and type_expected != type) {
944 throw CII_MAKE_EXCEPTION(
945 RepositoryIf::MetaData::TypeMismatch, key, type, type_expected);
946 }
947 } else {
948 // Dealing with a general unreserved user key. Therefore check that the type being assigned
949 // is from the list of allowed types.
950 if (not TypeIsAllowedForValue(type)) {
951 throw CII_MAKE_EXCEPTION(RepositoryIf::MetaData::UnsupportedType, type);
952 }
953 }
954}
955
963template <typename T>
964void CheckMetaDataValueType(const std::string& key) {
965 static_assert(
966 std::is_same_v<T, RtcBool> or std::is_same_v<T, RtcInt8> or std::is_same_v<T, RtcInt16> or
967 std::is_same_v<T, RtcInt32> or std::is_same_v<T, RtcInt64> or
968 std::is_same_v<T, RtcUInt8> or std::is_same_v<T, RtcUInt16> or
969 std::is_same_v<T, RtcUInt32> or std::is_same_v<T, RtcUInt64> or
970 std::is_same_v<T, RtcFloat> or std::is_same_v<T, RtcDouble> or
971 std::is_same_v<T, RtcString> or std::is_same_v<T, RtcBinary> or
972 std::is_same_v<T, RtcVectorUInt64> or std::is_same_v<T, const std::type_info&> or
973 std::is_same_v<T, RepositoryIf::Timestamp> or std::is_same_v<T, DataPointPath> or
974 std::is_same_v<T, std::set<DataPointPath>>,
975 "The type is not supported for MetaData values.");
976 if constexpr (std::is_same_v<T, const std::type_info&>) {
977 CheckMetaDataTypeForReservedKeys(key, typeid(std::reference_wrapper<const std::type_info>));
978 } else {
980 }
981}
982
990inline bool MetaDataKeyValueIsValid(const std::string& key, const std::any& value) {
991 const std::type_info& type_expected = GetMetaDataReservedKeyType(key);
992 if (type_expected != typeid(void)) {
993 // Dealing with a reserved key. Therefore just check that the type of the value is the same
994 // as the one expected.
995 if (value.type() != typeid(void)) {
996 return type_expected == value.type();
997 } else {
998 // If value has a void type, i.e. std::any is unassigned, this is a valid state.
999 return true;
1000 }
1001 } else {
1002 // Dealing with a general unreserved user key. Therefore check that the value has a type
1003 // from the allowed list.
1004 return TypeIsAllowedForValue(value.type());
1005 }
1006}
1007
1020template <typename T>
1021void CheckSpanSize(const T& span, const RepositoryIf::MetaData& metadata) {
1022 size_t expected_size = detail::GetNumOfElements(metadata["shape"].Cast<RtcVectorUInt64>());
1023 if (expected_size > span.size()) {
1024 throw CII_MAKE_EXCEPTION(RepositoryIf::BufferTooSmall, span.size(), expected_size);
1025 }
1026}
1027
1028} // namespace
1029
1030inline bool RepositoryIf::MetaData::ConstValueProxy::HasValue() const noexcept {
1031 return m_value.has_value();
1032}
1033
1034inline RepositoryIf::MetaData::ConstValueProxy::operator const std::any&() const {
1035 return m_value;
1036}
1037
1038template <typename T>
1039const T& RepositoryIf::MetaData::ConstValueProxy::Cast() const {
1041 if constexpr (std::is_same_v<T, const std::type_info&>) {
1042 return std::any_cast<std::reference_wrapper<const std::type_info>>(m_value).get();
1043 } else {
1044 return std::any_cast<const T&>(m_value);
1045 }
1046}
1047
1049 const std::any& value)
1050 : m_key(key), m_value(value) {
1051}
1052
1053inline bool RepositoryIf::MetaData::ValueProxy::HasValue() const noexcept {
1054 return m_value.has_value();
1055}
1056
1057inline RepositoryIf::MetaData::ValueProxy::operator const std::any&() const {
1058 return m_value;
1059}
1060
1061template <typename T>
1062T& RepositoryIf::MetaData::ValueProxy::Cast() {
1064 if constexpr (std::is_same_v<T, const std::type_info&>) {
1065 return std::any_cast<std::reference_wrapper<const std::type_info>>(m_value).get();
1066 } else {
1067 return std::any_cast<T&>(m_value);
1068 }
1069}
1070
1071template <typename T>
1072const T& RepositoryIf::MetaData::ValueProxy::Cast() const {
1074 if constexpr (std::is_same_v<T, const std::type_info&>) {
1075 return std::any_cast<std::reference_wrapper<const std::type_info>>(m_value).get();
1076 } else {
1077 return std::any_cast<const T&>(m_value);
1078 }
1079}
1080
1081template <typename T>
1083 using U = std::remove_cv_t<std::remove_reference_t<T>>;
1084 if constexpr (std::is_same_v<U, ValueProxy> or std::is_same_v<U, ConstValueProxy>) {
1085 // If assigning from ValueProxy or ConstValueProxy then just copy the value.
1086 CheckMetaDataTypeForReservedKeys(m_key, rhs.m_value.type());
1087 m_value = rhs.m_value;
1088 } else if constexpr (std::is_rvalue_reference_v<decltype(rhs)>) {
1089 // Handle the case where we get an rvalue reference, i.e. dealing with a temp object.
1090 // Move/forward where possible to be more efficient.
1091 if constexpr (std::is_same_v<U, std::type_info>) {
1093 typeid(std::reference_wrapper<const std::type_info>));
1094 m_value = std::make_any<std::reference_wrapper<const std::type_info>>(rhs);
1095 } else if constexpr (std::is_same_v<U, std::any>) {
1096 CheckMetaDataValueType(m_key, rhs.type());
1097 m_value = std::move(rhs);
1098 } else {
1100 m_value = std::forward<T>(rhs);
1101 }
1102 } else {
1103 // Handle the case where we get an lvalue reference.
1104 if constexpr (std::is_same_v<U, std::type_info>) {
1106 typeid(std::reference_wrapper<const std::type_info>));
1107 m_value = std::make_any<std::reference_wrapper<const std::type_info>>(rhs);
1108 } else if constexpr (std::is_same_v<U, std::any>) {
1109 CheckMetaDataValueType(m_key, rhs.type());
1110 m_value = rhs;
1111 } else {
1113 m_value = rhs;
1114 }
1115 }
1116 assert(MetaDataKeyValueIsValid(m_key, m_value) &&
1117 ("Metadata was modified in an invalid manner."));
1118 return *this;
1119}
1120
1121inline void RepositoryIf::MetaData::ValueProxy::Reset() noexcept {
1122 return m_value.reset();
1123}
1124
1125inline RepositoryIf::MetaData::ValueProxy::ValueProxy(const std::string& key, std::any& value)
1126 : m_key(key), m_value(value) {
1127}
1128
1129template <typename MapIterType, typename ProxyType>
1130typename RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::value_type&
1131RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator*() {
1132 m_pair.emplace(m_iterator->first, ProxyType(m_iterator->first, m_iterator->second));
1133 return m_pair.value();
1134}
1135
1136template <typename MapIterType, typename ProxyType>
1137typename RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::value_type
1138RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator*() const {
1139 return value_type(m_iterator->first, ProxyType(m_iterator->first, m_iterator->second));
1140}
1141
1142template <typename MapIterType, typename ProxyType>
1143typename RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::value_type*
1144RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator->() {
1145 m_pair.emplace(m_iterator->first, ProxyType(m_iterator->first, m_iterator->second));
1146 return &m_pair.value();
1147}
1148
1149template <typename MapIterType, typename ProxyType>
1150const typename RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::value_type*
1151RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator->() const {
1152 m_pair.emplace(m_iterator->first, ProxyType(m_iterator->first, m_iterator->second));
1153 return &m_pair.value();
1154}
1155
1156template <typename MapIterType, typename ProxyType>
1157RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>&
1158RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator++() {
1159 ++m_iterator;
1160 return *this;
1161}
1162
1163template <typename MapIterType, typename ProxyType>
1164RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>
1165RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator++(int) {
1166 auto tmp = *this;
1167 ++m_iterator;
1168 return tmp;
1169}
1170
1171template <typename MapIterType, typename ProxyType>
1172RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>&
1173RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator--() {
1174 --m_iterator;
1175 return *this;
1176}
1177
1178template <typename MapIterType, typename ProxyType>
1179RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>
1180RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator--(int) {
1181 auto tmp = *this;
1182 --m_iterator;
1183 return tmp;
1184}
1185
1186template <typename MapIterType, typename ProxyType>
1187bool RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator==(
1188 const RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>& rhs) const {
1189 return m_iterator == rhs.m_iterator;
1190}
1191
1192template <typename MapIterType, typename ProxyType>
1193bool RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::operator!=(
1194 const RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>& rhs) const {
1195 return m_iterator != rhs.m_iterator;
1196}
1197
1198template <typename MapIterType, typename ProxyType>
1199RepositoryIf::MetaData::IteratorImpl<MapIterType, ProxyType>::IteratorImpl(MapIterType&& iter)
1200 : m_iterator(std::forward<MapIterType>(iter)) {
1201}
1202
1203inline RepositoryIf::MetaData::Iterator::Iterator(RepositoryIf::MetaData::MapType::iterator&& iter)
1204 : RepositoryIf::MetaData::IteratorImpl<RepositoryIf::MetaData::MapType::iterator,
1205 RepositoryIf::MetaData::ValueProxy>(
1206 std::forward<RepositoryIf::MetaData::MapType::iterator>(iter)) {
1207}
1208
1209inline RepositoryIf::MetaData::ConstIterator::ConstIterator(
1210 RepositoryIf::MetaData::MapType::const_iterator&& iter)
1211 : RepositoryIf::MetaData::IteratorImpl<RepositoryIf::MetaData::MapType::const_iterator,
1212 RepositoryIf::MetaData::ConstValueProxy>(
1213 std::forward<RepositoryIf::MetaData::MapType::const_iterator>(iter)) {
1214}
1215
1216inline RepositoryIf::MetaData::ReverseIterator::ReverseIterator(
1217 RepositoryIf::MetaData::MapType::reverse_iterator&& iter)
1218 : RepositoryIf::MetaData::IteratorImpl<RepositoryIf::MetaData::MapType::reverse_iterator,
1219 RepositoryIf::MetaData::ValueProxy>(
1220 std::forward<RepositoryIf::MetaData::MapType::reverse_iterator>(iter)) {
1221}
1222
1223inline RepositoryIf::MetaData::ConstReverseIterator::ConstReverseIterator(
1224 MapType::const_reverse_iterator&& iter)
1225 : RepositoryIf::MetaData::IteratorImpl<RepositoryIf::MetaData::MapType::const_reverse_iterator,
1226 RepositoryIf::MetaData::ConstValueProxy>(
1227 std::forward<RepositoryIf::MetaData::MapType::const_reverse_iterator>(iter)) {
1228}
1229
1230inline RepositoryIf::MetaData::TypeMismatch::Attributes::Attributes(
1231 const std::string& key, const std::type_info& type_used, const std::type_info& type_expected)
1232 : m_key(key), m_type_used(type_used), m_type_expected(type_expected) {
1233}
1234
1236 return m_metadata.empty();
1237}
1238
1240 return m_metadata.size();
1241}
1242
1243inline bool RepositoryIf::MetaData::Contains(const std::string& key) const {
1244#if __cplusplus >= 202002L
1245 return m_metadata.contains(key);
1246#else
1247 return m_metadata.find(key) != m_metadata.end();
1248#endif
1249}
1250
1251template <typename T>
1252auto& RepositoryIf::MetaData::Insert(const std::string& key, T&& value) {
1253 std::string key_copy = key;
1254 return Insert(std::move(key_copy), std::forward<T>(value));
1255}
1256
1257template <typename T>
1258auto& RepositoryIf::MetaData::Insert(std::string&& key, T&& value) {
1259 using U = std::remove_cv_t<std::remove_reference_t<T>>;
1260 decltype(m_metadata)::iterator iter;
1261 bool inserted;
1262 if constexpr (std::is_same_v<U, std::type_info>) {
1263 // Handle the case where we are assigning a type_info as the value.
1264 CheckMetaDataTypeForReservedKeys(std::forward<std::string>(key),
1265 typeid(std::reference_wrapper<const std::type_info>));
1266 auto type = std::make_any<std::reference_wrapper<const std::type_info>>(value);
1267 std::tie(iter, inserted) = m_metadata.try_emplace(std::forward<std::string>(key), type);
1268 } else {
1269 CheckMetaDataValueType<U>(std::forward<std::string>(key));
1270 std::tie(iter, inserted) =
1271 m_metadata.try_emplace(std::forward<std::string>(key), std::forward<T>(value));
1272 }
1273 if (not inserted) {
1274 throw CII_MAKE_EXCEPTION(KeyAlreadyExists, std::forward<std::string>(key));
1275 }
1276 assert(MetaDataKeyValueIsValid(iter->first, iter->second) &&
1277 ("Metadata was modified in an invalid manner."));
1278 if constexpr (std::is_same_v<U, std::type_info>) {
1279 return std::any_cast<std::reference_wrapper<const std::type_info>>(iter->second).get();
1280 } else {
1281 return std::any_cast<U&>(iter->second);
1282 }
1283}
1284
1285// The following methods are for STL compatibility and therefore must use lower case.
1286// NOLINTBEGIN(readability-identifier-naming)
1288 return m_metadata.begin();
1289};
1290
1292 return m_metadata.begin();
1293};
1294
1298
1300 return m_metadata.end();
1301};
1302
1304 return m_metadata.end();
1305};
1306
1310
1312 return m_metadata.rbegin();
1313};
1314
1316 return m_metadata.rbegin();
1317};
1318
1321 return m_metadata.crbegin();
1322};
1323
1325 return m_metadata.rend();
1326};
1327
1329 return m_metadata.rend();
1330};
1331
1335// NOLINTEND(readability-identifier-naming)
1336
1337template <typename T>
1339 const DataPointPath& path,
1340 const T& initial_value,
1341 std::optional<std::reference_wrapper<const MetaData>> metadata,
1342 const CallbackType& callback) {
1343 using TypeHandler = detail::UserTypeHandler<T>;
1344
1346 if (metadata.has_value()) {
1347 merged_metadata = metadata.value();
1348 }
1349 auto shape = TypeHandler::GetShape(initial_value);
1350 merged_metadata["type"] = typeid(typename TypeHandler::DataPointType);
1351 merged_metadata["shape"] = shape;
1352
1353 if constexpr (TypeHandler::USES_TEMP_BUFFER) {
1354 // If the type handler indicates it needs a temporary buffer, then we need to create it from
1355 // the initial_value buffer by resizing it appropriately and copying the data over.
1356 // Next, we create a span compatible with the new temporary buffer (not a span from the
1357 // original initial_value!), which is passed onto the actual request.
1358 using TempBufferType = typename TypeHandler::TempBufferType;
1360 auto temp_buffer = std::make_shared<TempBufferType>();
1361 bool buffer_resized = TempBufferHandler::ResizeBuffer(*temp_buffer, shape);
1362 if (not buffer_resized) {
1363 throw CII_MAKE_EXCEPTION(
1365 fmt::format("Resizing of a '{}' buffer should have succeeded.",
1366 boost::core::demangle(typeid(TempBufferType).name())));
1367 }
1368 auto count = detail::GetNumOfElements(shape);
1369 TypeHandler::CopyToTempBuffer(initial_value, temp_buffer, 0, count);
1370 auto span = TempBufferHandler::MakeSpan(*temp_buffer);
1371
1372 // A customised callback is also needed to cleanup the buffer once the request has
1373 // completed. Also need to remember to call the actual user callback if one was provided.
1374 auto cb = [temp_buffer, callback](const DataPointPath& path) mutable {
1375 temp_buffer.reset();
1376 if (callback) {
1377 callback(path);
1378 }
1379 };
1380
1381 using ElementType = typename TempBufferHandler::ElementType;
1382 m_requests.push_back(detail::CreateRequest<ElementType>{
1383 path, std::move(span), std::move(merged_metadata), std::move(cb)});
1384 } else {
1385 // If a temporary buffer is not needed then just create the appropriate span directly from
1386 // the initial_value buffer and register the request.
1387 auto span = TypeHandler::MakeSpan(initial_value);
1388 using ElementType = typename TypeHandler::ElementType;
1389 m_requests.push_back(detail::CreateRequest<ElementType>{
1390 path, std::move(span), std::move(merged_metadata), callback});
1391 }
1392}
1393
1394template <typename T>
1396 const DataPointPath& path,
1397 T& buffer,
1398 std::optional<std::reference_wrapper<MetaData>> metadata,
1399 const CallbackType& callback) const {
1400 static_assert(not std::is_same_v<T, std::string_view>,
1401 "It is not possible to read data from a datapoint into a read-only string_view.");
1402
1403 using TypeHandler = detail::UserTypeHandler<T>;
1404 using DataPointType = typename TypeHandler::DataPointType; // Expected type of the data point.
1405
1406 if constexpr (TypeHandler::USES_TEMP_BUFFER) {
1407 using TempBufferType = typename TypeHandler::TempBufferType;
1409 auto temp_buffer = std::make_shared<TempBufferType>();
1410
1411 // If a temporary buffer is needed to handle the given data type T, we need to setup a
1412 // prepare_buffer callback that will allocate the temporary buffer and resize it to the
1413 // required size.
1414 // Note: "buffer" is maintained by the user, therefore its lifetime outlasts the request
1415 // and this callback invocation, therefore it can be captured by reference. The other
1416 // "temp_buffer" and user provided "callback" must be captured by value to have a copy that
1417 // will have a lifetime compatible with the invocation of the "prepare_buffer" and "cb"
1418 // functions.
1419 auto prepare_buffer = [&, temp_buffer](const MetaData& md) {
1420 assert((md.Contains("type")) && ("Adapter must provide the type in the metadata."));
1421 assert((md.Contains("shape")) && ("Adapter must provide the shape in the metadata."));
1422 if (md["type"].Cast<const std::type_info&>() != typeid(DataPointType)) {
1423 throw CII_MAKE_EXCEPTION(IncompatibleType, "Datapoint type mismatch.");
1424 }
1425 const auto& shape = md["shape"].Cast<RtcVectorUInt64>();
1426 TypeHandler::ResizeBuffer(buffer, shape);
1427 TempBufferHandler::ResizeBuffer(*temp_buffer, shape);
1428 // Note: no need to check if buffer was actually resized at this point.
1429 // This is effectively checked by the call to CheckSpanSize later.
1430 auto span = TempBufferHandler::MakeSpan(*temp_buffer);
1431 CheckSpanSize(span, md);
1432 return span;
1433 };
1434
1435 // In the callback we copy the data from the temporary buffer into the original buffer.
1436 // Once the data is copied, cleanup the temporary buffer and remember to call the actual
1437 // user callback if one was provided.
1438 auto cb = [&, temp_buffer, callback](const DataPointPath& path) mutable {
1439 auto shape = TempBufferHandler::GetShape(*temp_buffer);
1440 auto count = detail::GetNumOfElements(shape);
1441 TypeHandler::CopyFromTempBuffer(buffer, temp_buffer, 0, count);
1442 temp_buffer.reset();
1443 if (callback) {
1444 callback(path);
1445 }
1446 };
1447
1448 using ElementType = typename TempBufferHandler::ElementType;
1449 m_requests.push_back(detail::ReadRequest<ElementType>{
1450 path, std::move(prepare_buffer), metadata, std::move(cb)});
1451 } else {
1452 auto prepare_buffer = [&](const MetaData& md) {
1453 assert((md.Contains("type")) && ("Adapter must provide the type in the metadata."));
1454 assert((md.Contains("shape")) && ("Adapter must provide the shape in the metadata."));
1455 if (md["type"].Cast<const std::type_info&>() != typeid(DataPointType)) {
1456 throw CII_MAKE_EXCEPTION(IncompatibleType, "Datapoint type mismatch.");
1457 }
1458 TypeHandler::ResizeBuffer(buffer, md["shape"].Cast<RtcVectorUInt64>());
1459 auto span = TypeHandler::MakeSpan(buffer);
1460 CheckSpanSize(span, md);
1461 return span;
1462 };
1463
1464 using ElementType = typename TypeHandler::ElementType;
1465 m_requests.push_back(
1466 detail::ReadRequest<ElementType>{path, std::move(prepare_buffer), metadata, callback});
1467 }
1468}
1469
1470template <typename T>
1472 const DataPointPath& path,
1473 const T& buffer,
1474 std::optional<std::reference_wrapper<const MetaData>> metadata,
1475 const CallbackType& callback) {
1476 using TypeHandler = detail::UserTypeHandler<T>;
1477
1479 if (metadata.has_value()) {
1480 merged_metadata = metadata.value();
1481 }
1482 auto shape = TypeHandler::GetShape(buffer);
1483 merged_metadata["type"] = typeid(typename TypeHandler::DataPointType);
1484 merged_metadata["shape"] = shape;
1485
1486 if constexpr (TypeHandler::USES_TEMP_BUFFER) {
1487 // If the type handler indicates it needs a temporary buffer, then create it, resize it to
1488 // the required size and copy the data from the input buffer into the temporary buffer.
1489 // Next, we create a span compatible with the new temporary buffer (not a span from the
1490 // original initial_value!), which is passed onto the actual request.
1491 using TempBufferType = typename TypeHandler::TempBufferType;
1493 auto temp_buffer = std::make_shared<TempBufferType>();
1494 bool buffer_resized = TempBufferHandler::ResizeBuffer(*temp_buffer, shape);
1495 if (not buffer_resized) {
1496 throw CII_MAKE_EXCEPTION(
1498 fmt::format("Resizing of a '{}' buffer should have succeeded.",
1499 boost::core::demangle(typeid(TempBufferType).name())));
1500 }
1501 auto count = detail::GetNumOfElements(shape);
1502 TypeHandler::CopyToTempBuffer(buffer, temp_buffer, 0, count);
1503 auto span = TempBufferHandler::MakeSpan(*temp_buffer);
1504
1505 // A customised callback is also needed to cleanup the buffer once the request has
1506 // completed. Remember to call the actual user callback if one was provided.
1507 auto cb = [temp_buffer, callback](const DataPointPath& path) mutable {
1508 temp_buffer.reset();
1509 if (callback) {
1510 callback(path);
1511 }
1512 };
1513
1514 using ElementType = typename TempBufferHandler::ElementType;
1515 m_requests.push_back(detail::WriteRequest<ElementType>{
1516 path, std::move(span), std::move(merged_metadata), std::move(cb)});
1517 } else {
1518 auto span = TypeHandler::MakeSpan(buffer);
1519 using ElementType = typename TypeHandler::ElementType;
1520 m_requests.push_back(detail::WriteRequest<ElementType>{
1521 path, std::move(span), std::move(merged_metadata), callback});
1522 }
1523}
1524
1525template <typename T>
1527 const DataPointPath& path,
1528 T& buffer,
1529 size_t first,
1530 size_t last,
1531 size_t d_first,
1532 std::optional<std::reference_wrapper<MetaData>> metadata,
1533 const CallbackType& callback) const {
1534 using TypeHandler = detail::UserTypeHandler<T>;
1535
1536 auto shape = TypeHandler::GetShape(buffer);
1537 size_t buffer_size = detail::GetNumOfElements(shape);
1538 size_t expected_size = d_first + last - first;
1539 if (first > last or expected_size > buffer_size) {
1541 buffer_size,
1543 "Make sure first <= last and d_first + last - first <= number of "
1544 "elements in the output buffer.");
1545 }
1546 MetaData input_metadata;
1547 input_metadata["type"] = typeid(typename TypeHandler::DataPointType);
1548 input_metadata["shape"] = shape;
1549
1550 if constexpr (TypeHandler::USES_TEMP_BUFFER) {
1551 // If a temporary buffer is needed to handle the given data type T, we create the temporary
1552 // buffer and resize it as a one dimensional array. It should hold just enough elements to
1553 // store the actual number that will be read from the datapoint.
1554 // Next, we create a span compatible with the new temporary buffer (not a span from the
1555 // original output buffer!), which is passed onto the actual request. Thus, the repository
1556 // adapter will actually write into the temporary buffer, from which we later copy back into
1557 // the original output buffer.
1558 using TempBufferType = typename TypeHandler::TempBufferType;
1560 auto temp_buffer = std::make_shared<TempBufferType>();
1561 bool buffer_resized = TempBufferHandler::ResizeBuffer(*temp_buffer, {last - first});
1562 if (not buffer_resized) {
1563 throw CII_MAKE_EXCEPTION(
1565 fmt::format("Resizing of a '{}' buffer should have succeeded.",
1566 boost::core::demangle(typeid(TempBufferType).name())));
1567 }
1568 auto span = TempBufferHandler::MakeSpan(*temp_buffer);
1569 assert((span.size() >= last - first) &&
1570 ("The temporary buffer was not resized correctly."));
1571
1572 // In the callback we copy the data from the temporary buffer into the original buffer.
1573 // Note: the temporary buffer is treated as a one dimensional array.
1574 // Once the data is copied, cleanup the temporary buffer and remember to call the actual
1575 // user callback if one was provided.
1576 auto cb =
1577 [&, temp_buffer, callback, first, last, d_first](const DataPointPath& path) mutable {
1578 TypeHandler::CopyFromTempBuffer(buffer, temp_buffer, d_first, last - first);
1579 temp_buffer.reset();
1580 if (callback) {
1581 callback(path);
1582 }
1583 };
1584
1585 using ElementType = typename TempBufferHandler::ElementType;
1586 m_requests.push_back(detail::PartialReadRequest<ElementType>{
1587 path, span, input_metadata, metadata, first, std::move(cb)});
1588 } else {
1589 auto span = TypeHandler::MakeSpan(buffer);
1590 using ElementType = typename TypeHandler::ElementType;
1591 m_requests.push_back(detail::PartialReadRequest<ElementType>{
1592 path, span.subspan(d_first, last - first), input_metadata, metadata, first, callback});
1593 }
1594}
1595
1596template <typename T>
1598 const DataPointPath& path,
1599 const T& buffer,
1600 size_t first,
1601 size_t last,
1602 size_t d_first,
1603 std::optional<std::reference_wrapper<const MetaData>> metadata,
1604 const CallbackType& callback) {
1605 using TypeHandler = detail::UserTypeHandler<T>;
1606
1607 auto shape = TypeHandler::GetShape(buffer);
1608 size_t buffer_size = detail::GetNumOfElements(shape);
1609 if (first > last or last > buffer_size) {
1610 throw CII_MAKE_EXCEPTION(
1612 buffer_size,
1613 last,
1614 "Make sure first <= last <= number of elements in the input buffer.");
1615 }
1616
1618 if (metadata.has_value()) {
1619 merged_metadata = metadata.value();
1620 }
1621 merged_metadata["type"] = typeid(typename TypeHandler::DataPointType);
1622 merged_metadata["shape"] = shape;
1623
1624 if constexpr (TypeHandler::USES_TEMP_BUFFER) {
1625 // If a temporary buffer is needed to handle the given data type T, we create the temporary
1626 // buffer and resize it as a one dimensional array. It should hold just enough elements to
1627 // store the actual number that will be written to the datapoint.
1628 // The data from the original input buffer is then copied into the temporary buffer.
1629 // Next, we create a span compatible with the new temporary buffer (not a span from the
1630 // original input buffer!), which is passed onto the actual request.
1631 using TempBufferType = typename TypeHandler::TempBufferType;
1633 auto temp_buffer = std::make_shared<TempBufferType>();
1634 bool buffer_resized = TempBufferHandler::ResizeBuffer(*temp_buffer, {last - first});
1635 if (not buffer_resized) {
1636 throw CII_MAKE_EXCEPTION(
1638 fmt::format("Resizing of a '{}' buffer should have succeeded.",
1639 boost::core::demangle(typeid(TempBufferType).name())));
1640 }
1641 TypeHandler::CopyToTempBuffer(buffer, temp_buffer, 0, last - first);
1642 auto span = TempBufferHandler::MakeSpan(*temp_buffer);
1643 assert((span.size() >= last - first) &&
1644 ("The temporary buffer was not resized correctly."));
1645
1646 // A customised callback is also needed to cleanup the buffer once the request has
1647 // completed. Remember to call the actual user callback if one was provided.
1648 auto cb = [temp_buffer, callback](const DataPointPath& path) mutable {
1649 temp_buffer.reset();
1650 if (callback) {
1651 callback(path);
1652 }
1653 };
1654
1655 using ElementType = typename TempBufferHandler::ElementType;
1656 m_requests.push_back(detail::PartialWriteRequest<ElementType>{
1657 path, span, std::move(merged_metadata), d_first, std::move(cb)});
1658 } else {
1659 auto span = TypeHandler::MakeSpan(buffer);
1660 using ElementType = typename TypeHandler::ElementType;
1661 m_requests.push_back(
1663 span.subspan(first, last - first),
1664 std::move(merged_metadata),
1665 d_first,
1666 callback});
1667 }
1668}
1669
1670template <typename Rep, typename Period>
1671bool RepositoryIf::BatchResponse::WaitFor(const std::chrono::duration<Rep, Period>& timeout) {
1672 // Calculate a timepoint in future that will correspond to the requested timeout period and then
1673 // invoke the WaitUntil implementation. We do it this way since we may have multiple futures to
1674 // check. Using WaitUntil will make sure the original timeout period is more closely adhered to
1675 // in such a case.
1676 auto maxtime = Clock::now();
1677 maxtime += std::chrono::duration_cast<Clock::duration>(timeout);
1678 return WaitUntil(maxtime);
1679}
1680
1681template <typename Clk, typename Duration>
1682bool RepositoryIf::BatchResponse::WaitUntil(const std::chrono::time_point<Clk, Duration>& timeout) {
1683 // Check if every future in the responses list is ready.
1684 for (auto& response : m_responses) {
1685 if (response.wait_until(timeout) != std::future_status::ready) {
1686 return false;
1687 }
1688 }
1689 // If we got here then all futures are ready, therefore the call to Wait() should complete
1690 // without blocking.
1691 Wait();
1692 return true;
1693}
1694
1695template <typename T>
1697 BatchRequest req;
1698 T value{};
1699 req.CreateDataPoint(path, value);
1700 SendRequest(req).Wait();
1701}
1702
1703template <typename T>
1705 BatchRequest req;
1706 req.CreateDataPoint(path, initial_value);
1707 SendRequest(req).Wait();
1708}
1709
1710template <typename T>
1712 BatchRequest req;
1713 T result;
1714 req.ReadDataPoint(path, result);
1715 SendRequest(req).Wait();
1716 return result;
1717}
1718
1719template <typename T>
1720void RepositoryIf::SetDataPoint(const DataPointPath& path, const T& value) {
1721 BatchRequest req;
1722 req.WriteDataPoint(path, value);
1723 SendRequest(req).Wait();
1724}
1725
1726template <typename T>
1728 BatchRequest req;
1729 req.ReadDataPoint(path, buffer);
1730 SendRequest(req).Wait();
1731}
1732
1733template <typename T>
1735 BatchRequest req;
1736 req.WriteDataPoint(path, buffer);
1737 SendRequest(req).Wait();
1738}
1739
1740template <typename... T>
1742 std::optional<std::reference_wrapper<const DataPointPath>> path_ref;
1743 BatchRequest req;
1744 (
1745 [&] {
1746 if constexpr (std::is_same_v<const DataPointPath&, decltype(args)>) {
1747 path_ref = args;
1748 } else {
1749 req.WriteDataPoint(path_ref.value().get(), args);
1750 }
1751 }(),
1752 ...);
1753 SendRequest(req).Wait();
1754}
1755
1756template <typename... T>
1758 std::optional<std::reference_wrapper<const DataPointPath>> path_ref;
1759 BatchRequest req;
1760 (
1761 [&] {
1762 if constexpr (std::is_same_v<DataPointPath&, decltype(args)>) {
1763 path_ref = args;
1764 } else {
1765 req.ReadDataPoint(path_ref.value().get(), args);
1766 }
1767 }(),
1768 ...);
1769 SendRequest(req).Wait();
1770}
1771
1773// The following are legacy methods:
1774
1785template <typename T>
1787 m_params.push_back(Parameters(path, &buffer, typeid(buffer), nullptr));
1788}
1789
1818template <typename T, typename F>
1820 static_assert(std::is_convertible_v<F, std::function<void(T&)>>,
1821 "The handler callback must have a signature compatible with void(T&).");
1822 // Prepare a lambda with no arguments that also captures the buffer, i.e. it effectively
1823 // captures the type and allows us to store this in the m_callback member and invoke the
1824 // handler at a later time.
1825 auto callback = [handler, &buffer]() -> void { handler(buffer); };
1826 m_params.push_back(Parameters(path, &buffer, typeid(buffer), callback));
1827}
1828
1839template <typename T>
1841 m_params.push_back(Parameters(path, &buffer, typeid(buffer), nullptr));
1842}
1843
1870template <typename T, typename F>
1872 static_assert(std::is_convertible_v<F, std::function<void(const T&)>>,
1873 "The handler callback must have a signature compatible with void(const T&).");
1874 auto callback = [handler, &buffer]() -> void { handler(buffer); };
1875 m_params.push_back(Parameters(path, &buffer, typeid(buffer), callback));
1876}
1877
1878} // namespace rtctk::componentFramework
This class provides a wrapper for a data point path.
Definition dataPointPath.hpp:74
A buffer class representing 2D matrix data.
Definition matrixBuffer.hpp:28
A span referencing a 2D matrix buffer.
Definition matrixSpan.hpp:35
An object representing one or more asynchronous I/O requests to a repository.
Definition repositoryIf.hpp:683
void ReadDataPoint(const DataPointPath &path, T &buffer, std::optional< std::reference_wrapper< MetaData > > metadata=std::nullopt, const CallbackType &callback=nullptr) const
Definition repositoryIf.ipp:1395
void PartialWriteDataPoint(const DataPointPath &path, const T &buffer, size_t first, size_t last, size_t d_first, std::optional< std::reference_wrapper< const MetaData > > metadata=std::nullopt, const CallbackType &callback=nullptr)
Definition repositoryIf.ipp:1597
void PartialReadDataPoint(const DataPointPath &path, T &buffer, size_t first, size_t last, size_t d_first, std::optional< std::reference_wrapper< MetaData > > metadata=std::nullopt, const CallbackType &callback=nullptr) const
Add request to partially read a datapoint.
Definition repositoryIf.ipp:1526
void CreateDataPoint(const DataPointPath &path, const T &initial_value, std::optional< std::reference_wrapper< const MetaData > > metadata=std::nullopt, const CallbackType &callback=nullptr)
Add a request to create a new datapoint.
Definition repositoryIf.ipp:1338
void WriteDataPoint(const DataPointPath &path, const T &buffer, std::optional< std::reference_wrapper< const MetaData > > metadata=std::nullopt, const CallbackType &callback=nullptr)
Definition repositoryIf.ipp:1471
void Wait()
Definition repositoryIf.cpp:342
bool WaitFor(const std::chrono::duration< Rep, Period > &timeout)
Definition repositoryIf.ipp:1671
bool WaitUntil(const std::chrono::time_point< Clk, Duration > &timeout)
Definition repositoryIf.ipp:1682
Constant version of the bidirectional forward iterator returned by the cbegin/cend methods.
Definition repositoryIf.hpp:410
Constant version of the bidirectional reverse iterator returned by the crbegin/crend methods.
Definition repositoryIf.hpp:431
A read-only interface class to an underlying metadata value.
Definition repositoryIf.hpp:203
Bidirectional forward iterator returned by the begin/end methods.
Definition repositoryIf.hpp:399
Exception indicating that the metadata already contains the given key.
Definition repositoryIf.hpp:452
Bidirectional reverse iterator returned by the rbegin/rend methods.
Definition repositoryIf.hpp:420
Interface class to an underlying metadata value.
Definition repositoryIf.hpp:257
Class for passing/receiving metadata to/from the repository.
Definition repositoryIf.hpp:195
ConstIterator cbegin() const noexcept
Return a read-only forward iterator to the beginning of the metadata entries.
Definition repositoryIf.ipp:1295
MetaData & operator=(const MetaData &rhs)=default
ValueProxy Insert(const std::string &key)
Add a new metadata key.
Definition repositoryIf.cpp:239
size_t GetSize() const noexcept
Get the number of entries in the metadata.
Definition repositoryIf.ipp:1239
Iterator end()
Return a forward iterator to the end of the metadata entries.
Definition repositoryIf.ipp:1299
ReverseIterator rbegin()
Return a reverse iterator to the beginning of the metadata entries.
Definition repositoryIf.ipp:1311
Iterator begin()
Return a forward iterator to the beginning of the metadata entries.
Definition repositoryIf.ipp:1287
ConstReverseIterator crend() const noexcept
Return a read-only reverse iterator to the end of the metadata entries.
Definition repositoryIf.ipp:1332
ConstReverseIterator crbegin() const noexcept
Return a read-only reverse iterator to the beginning of the metadata entries.
Definition repositoryIf.ipp:1320
bool Empty() const
Check if the metadata contains any values.
Definition repositoryIf.ipp:1235
ReverseIterator rend()
Return a reverse iterator to the end of the metadata entries.
Definition repositoryIf.ipp:1324
bool Contains(const std::string &key) const
Check if the metadata contains a specific key.
Definition repositoryIf.ipp:1243
ConstIterator cend() const noexcept
Return a read-only forward iterator to the end of the metadata entries.
Definition repositoryIf.ipp:1307
A structure to hold the arguments passed with one of the Add methods.
Definition repositoryIf.hpp:1212
void Add(const DataPointPath &path, T &buffer)
Adds a datapoint to the request for reading.
Definition repositoryIf.ipp:1786
A structure to hold the arguments passed with one of the Add methods.
Definition repositoryIf.hpp:1285
void Add(const DataPointPath &path, const T &buffer)
Adds a datapoint to the request for writing.
Definition repositoryIf.ipp:1840
Clock::time_point Timestamp
Definition repositoryIf.hpp:111
void WriteDataPoints(const T &... args)
Definition repositoryIf.ipp:1741
T GetDataPoint(const DataPointPath &path) const
Fetches a datapoint from the repository.
Definition repositoryIf.ipp:1711
void ReadDataPoints(T &... args) const
Definition repositoryIf.ipp:1757
void CreateDataPoint(const DataPointPath &path)
Creates a new datapoint in the repository.
Definition repositoryIf.ipp:1696
void SetDataPoint(const DataPointPath &path, const T &value)
Sets a datapoint in the repository.
Definition repositoryIf.ipp:1720
void WriteDataPoint(const DataPointPath &path, const T &buffer)
Writes a datapoint to the repository.
Definition repositoryIf.ipp:1734
BatchResponse SendRequest(const BatchRequest &request)
Definition repositoryIf.cpp:364
void ReadDataPoint(const DataPointPath &path, T &buffer) const
Reads a datapoint from the repository.
Definition repositoryIf.ipp:1727
std::function< void(const DataPointPath &)> CallbackType
Signature of the callback functions that can be registered with the repository requests.
Definition repositoryIf.hpp:114
RtcUInt64 GetNumOfElements(const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:130
Definition commandReplier.cpp:22
elt::mal::future< std::string > InjectReqRepEvent(StateMachineEngine &engine)
Definition malEventInjector.hpp:23
uint64_t RtcUInt64
Definition repositoryIf.hpp:61
uint8_t RtcUInt8
Definition repositoryIf.hpp:58
int64_t RtcInt64
Definition repositoryIf.hpp:57
float RtcFloat
Definition repositoryIf.hpp:62
std::string RtcString
Definition repositoryIf.hpp:64
int8_t RtcInt8
Definition repositoryIf.hpp:54
std::vector< T > RtcVector
Definition repositoryIf.hpp:45
uint32_t RtcUInt32
Definition repositoryIf.hpp:60
bool RtcBool
Definition repositoryIf.hpp:53
int16_t RtcInt16
Definition repositoryIf.hpp:55
RtcMatrix< RtcBool > RtcMatrixBool
Definition repositoryIf.hpp:78
uint16_t RtcUInt16
Definition repositoryIf.hpp:59
RtcVector< RtcBool > RtcVectorBool
Definition repositoryIf.hpp:66
int32_t RtcInt32
Definition repositoryIf.hpp:56
RtcVector< RtcUInt64 > RtcVectorUInt64
Definition repositoryIf.hpp:74
std::vector< std::byte > RtcBinary
Definition repositoryIf.hpp:65
double RtcDouble
Definition repositoryIf.hpp:63
gsl::span< const T > data
Definition repositoryIf.ipp:39
DataPointPath path
Definition repositoryIf.ipp:38
T ElementType
Definition repositoryIf.ipp:37
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:41
RepositoryIf::MetaData metadata
Definition repositoryIf.ipp:40
DataPointPath link_path
Definition repositoryIf.ipp:120
DataPointPath path
Definition repositoryIf.ipp:119
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:121
DataPointPath path
Definition repositoryIf.ipp:45
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:46
DataPointPath path
Definition repositoryIf.ipp:50
bool & result
Definition repositoryIf.ipp:51
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:52
bool recurse
Definition repositoryIf.ipp:57
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:59
std::pair< RepositoryIf::PathList, RepositoryIf::PathList > & result
Definition repositoryIf.ipp:58
DataPointPath path
Definition repositoryIf.ipp:56
DataPointPath path
Definition repositoryIf.ipp:88
gsl::span< T > data
Definition repositoryIf.ipp:89
RepositoryIf::MetaData input_metadata
Definition repositoryIf.ipp:90
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:93
std::optional< std::reference_wrapper< RepositoryIf::MetaData > > output_metadata
Definition repositoryIf.ipp:91
size_t offset
Definition repositoryIf.ipp:92
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:103
DataPointPath path
Definition repositoryIf.ipp:99
RepositoryIf::MetaData metadata
Definition repositoryIf.ipp:101
gsl::span< const T > data
Definition repositoryIf.ipp:100
size_t offset
Definition repositoryIf.ipp:102
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:109
RepositoryIf::MetaData & metadata
Definition repositoryIf.ipp:108
DataPointPath path
Definition repositoryIf.ipp:107
T ElementType
Definition repositoryIf.ipp:64
std::function< gsl::span< T >(const RepositoryIf::MetaData &)> PrepareFunctionType
Definition repositoryIf.ipp:65
std::optional< std::reference_wrapper< RepositoryIf::MetaData > > metadata
Definition repositoryIf.ipp:72
PrepareFunctionType prepare_buffer
Definition repositoryIf.ipp:71
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:73
DataPointPath path
Definition repositoryIf.ipp:66
DataPointPath path
Definition repositoryIf.ipp:125
DataPointPath link_path
Definition repositoryIf.ipp:126
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:127
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:503
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:508
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:523
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:527
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:519
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:559
static gsl::span< ElementType > MakeSpan(BufferType &buffer)=delete
Span not constructable from a MatrixBuffer<bool> type.
boost::container::vector< bool > TempBufferType
Definition repositoryIf.ipp:543
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)=delete
Span not constructable from a MatrixBuffer<bool> type.
static void CopyToTempBuffer(const BufferType &buffer, std::shared_ptr< TempBufferType > &temp_buffer, size_t offset, size_t count)
Definition repositoryIf.ipp:568
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:540
static void CopyFromTempBuffer(BufferType &buffer, const std::shared_ptr< TempBufferType > &temp_buffer, size_t offset, size_t count)
Definition repositoryIf.ipp:577
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:545
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:595
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:606
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:614
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:590
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:610
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:831
std::remove_cv_t< T > ElementType
Definition repositoryIf.ipp:810
T[N][M] BufferType
Definition repositoryIf.ipp:809
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:815
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:836
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:826
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:760
T[N] BufferType
Definition repositoryIf.ipp:738
void TempBufferType
Definition repositoryIf.ipp:742
RtcVector< ElementType > DataPointType
Definition repositoryIf.ipp:740
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:744
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:764
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:756
std::remove_cv_t< T > ElementType
Definition repositoryIf.ipp:739
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:423
RtcVector< ElementType > DataPointType
Definition repositoryIf.ipp:403
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:427
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:402
boost::container::vector< T, A > BufferType
Definition repositoryIf.ipp:401
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:407
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:419
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:790
RtcString DataPointType
Definition repositoryIf.ipp:778
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:786
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:794
char[N] BufferType
Definition repositoryIf.ipp:776
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:782
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:461
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:445
gsl::span< T, N > BufferType
Definition repositoryIf.ipp:439
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:440
RtcVector< ElementType > DataPointType
Definition repositoryIf.ipp:441
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:465
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:457
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:478
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:491
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:487
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:495
gsl::span< char, N > BufferType
Definition repositoryIf.ipp:477
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:483
std::array< T, N > BufferType
Definition repositoryIf.ipp:626
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:652
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:648
RtcVector< ElementType > DataPointType
Definition repositoryIf.ipp:628
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:644
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:632
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:627
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:670
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:682
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:678
std::array< char, N > BufferType
Definition repositoryIf.ipp:664
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:665
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:674
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:711
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:700
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:723
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:717
std::array< std::array< T, M >, N > BufferType
Definition repositoryIf.ipp:694
std::string BufferType
Definition repositoryIf.ipp:252
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:258
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:262
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:270
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:266
RtcString DataPointType
Definition repositoryIf.ipp:254
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:253
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:288
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:301
static gsl::span< ElementType > MakeSpan(BufferType &buffer)=delete
It is not possible to create mutable span from a read-only string view.
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:297
std::string_view BufferType
Definition repositoryIf.ipp:282
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:283
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:314
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:319
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Definition repositoryIf.ipp:331
RtcVector< ElementType > DataPointType
Definition repositoryIf.ipp:315
std::vector< T, A > BufferType
Definition repositoryIf.ipp:313
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Definition repositoryIf.ipp:335
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:339
static gsl::span< ElementType > MakeSpan(BufferType &buffer)=delete
Span not constructable from a std::vector<bool> type.
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)=delete
Span not constructable from a std::vector<bool> type.
boost::container::vector< bool > TempBufferType
Definition repositoryIf.ipp:355
static void CopyFromTempBuffer(BufferType &buffer, const std::shared_ptr< TempBufferType > &temp_buffer, size_t offset, size_t count)
Definition repositoryIf.ipp:389
std::remove_cv_t< typename BufferType::value_type > ElementType
Definition repositoryIf.ipp:352
std::vector< bool, A > BufferType
Definition repositoryIf.ipp:351
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Definition repositoryIf.ipp:357
static void CopyToTempBuffer(const BufferType &buffer, std::shared_ptr< TempBufferType > &temp_buffer, size_t offset, size_t count)
Definition repositoryIf.ipp:380
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Definition repositoryIf.ipp:371
void TempBufferType
Defines the temporary buffer type (set to void if USES_TEMP_BUFFER is false).
Definition repositoryIf.ipp:153
static const bool USES_TEMP_BUFFER
Flag indicating if a temporary buffer is required to read/write this type.
Definition repositoryIf.ipp:150
static void CopyToTempBuffer(const BufferType &buffer, std::shared_ptr< TempBufferType > &temp_buffer, size_t offset, size_t count)=delete
Copy data from the original buffer into the temporary buffer.
static gsl::span< const ElementType > MakeSpan(const BufferType &buffer)
Creates a span from a read-only buffer object.
Definition repositoryIf.ipp:187
std::remove_cv_t< T > ElementType
Defines the element type of the buffer object.
Definition repositoryIf.ipp:144
T DataPointType
Defines the corresponding data point type that type T is compatible with.
Definition repositoryIf.ipp:147
static gsl::span< ElementType > MakeSpan(BufferType &buffer)
Creates a span from a buffer object.
Definition repositoryIf.ipp:178
static RtcVectorUInt64 GetShape(const BufferType &buffer)
Returns the shape of a buffer object.
Definition repositoryIf.ipp:162
T BufferType
Defines the type of the buffer object that handles type T.
Definition repositoryIf.ipp:141
static bool ResizeBuffer(BufferType &buffer, const RtcVectorUInt64 &shape)
Tries to resize the buffer to the given shape.
Definition repositoryIf.ipp:204
static void CopyFromTempBuffer(BufferType &buffer, const std::shared_ptr< TempBufferType > &temp_buffer, size_t offset, size_t count)=delete
Copy data from the temporary buffer into the original buffer.
DataPointPath path
Definition repositoryIf.ipp:113
RepositoryIf::MetaData metadata
Definition repositoryIf.ipp:114
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:115
RepositoryIf::MetaData metadata
Definition repositoryIf.ipp:81
DataPointPath path
Definition repositoryIf.ipp:79
gsl::span< const T > data
Definition repositoryIf.ipp:80
T ElementType
Definition repositoryIf.ipp:78
RepositoryIf::CallbackType callback
Definition repositoryIf.ipp:82
Provides useful mechanisms to test various type traits.