Rerun C++ SDK
Loading...
Searching...
No Matches
collection_adapter_builtins.hpp
1#pragma once
2
3#include "collection.hpp"
4#include "collection_adapter.hpp"
5#include "type_traits.hpp"
6
7#include <array>
8#include <vector>
9
10// Documenting the builtin adapters is too much clutter for the doc class overview.
11/// \cond private
12
13namespace rerun {
14 /// Adapter from `std::vector` of elements with the target type.
15 ///
16 /// Only takes ownership if a temporary is passed.
17 /// No allocation or copy is performed in any case. Furthermore, elements are not moved.
18 template <typename TElement>
19 struct CollectionAdapter<TElement, std::vector<TElement>> {
20 Collection<TElement> operator()(const std::vector<TElement>& input) {
21 return Collection<TElement>::borrow(input.data(), input.size());
22 }
23
24 Collection<TElement> operator()(std::vector<TElement>&& input) {
25 return Collection<TElement>::take_ownership(std::move(input));
26 }
27 };
28
29 /// Adapter for a iterable container (see `rerun::traits::is_iterable_v`) which
30 /// has a value type from which `TElement` can be constructed but is not equal to `TElement`.
31 ///
32 /// Since this needs to do a conversion, this will always need to allocate space.
33 /// However, if a temporary is passed, elements will be moved instead of copied upon construction of `TElement`.
34 template <typename TElement, typename TContainer>
35 struct CollectionAdapter<
36 TElement, TContainer,
37 std::enable_if_t<
38 !std::is_same_v<TElement, traits::value_type_of_t<TContainer>> && //
39 traits::is_iterable_v<TContainer> && //
40 std::is_constructible_v<
41 TElement,
42 traits::value_type_of_t<TContainer>> //
43 >> {
44 Collection<TElement> operator()(const TContainer& input) {
45 std::vector<TElement> elements(std::begin(input), std::end(input));
46 return Collection<TElement>::take_ownership(std::move(elements));
47 }
48
49 Collection<TElement> operator()(TContainer&& input) {
50 std::vector<TElement> elements;
51 // There's no batch emplace method, so we need to reserve and then emplace manually.
52 // We decide here to take the performance cost if a the input's iterator is not a random access iterator.
53 // (in that case determining the size will have linear complexity)
54 elements.reserve(static_cast<size_t>(std::distance(std::begin(input), std::end(input)))
55 );
56 for (auto& element : input) {
57 elements.emplace_back(std::move(element));
58 }
59
60 return Collection<TElement>::take_ownership(std::move(elements));
61 }
62 };
63
64 /// Adapter from std::array of elements with the target type.
65 ///
66 /// Only takes ownership if a temporary is passed in which case an allocation and per element move is performed.
67 template <typename TElement, size_t NumInstances>
68 struct CollectionAdapter<TElement, std::array<TElement, NumInstances>> {
69 Collection<TElement> operator()(const std::array<TElement, NumInstances>& array) {
70 return Collection<TElement>::borrow(array.data(), NumInstances);
71 }
72
73 Collection<TElement> operator()(std::array<TElement, NumInstances>&& array) {
74 std::vector<TElement> elements(
75 std::make_move_iterator(array.begin()),
76 std::make_move_iterator(array.end())
77 );
78 return Collection<TElement>::take_ownership(std::move(elements));
79 }
80 };
81
82 /// Adapter from a C-Array reference with the target type.
83 ///
84 /// Only takes ownership if a temporary is passed in which case an allocation and per element move is performed.
85 template <typename TElement, size_t NumInstances>
86 struct CollectionAdapter<TElement, TElement[NumInstances]> {
87 Collection<TElement> operator()(const TElement (&array)[NumInstances]) {
88 return Collection<TElement>::borrow(array, NumInstances);
89 }
90
91 Collection<TElement> operator()(TElement (&&array)[NumInstances]) {
92 std::vector<TElement> elements(
93 std::make_move_iterator(array),
94 std::make_move_iterator(array + NumInstances)
95 );
96 return Collection<TElement>::take_ownership(std::move(elements));
97 }
98 };
99
100 /// Adapter for a single element from which `TElement`, temporary or reference.
101 ///
102 /// Only takes ownership if a temporary is passed in which case the element is moved.
103 /// Otherwise a borrow takes place.
104 template <typename TElement>
105 struct CollectionAdapter<TElement, TElement> {
106 Collection<TElement> operator()(const TElement& one_and_only) {
107 return Collection<TElement>::borrow(&one_and_only, 1);
108 }
109
110 Collection<TElement> operator()(TElement&& one_and_only) {
111 return Collection<TElement>::take_ownership(std::move(one_and_only));
112 }
113 };
114
115 /// Adapter for a single element of from which `TElement` can be constructed.
116 ///
117 /// Since this needs to do a conversion, this will always need to allocate space.
118 /// However, if a temporary is passed the element will be moved instead of copied upon construction of `TElement`.
119 template <typename TElement, typename TInput>
120 struct CollectionAdapter<
121 TElement, TInput,
122 std::enable_if_t<
123 !std::is_same_v<TElement, TInput> && //
124 !traits::is_iterable_v<TInput> && //
125 std::is_constructible_v<TElement, TInput> //
126 >> {
127 Collection<TElement> operator()(const TInput& input) {
128 return Collection<TElement>::take_ownership(TElement(input));
129 }
130
131 Collection<TElement> operator()(TInput&& input) {
132 return Collection<TElement>::take_ownership(TElement(std::move(input)));
133 }
134 };
135
136} // namespace rerun
137
138/// \endcond
static Collection< TElement > borrow(const T *data, size_t num_instances=1)
Borrows binary compatible data into the collection from a typed pointer.
Definition collection.hpp:154
static Collection< TElement > take_ownership(std::vector< TElement > &&data)
Takes ownership of a temporary std::vector, moving it into the collection.
Definition collection.hpp:200
All Rerun C++ types and functions are in the rerun namespace or one of its nested namespaces.
Definition rerun.hpp:22