C/C++ API Reference
Loading...
Searching...
No Matches
var_len_entry.h
1// Copyright 2025 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include "pw_preprocessor/util.h"
17
18#ifndef __cplusplus
19
20#include <stddef.h>
21#include <stdint.h>
22
23#else // __cplusplus
24
25#include <cstddef>
26#include <cstdint>
27#include <type_traits>
28#include <utility>
29
30#include "pw_assert/assert.h"
31#include "pw_bytes/span.h"
33#include "pw_containers/internal/var_len_entry_iterator.h"
34#include "pw_containers/internal/wrap.h"
35#include "pw_span/span.h"
36#include "pw_varint/varint.h"
37
38#endif // __cplusplus
39
40// Forward declarations of C structs.
44
45#ifdef __cplusplus
46namespace pw::containers::internal {
47
52template <typename T>
53constexpr uint32_t ReadVarLenEntryEncodedSize(span<T> bytes, size_t offset);
54
59template <typename T>
60constexpr std::pair<uint32_t, uint32_t> ReadVarLenEntrySize(span<T> bytes,
61 size_t offset);
62
64template <typename T>
66 public:
67 using element_type = T;
68 using value_type = std::remove_cv_t<T>;
69 using size_type = uint32_t;
70 using pointer = T*;
71 using const_pointer = const T*;
72 using reference = T&;
73 using const_reference = const T&;
74
79
80 constexpr VarLenEntry() = default;
81 constexpr VarLenEntry(const VarLenEntry&) = default;
82 constexpr VarLenEntry& operator=(const VarLenEntry&) = default;
83
84 constexpr operator VarLenEntry<const T>() const {
85 return VarLenEntry<const T>(data1_, data2_);
86 }
87
88 [[nodiscard]] constexpr bool empty() const {
89 return data1_.empty() && data2_.empty();
90 }
91
92 constexpr size_t size() const { return data1_.size() + data2_.size(); }
93
97 constexpr reference at(size_t index) const;
98
99 constexpr reference operator[](size_t index) const { return at(index); }
100 constexpr reference front() const { return at(0); }
101 constexpr reference back() const { return at(size() - 1); }
102
106 constexpr std::pair<span<T>, span<T>> contiguous_data() const {
107 return std::make_pair(data1_, data2_);
108 }
109
119 constexpr size_t copy(value_type* dest, size_t count) const;
120
121 constexpr iterator begin() const { return iterator(*this, 0); }
122 constexpr const_iterator cbegin() const { return const_iterator(*this, 0); }
123
124 constexpr iterator end() const { return iterator(*this, size()); }
125 constexpr const_iterator cend() const {
126 return const_iterator(*this, size());
127 }
128
129 [[nodiscard]] friend constexpr bool operator==(const VarLenEntry& lhs,
130 const VarLenEntry& rhs) {
131 return lhs.Equals(rhs);
132 }
133 [[nodiscard]] friend constexpr bool operator!=(const VarLenEntry& lhs,
134 const VarLenEntry& rhs) {
135 return !(lhs == rhs);
136 }
137
138 private:
139 template <typename>
140 friend class VarLenEntry;
141
142 friend class VarLenEntryC;
143
144 template <typename>
145 friend class VarLenEntryQueueIterator;
146
147 constexpr VarLenEntry(span<T> data1, span<T> data2)
148 : data1_(data1), data2_(data2) {}
149
151 [[nodiscard]] constexpr bool Equals(const VarLenEntry& other) const;
152
154 span<T> data1_;
155 span<T> data2_;
156};
157
159// Template method implementations.
160
161template <typename T>
162constexpr uint32_t ReadVarLenEntryEncodedSize(span<T> bytes, size_t offset) {
163 std::pair<uint32_t, uint32_t> entry_size = ReadVarLenEntrySize(bytes, offset);
164 return entry_size.first + entry_size.second;
165}
166
167template <typename T>
168constexpr std::pair<uint32_t, uint32_t> ReadVarLenEntrySize(span<T> bytes,
169 size_t offset) {
170 uint32_t prefix_size = 0;
171 uint32_t data_size = 0;
172 while (true) {
173 PW_DASSERT(prefix_size < varint::kMaxVarint32SizeBytes);
175 std::byte(bytes[offset]), prefix_size++, &data_size)) {
176 return std::make_pair(prefix_size, data_size);
177 }
178 IncrementWithWrap(offset, size_t(1), bytes.size());
179 }
180}
181
182template <typename T>
183constexpr size_t VarLenEntry<T>::copy(value_type* dest, size_t count) const {
184 using difference_type = typename span<T>::difference_type;
185 size_t size1 = std::min(count, data1_.size());
186 auto end = data1_.begin() + static_cast<difference_type>(size1);
187 pw::copy(data1_.begin(), end, dest);
188 dest = &dest[size1];
189 count -= size1;
190 size_t size2 = std::min(count, data2_.size());
191 if (size2 != 0) {
192 end = data2_.begin() + static_cast<difference_type>(size2);
193 pw::copy(data2_.begin(), end, dest);
194 }
195 return data1_.size() + data2_.size();
196}
197
198template <typename T>
199constexpr T& VarLenEntry<T>::at(size_t index) const {
200 if (index < data1_.size()) {
201 return data1_[index];
202 }
203 index -= data1_.size();
204 PW_ASSERT(index < data2_.size());
205 return data2_[index];
206}
207
208template <typename T>
209constexpr bool VarLenEntry<T>::Equals(const VarLenEntry& other) const {
210 return data1_.data() == other.data1_.data() &&
211 data1_.size() == other.data1_.size() &&
212 data2_.data() == other.data2_.data() &&
213 data2_.size() == other.data2_.size();
214}
215
217// Helper class with methods to convert between the C++ object and C structs.
219 public:
220 static VarLenEntry<std::byte> From(
225 const VarLenEntry<std::byte>& cxx_entry);
227 const VarLenEntry<const std::byte>& cxx_entry);
228};
229
230} // namespace pw::containers::internal
231#endif // __cplusplus
232
234// C API.
235
236PW_EXTERN_C_START
237
239 uint8_t* data_1;
240 uint32_t size_1;
241 uint8_t* data_2;
242 uint32_t size_2;
243};
244
246 const uint8_t* data_1;
247 uint32_t size_1;
248 const uint8_t* data_2;
249 uint32_t size_2;
250};
251
253uint32_t pw_InlineVarLenEntryQueue_Entry_Copy(
254 const pw_InlineVarLenEntryQueue_Entry* entry, void* dest, uint32_t count);
255uint32_t pw_InlineVarLenEntryQueue_ConstEntry_Copy(
257 void* dest,
258 uint32_t count);
259
261uint8_t pw_InlineVarLenEntryQueue_Entry_At(
262 const pw_InlineVarLenEntryQueue_Entry* entry, size_t index);
263uint8_t pw_InlineVarLenEntryQueue_ConstEntry_At(
264 const pw_InlineVarLenEntryQueue_ConstEntry* entry, size_t index);
265
266PW_EXTERN_C_END
Definition: var_len_entry.h:218
Refers to an entry in-place in the queue. Entries may be discontiguous.
Definition: var_len_entry.h:65
constexpr reference at(size_t index) const
Definition: var_len_entry.h:199
VarLenEntryIterator< T > iterator
Definition: var_len_entry.h:77
constexpr size_t copy(value_type *dest, size_t count) const
Definition: var_len_entry.h:183
constexpr std::pair< span< T >, span< T > > contiguous_data() const
Definition: var_len_entry.h:106
Definition: var_len_entry_iterator.h:30
Definition: span_impl.h:235
constexpr OutputIt copy(InputIt first, InputIt last, OutputIt d_first)
constexpr backport of <algorithm>'s std::copy for C++17.
Definition: algorithm.h:355
constexpr size_t kMaxVarint32SizeBytes
Maximum size of a varint (LEB128) encoded uint32_t.
Definition: varint.h:74
constexpr bool DecodeOneByte(std::byte encoded, size_t count, T *out_value)
Definition: varint.h:396
Definition: var_len_entry.h:245
Definition: var_len_entry.h:238