WPILibC++ 2027.0.0-alpha-3
Loading...
Searching...
No Matches
array.h
Go to the documentation of this file.
1// Protocol Buffers - Google's data interchange format
2// Copyright 2023 Google LLC. All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
7
8#ifndef UPB_MESSAGE_INTERNAL_ARRAY_H_
9#define UPB_MESSAGE_INTERNAL_ARRAY_H_
10
11#include <stdint.h>
12#include <string.h>
13
14#include "upb/mem/arena.h"
15
16// Must be last.
17#include "upb/port/def.inc"
18
19#define _UPB_ARRAY_MASK_IMM 0x4 // Frozen/immutable bit.
20#define _UPB_ARRAY_MASK_LG2 0x3 // Encoded elem size.
21#define _UPB_ARRAY_MASK_ALL (_UPB_ARRAY_MASK_IMM | _UPB_ARRAY_MASK_LG2)
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27// LINT.IfChange(upb_Array)
28
29// Our internal representation for repeated fields.
30struct upb_Array {
31 // This is a tagged pointer. Bits #0 and #1 encode the elem size as follows:
32 // 0 maps to elem size 1
33 // 1 maps to elem size 4
34 // 2 maps to elem size 8
35 // 3 maps to elem size 16
36 //
37 // Bit #2 contains the frozen/immutable flag.
38 uintptr_t UPB_ONLYBITS(data);
39
40 size_t UPB_ONLYBITS(size); // The number of elements in the array.
41 size_t UPB_PRIVATE(capacity); // Allocated storage. Measured in elements.
42};
43
45 arr->UPB_ONLYBITS(data) |= _UPB_ARRAY_MASK_IMM;
46}
47
49 return (arr->UPB_ONLYBITS(data) & _UPB_ARRAY_MASK_IMM) != 0;
50}
51
53 void* data, size_t lg2) {
54 UPB_ASSERT(lg2 != 1);
55 UPB_ASSERT(lg2 <= 4);
56 const size_t bits = lg2 - (lg2 != 0);
57 array->UPB_ONLYBITS(data) = (uintptr_t)data | bits;
58}
59
60UPB_INLINE size_t
62 const size_t bits = array->UPB_ONLYBITS(data) & _UPB_ARRAY_MASK_LG2;
63 const size_t lg2 = bits + (bits != 0);
64 return lg2;
65}
66
67UPB_API_INLINE const void* upb_Array_DataPtr(const struct upb_Array* array) {
68 UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); // Check assertions.
69 return (void*)(array->UPB_ONLYBITS(data) & ~(uintptr_t)_UPB_ARRAY_MASK_ALL);
70}
71
73 return (void*)upb_Array_DataPtr(array);
74}
75
77 upb_Arena* arena, size_t init_capacity, int elem_size_lg2,
78 bool allow_slow) {
79 UPB_ASSERT(elem_size_lg2 != 1);
80 UPB_ASSERT(elem_size_lg2 <= 4);
81 const size_t array_size =
83 const size_t bytes = array_size + (init_capacity << elem_size_lg2);
85 if (!allow_slow && UPB_PRIVATE(_upb_ArenaHas)(arena) < span) return NULL;
86 struct upb_Array* array = (struct upb_Array*)upb_Arena_Malloc(arena, bytes);
87 if (!array) return NULL;
89 (array, UPB_PTR_AT(array, array_size, void), elem_size_lg2);
90 array->UPB_ONLYBITS(size) = 0;
91 array->UPB_PRIVATE(capacity) = init_capacity;
92 return array;
93}
94
96 size_t init_capacity,
97 int elem_size_lg2) {
98 return UPB_PRIVATE(_upb_Array_NewMaybeAllowSlow)(arena, init_capacity,
99 elem_size_lg2, true);
100}
101
103 upb_Arena* arena, size_t init_capacity, int elem_size_lg2) {
104 return UPB_PRIVATE(_upb_Array_NewMaybeAllowSlow)(arena, init_capacity,
105 elem_size_lg2, false);
106}
107
108// Resizes the capacity of the array to be at least min_size.
109bool UPB_PRIVATE(_upb_Array_Realloc)(struct upb_Array* array, size_t min_size,
110 upb_Arena* arena);
111
114 size_t capacity, int elem_size_lg2,
115 upb_Arena* arena) {
116 size_t old_bytes = array->UPB_PRIVATE(capacity) << elem_size_lg2;
117 size_t new_bytes = capacity << elem_size_lg2;
118 UPB_ASSUME(new_bytes > old_bytes);
119 if (!upb_Arena_TryExtend(arena, array, old_bytes, new_bytes)) return false;
120 array->UPB_PRIVATE(capacity) = capacity;
121 return true;
122}
123
124UPB_API_INLINE bool upb_Array_Reserve(struct upb_Array* array, size_t size,
125 upb_Arena* arena) {
127 if (array->UPB_PRIVATE(capacity) < size)
128 return UPB_PRIVATE(_upb_Array_Realloc)(array, size, arena);
129 return true;
130}
131
132// Resize without initializing new elements.
134 struct upb_Array* array, size_t size, upb_Arena* arena) {
136 UPB_ASSERT(size <= array->UPB_ONLYBITS(size) ||
137 arena); // Allow NULL arena when shrinking.
138 if (!upb_Array_Reserve(array, size, arena)) return false;
139 array->UPB_ONLYBITS(size) = size;
140 return true;
141}
142
143// This function is intended for situations where elem_size is compile-time
144// constant or a known expression of the form (1 << lg2), so that the expression
145// i*elem_size does not result in an actual multiplication.
146UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(struct upb_Array* array, size_t i,
147 const void* data,
148 size_t elem_size) {
150 UPB_ASSERT(i < array->UPB_ONLYBITS(size));
151 UPB_ASSERT(elem_size == 1U << UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array));
152 char* arr_data = (char*)upb_Array_MutableDataPtr(array);
153 memcpy(arr_data + (i * elem_size), data, elem_size);
154}
155
156UPB_API_INLINE size_t upb_Array_Size(const struct upb_Array* arr) {
157 return arr->UPB_ONLYBITS(size);
158}
159
160UPB_API_INLINE size_t upb_Array_Capacity(const struct upb_Array* arr) {
161 return arr->UPB_PRIVATE(capacity);
162}
163
164// LINT.ThenChange(GoogleInternalName0)
165
166#ifdef __cplusplus
167} /* extern "C" */
168#endif
169
170#undef _UPB_ARRAY_MASK_IMM
171#undef _UPB_ARRAY_MASK_LG2
172#undef _UPB_ARRAY_MASK_ALL
173
174#include "upb/port/undef.inc"
175
176#endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */
#define UPB_API_INLINE
Definition def.inc:163
#define UPB_ALIGN_UP(size, align)
Definition def.inc:205
#define UPB_PTR_AT(msg, ofs, type)
Definition def.inc:118
#define UPB_ASSUME(expr)
Definition def.inc:319
#define UPB_ASSERT(expr)
Definition def.inc:329
#define UPB_PRIVATE(x)
Definition def.inc:393
#define UPB_FORCEINLINE
Definition def.inc:288
#define UPB_MALLOC_ALIGN
Definition def.inc:184
#define UPB_INLINE
Definition def.inc:144
#define UPB_ONLYBITS(x)
Definition def.inc:398
UPB_INLINE size_t UPB_PRIVATE _upb_ArenaHas(const struct upb_Arena *a)
Definition arena.h:46
UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena *a, void *ptr, size_t oldsize, size_t size)
Definition arena.h:106
UPB_INLINE size_t UPB_PRIVATE _upb_Arena_AllocSpan(size_t size)
Definition arena.h:50
UPB_API_INLINE void * upb_Arena_Malloc(struct upb_Arena *a, size_t size)
Definition arena.h:65
Definition format.h:4001
Definition arena.h:29
Definition array.h:30
uintptr_t UPB_ONLYBITS(data)
size_t UPB_ONLYBITS(size)
size_t UPB_PRIVATE(capacity)
UPB_API_INLINE size_t upb_Array_Capacity(const upb_Array *arr)
UPB_API_INLINE bool upb_Array_IsFrozen(const upb_Array *arr)
UPB_API_INLINE const void * upb_Array_DataPtr(const upb_Array *arr)
UPB_API_INLINE void * upb_Array_MutableDataPtr(upb_Array *arr)
Definition array.h:72
UPB_API_INLINE size_t upb_Array_Size(const upb_Array *arr)
UPB_API_INLINE bool upb_Array_Reserve(struct upb_Array *array, size_t size, upb_Arena *arena)
Definition array.h:124
UPB_INLINE struct upb_Array *UPB_PRIVATE _upb_Array_New(upb_Arena *arena, size_t init_capacity, int elem_size_lg2)
Definition array.h:95
#define _UPB_ARRAY_MASK_IMM
Definition array.h:19
#define _UPB_ARRAY_MASK_LG2
Definition array.h:20
UPB_INLINE void UPB_PRIVATE _upb_Array_SetTaggedPtr(struct upb_Array *array, void *data, size_t lg2)
Definition array.h:52
UPB_INLINE struct upb_Array *UPB_PRIVATE _upb_Array_TryFastNew(upb_Arena *arena, size_t init_capacity, int elem_size_lg2)
Definition array.h:102
bool UPB_PRIVATE _upb_Array_Realloc(struct upb_Array *array, size_t min_size, upb_Arena *arena)
UPB_INLINE size_t UPB_PRIVATE _upb_Array_ElemSizeLg2(const struct upb_Array *array)
Definition array.h:61
UPB_INLINE bool UPB_PRIVATE _upb_Array_ResizeUninitialized(struct upb_Array *array, size_t size, upb_Arena *arena)
Definition array.h:133
UPB_INLINE void UPB_PRIVATE _upb_Array_ShallowFreeze(struct upb_Array *arr)
Definition array.h:44
UPB_INLINE void UPB_PRIVATE _upb_Array_Set(struct upb_Array *array, size_t i, const void *data, size_t elem_size)
Definition array.h:146
UPB_FORCEINLINE bool UPB_PRIVATE _upb_Array_TryFastRealloc(struct upb_Array *array, size_t capacity, int elem_size_lg2, upb_Arena *arena)
Definition array.h:113
UPB_INLINE struct upb_Array *UPB_PRIVATE _upb_Array_NewMaybeAllowSlow(upb_Arena *arena, size_t init_capacity, int elem_size_lg2, bool allow_slow)
Definition array.h:76
#define _UPB_ARRAY_MASK_ALL
Definition array.h:21