cannam@62
|
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
|
cannam@62
|
2 // Licensed under the MIT License:
|
cannam@62
|
3 //
|
cannam@62
|
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
cannam@62
|
5 // of this software and associated documentation files (the "Software"), to deal
|
cannam@62
|
6 // in the Software without restriction, including without limitation the rights
|
cannam@62
|
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
cannam@62
|
8 // copies of the Software, and to permit persons to whom the Software is
|
cannam@62
|
9 // furnished to do so, subject to the following conditions:
|
cannam@62
|
10 //
|
cannam@62
|
11 // The above copyright notice and this permission notice shall be included in
|
cannam@62
|
12 // all copies or substantial portions of the Software.
|
cannam@62
|
13 //
|
cannam@62
|
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
cannam@62
|
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
cannam@62
|
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
cannam@62
|
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
cannam@62
|
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
cannam@62
|
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
cannam@62
|
20 // THE SOFTWARE.
|
cannam@62
|
21
|
cannam@62
|
22 // This file contains types which are intended to help detect incorrect usage at compile
|
cannam@62
|
23 // time, but should then be optimized down to basic primitives (usually, integers) by the
|
cannam@62
|
24 // compiler.
|
cannam@62
|
25
|
cannam@62
|
26 #ifndef CAPNP_COMMON_H_
|
cannam@62
|
27 #define CAPNP_COMMON_H_
|
cannam@62
|
28
|
cannam@62
|
29 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
|
cannam@62
|
30 #pragma GCC system_header
|
cannam@62
|
31 #endif
|
cannam@62
|
32
|
cannam@62
|
33 #include <inttypes.h>
|
cannam@62
|
34 #include <kj/string.h>
|
cannam@62
|
35 #include <kj/memory.h>
|
cannam@62
|
36
|
cannam@62
|
37 #if CAPNP_DEBUG_TYPES
|
cannam@62
|
38 #include <kj/units.h>
|
cannam@62
|
39 #endif
|
cannam@62
|
40
|
cannam@62
|
41 namespace capnp {
|
cannam@62
|
42
|
cannam@62
|
43 #define CAPNP_VERSION_MAJOR 0
|
cannam@62
|
44 #define CAPNP_VERSION_MINOR 6
|
cannam@62
|
45 #define CAPNP_VERSION_MICRO 0
|
cannam@62
|
46
|
cannam@62
|
47 #define CAPNP_VERSION \
|
cannam@62
|
48 (CAPNP_VERSION_MAJOR * 1000000 + CAPNP_VERSION_MINOR * 1000 + CAPNP_VERSION_MICRO)
|
cannam@62
|
49
|
cannam@62
|
50 #ifndef CAPNP_LITE
|
cannam@62
|
51 #define CAPNP_LITE 0
|
cannam@62
|
52 #endif
|
cannam@62
|
53
|
cannam@62
|
54 typedef unsigned int uint;
|
cannam@62
|
55
|
cannam@62
|
56 struct Void {
|
cannam@62
|
57 // Type used for Void fields. Using C++'s "void" type creates a bunch of issues since it behaves
|
cannam@62
|
58 // differently from other types.
|
cannam@62
|
59
|
cannam@62
|
60 inline constexpr bool operator==(Void other) const { return true; }
|
cannam@62
|
61 inline constexpr bool operator!=(Void other) const { return false; }
|
cannam@62
|
62 };
|
cannam@62
|
63
|
cannam@62
|
64 static constexpr Void VOID = Void();
|
cannam@62
|
65 // Constant value for `Void`, which is an empty struct.
|
cannam@62
|
66
|
cannam@62
|
67 inline kj::StringPtr KJ_STRINGIFY(Void) { return "void"; }
|
cannam@62
|
68
|
cannam@62
|
69 struct Text;
|
cannam@62
|
70 struct Data;
|
cannam@62
|
71
|
cannam@62
|
72 enum class Kind: uint8_t {
|
cannam@62
|
73 PRIMITIVE,
|
cannam@62
|
74 BLOB,
|
cannam@62
|
75 ENUM,
|
cannam@62
|
76 STRUCT,
|
cannam@62
|
77 UNION,
|
cannam@62
|
78 INTERFACE,
|
cannam@62
|
79 LIST,
|
cannam@62
|
80
|
cannam@62
|
81 OTHER
|
cannam@62
|
82 // Some other type which is often a type parameter to Cap'n Proto templates, but which needs
|
cannam@62
|
83 // special handling. This includes types like AnyPointer, Dynamic*, etc.
|
cannam@62
|
84 };
|
cannam@62
|
85
|
cannam@62
|
86 enum class Style: uint8_t {
|
cannam@62
|
87 PRIMITIVE,
|
cannam@62
|
88 POINTER, // other than struct
|
cannam@62
|
89 STRUCT,
|
cannam@62
|
90 CAPABILITY
|
cannam@62
|
91 };
|
cannam@62
|
92
|
cannam@62
|
93 enum class ElementSize: uint8_t {
|
cannam@62
|
94 // Size of a list element.
|
cannam@62
|
95
|
cannam@62
|
96 VOID = 0,
|
cannam@62
|
97 BIT = 1,
|
cannam@62
|
98 BYTE = 2,
|
cannam@62
|
99 TWO_BYTES = 3,
|
cannam@62
|
100 FOUR_BYTES = 4,
|
cannam@62
|
101 EIGHT_BYTES = 5,
|
cannam@62
|
102
|
cannam@62
|
103 POINTER = 6,
|
cannam@62
|
104
|
cannam@62
|
105 INLINE_COMPOSITE = 7
|
cannam@62
|
106 };
|
cannam@62
|
107
|
cannam@62
|
108 enum class PointerType {
|
cannam@62
|
109 // Various wire types a pointer field can take
|
cannam@62
|
110
|
cannam@62
|
111 NULL_,
|
cannam@62
|
112 // Should be NULL, but that's #defined in stddef.h
|
cannam@62
|
113
|
cannam@62
|
114 STRUCT,
|
cannam@62
|
115 LIST,
|
cannam@62
|
116 CAPABILITY
|
cannam@62
|
117 };
|
cannam@62
|
118
|
cannam@62
|
119 namespace schemas {
|
cannam@62
|
120
|
cannam@62
|
121 template <typename T>
|
cannam@62
|
122 struct EnumInfo;
|
cannam@62
|
123
|
cannam@62
|
124 } // namespace schemas
|
cannam@62
|
125
|
cannam@62
|
126 namespace _ { // private
|
cannam@62
|
127
|
cannam@62
|
128 template <typename T, typename = void> struct Kind_;
|
cannam@62
|
129
|
cannam@62
|
130 template <> struct Kind_<Void> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
131 template <> struct Kind_<bool> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
132 template <> struct Kind_<int8_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
133 template <> struct Kind_<int16_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
134 template <> struct Kind_<int32_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
135 template <> struct Kind_<int64_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
136 template <> struct Kind_<uint8_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
137 template <> struct Kind_<uint16_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
138 template <> struct Kind_<uint32_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
139 template <> struct Kind_<uint64_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
140 template <> struct Kind_<float> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
141 template <> struct Kind_<double> { static constexpr Kind kind = Kind::PRIMITIVE; };
|
cannam@62
|
142 template <> struct Kind_<Text> { static constexpr Kind kind = Kind::BLOB; };
|
cannam@62
|
143 template <> struct Kind_<Data> { static constexpr Kind kind = Kind::BLOB; };
|
cannam@62
|
144
|
cannam@62
|
145 template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsStruct>> {
|
cannam@62
|
146 static constexpr Kind kind = Kind::STRUCT;
|
cannam@62
|
147 };
|
cannam@62
|
148 template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsInterface>> {
|
cannam@62
|
149 static constexpr Kind kind = Kind::INTERFACE;
|
cannam@62
|
150 };
|
cannam@62
|
151 template <typename T> struct Kind_<T, kj::VoidSfinae<typename schemas::EnumInfo<T>::IsEnum>> {
|
cannam@62
|
152 static constexpr Kind kind = Kind::ENUM;
|
cannam@62
|
153 };
|
cannam@62
|
154
|
cannam@62
|
155 } // namespace _ (private)
|
cannam@62
|
156
|
cannam@62
|
157 template <typename T, Kind k = _::Kind_<T>::kind>
|
cannam@62
|
158 inline constexpr Kind kind() {
|
cannam@62
|
159 // This overload of kind() matches types which have a Kind_ specialization.
|
cannam@62
|
160
|
cannam@62
|
161 return k;
|
cannam@62
|
162 }
|
cannam@62
|
163
|
cannam@62
|
164 #if CAPNP_LITE
|
cannam@62
|
165
|
cannam@62
|
166 #define CAPNP_KIND(T) ::capnp::_::Kind_<T>::kind
|
cannam@62
|
167 // Avoid constexpr methods in lite mode (MSVC is bad at constexpr).
|
cannam@62
|
168
|
cannam@62
|
169 #else // CAPNP_LITE
|
cannam@62
|
170
|
cannam@62
|
171 #define CAPNP_KIND(T) ::capnp::kind<T>()
|
cannam@62
|
172 // Use this macro rather than kind<T>() in any code which must work in lite mode.
|
cannam@62
|
173
|
cannam@62
|
174 template <typename T, Kind k = kind<T>()>
|
cannam@62
|
175 inline constexpr Style style() {
|
cannam@62
|
176 return k == Kind::PRIMITIVE || k == Kind::ENUM ? Style::PRIMITIVE
|
cannam@62
|
177 : k == Kind::STRUCT ? Style::STRUCT
|
cannam@62
|
178 : k == Kind::INTERFACE ? Style::CAPABILITY : Style::POINTER;
|
cannam@62
|
179 }
|
cannam@62
|
180
|
cannam@62
|
181 #endif // CAPNP_LITE, else
|
cannam@62
|
182
|
cannam@62
|
183 template <typename T, Kind k = CAPNP_KIND(T)>
|
cannam@62
|
184 struct List;
|
cannam@62
|
185
|
cannam@62
|
186 #if _MSC_VER
|
cannam@62
|
187
|
cannam@62
|
188 template <typename T, Kind k>
|
cannam@62
|
189 struct List {};
|
cannam@62
|
190 // For some reason, without this declaration, MSVC will error out on some uses of List
|
cannam@62
|
191 // claiming that "T" -- as used in the default initializer for the second template param, "k" --
|
cannam@62
|
192 // is not defined. I do not understand this error, but adding this empty default declaration fixes
|
cannam@62
|
193 // it.
|
cannam@62
|
194
|
cannam@62
|
195 #endif
|
cannam@62
|
196
|
cannam@62
|
197 template <typename T> struct ListElementType_;
|
cannam@62
|
198 template <typename T> struct ListElementType_<List<T>> { typedef T Type; };
|
cannam@62
|
199 template <typename T> using ListElementType = typename ListElementType_<T>::Type;
|
cannam@62
|
200
|
cannam@62
|
201 namespace _ { // private
|
cannam@62
|
202 template <typename T, Kind k> struct Kind_<List<T, k>> {
|
cannam@62
|
203 static constexpr Kind kind = Kind::LIST;
|
cannam@62
|
204 };
|
cannam@62
|
205 } // namespace _ (private)
|
cannam@62
|
206
|
cannam@62
|
207 template <typename T, Kind k = CAPNP_KIND(T)> struct ReaderFor_ { typedef typename T::Reader Type; };
|
cannam@62
|
208 template <typename T> struct ReaderFor_<T, Kind::PRIMITIVE> { typedef T Type; };
|
cannam@62
|
209 template <typename T> struct ReaderFor_<T, Kind::ENUM> { typedef T Type; };
|
cannam@62
|
210 template <typename T> struct ReaderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
|
cannam@62
|
211 template <typename T> using ReaderFor = typename ReaderFor_<T>::Type;
|
cannam@62
|
212 // The type returned by List<T>::Reader::operator[].
|
cannam@62
|
213
|
cannam@62
|
214 template <typename T, Kind k = CAPNP_KIND(T)> struct BuilderFor_ { typedef typename T::Builder Type; };
|
cannam@62
|
215 template <typename T> struct BuilderFor_<T, Kind::PRIMITIVE> { typedef T Type; };
|
cannam@62
|
216 template <typename T> struct BuilderFor_<T, Kind::ENUM> { typedef T Type; };
|
cannam@62
|
217 template <typename T> struct BuilderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
|
cannam@62
|
218 template <typename T> using BuilderFor = typename BuilderFor_<T>::Type;
|
cannam@62
|
219 // The type returned by List<T>::Builder::operator[].
|
cannam@62
|
220
|
cannam@62
|
221 template <typename T, Kind k = CAPNP_KIND(T)> struct PipelineFor_ { typedef typename T::Pipeline Type;};
|
cannam@62
|
222 template <typename T> struct PipelineFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
|
cannam@62
|
223 template <typename T> using PipelineFor = typename PipelineFor_<T>::Type;
|
cannam@62
|
224
|
cannam@62
|
225 template <typename T, Kind k = CAPNP_KIND(T)> struct TypeIfEnum_;
|
cannam@62
|
226 template <typename T> struct TypeIfEnum_<T, Kind::ENUM> { typedef T Type; };
|
cannam@62
|
227
|
cannam@62
|
228 template <typename T>
|
cannam@62
|
229 using TypeIfEnum = typename TypeIfEnum_<kj::Decay<T>>::Type;
|
cannam@62
|
230
|
cannam@62
|
231 template <typename T>
|
cannam@62
|
232 using FromReader = typename kj::Decay<T>::Reads;
|
cannam@62
|
233 // FromReader<MyType::Reader> = MyType (for any Cap'n Proto type).
|
cannam@62
|
234
|
cannam@62
|
235 template <typename T>
|
cannam@62
|
236 using FromBuilder = typename kj::Decay<T>::Builds;
|
cannam@62
|
237 // FromBuilder<MyType::Builder> = MyType (for any Cap'n Proto type).
|
cannam@62
|
238
|
cannam@62
|
239 template <typename T>
|
cannam@62
|
240 using FromPipeline = typename kj::Decay<T>::Pipelines;
|
cannam@62
|
241 // FromBuilder<MyType::Pipeline> = MyType (for any Cap'n Proto type).
|
cannam@62
|
242
|
cannam@62
|
243 template <typename T>
|
cannam@62
|
244 using FromClient = typename kj::Decay<T>::Calls;
|
cannam@62
|
245 // FromReader<MyType::Client> = MyType (for any Cap'n Proto interface type).
|
cannam@62
|
246
|
cannam@62
|
247 template <typename T>
|
cannam@62
|
248 using FromServer = typename kj::Decay<T>::Serves;
|
cannam@62
|
249 // FromBuilder<MyType::Server> = MyType (for any Cap'n Proto interface type).
|
cannam@62
|
250
|
cannam@62
|
251 template <typename T, typename = void>
|
cannam@62
|
252 struct FromAny_;
|
cannam@62
|
253
|
cannam@62
|
254 template <typename T>
|
cannam@62
|
255 struct FromAny_<T, kj::VoidSfinae<FromReader<T>>> {
|
cannam@62
|
256 using Type = FromReader<T>;
|
cannam@62
|
257 };
|
cannam@62
|
258
|
cannam@62
|
259 template <typename T>
|
cannam@62
|
260 struct FromAny_<T, kj::VoidSfinae<FromBuilder<T>>> {
|
cannam@62
|
261 using Type = FromBuilder<T>;
|
cannam@62
|
262 };
|
cannam@62
|
263
|
cannam@62
|
264 template <typename T>
|
cannam@62
|
265 struct FromAny_<T, kj::VoidSfinae<FromPipeline<T>>> {
|
cannam@62
|
266 using Type = FromPipeline<T>;
|
cannam@62
|
267 };
|
cannam@62
|
268
|
cannam@62
|
269 // Note that T::Client is covered by FromReader
|
cannam@62
|
270
|
cannam@62
|
271 template <typename T>
|
cannam@62
|
272 struct FromAny_<kj::Own<T>, kj::VoidSfinae<FromServer<T>>> {
|
cannam@62
|
273 using Type = FromServer<T>;
|
cannam@62
|
274 };
|
cannam@62
|
275
|
cannam@62
|
276 template <typename T>
|
cannam@62
|
277 struct FromAny_<T,
|
cannam@62
|
278 kj::EnableIf<_::Kind_<T>::kind == Kind::PRIMITIVE || _::Kind_<T>::kind == Kind::ENUM>> {
|
cannam@62
|
279 // TODO(msvc): Ideally the EnableIf condition would be `style<T>() == Style::PRIMITIVE`, but MSVC
|
cannam@62
|
280 // cannot yet use style<T>() in this constexpr context.
|
cannam@62
|
281
|
cannam@62
|
282 using Type = kj::Decay<T>;
|
cannam@62
|
283 };
|
cannam@62
|
284
|
cannam@62
|
285 template <typename T>
|
cannam@62
|
286 using FromAny = typename FromAny_<T>::Type;
|
cannam@62
|
287 // Given any Cap'n Proto value type as an input, return the Cap'n Proto base type. That is:
|
cannam@62
|
288 //
|
cannam@62
|
289 // Foo::Reader -> Foo
|
cannam@62
|
290 // Foo::Builder -> Foo
|
cannam@62
|
291 // Foo::Pipeline -> Foo
|
cannam@62
|
292 // Foo::Client -> Foo
|
cannam@62
|
293 // Own<Foo::Server> -> Foo
|
cannam@62
|
294 // uint32_t -> uint32_t
|
cannam@62
|
295
|
cannam@62
|
296 namespace _ { // private
|
cannam@62
|
297
|
cannam@62
|
298 template <typename T, Kind k = CAPNP_KIND(T)>
|
cannam@62
|
299 struct PointerHelpers;
|
cannam@62
|
300
|
cannam@62
|
301 #if _MSC_VER
|
cannam@62
|
302
|
cannam@62
|
303 template <typename T, Kind k>
|
cannam@62
|
304 struct PointerHelpers {};
|
cannam@62
|
305 // For some reason, without this declaration, MSVC will error out on some uses of PointerHelpers
|
cannam@62
|
306 // claiming that "T" -- as used in the default initializer for the second template param, "k" --
|
cannam@62
|
307 // is not defined. I do not understand this error, but adding this empty default declaration fixes
|
cannam@62
|
308 // it.
|
cannam@62
|
309
|
cannam@62
|
310 #endif
|
cannam@62
|
311
|
cannam@62
|
312 } // namespace _ (private)
|
cannam@62
|
313
|
cannam@62
|
314 struct MessageSize {
|
cannam@62
|
315 // Size of a message. Every struct type has a method `.totalSize()` that returns this.
|
cannam@62
|
316 uint64_t wordCount;
|
cannam@62
|
317 uint capCount;
|
cannam@62
|
318 };
|
cannam@62
|
319
|
cannam@62
|
320 // =======================================================================================
|
cannam@62
|
321 // Raw memory types and measures
|
cannam@62
|
322
|
cannam@62
|
323 using kj::byte;
|
cannam@62
|
324
|
cannam@62
|
325 class word { uint64_t content KJ_UNUSED_MEMBER; KJ_DISALLOW_COPY(word); public: word() = default; };
|
cannam@62
|
326 // word is an opaque type with size of 64 bits. This type is useful only to make pointer
|
cannam@62
|
327 // arithmetic clearer. Since the contents are private, the only way to access them is to first
|
cannam@62
|
328 // reinterpret_cast to some other pointer type.
|
cannam@62
|
329 //
|
cannam@62
|
330 // Copying is disallowed because you should always use memcpy(). Otherwise, you may run afoul of
|
cannam@62
|
331 // aliasing rules.
|
cannam@62
|
332 //
|
cannam@62
|
333 // A pointer of type word* should always be word-aligned even if won't actually be dereferenced as
|
cannam@62
|
334 // that type.
|
cannam@62
|
335
|
cannam@62
|
336 static_assert(sizeof(byte) == 1, "uint8_t is not one byte?");
|
cannam@62
|
337 static_assert(sizeof(word) == 8, "uint64_t is not 8 bytes?");
|
cannam@62
|
338
|
cannam@62
|
339 #if CAPNP_DEBUG_TYPES
|
cannam@62
|
340 // Set CAPNP_DEBUG_TYPES to 1 to use kj::Quantity for "count" types. Otherwise, plain integers are
|
cannam@62
|
341 // used. All the code should still operate exactly the same, we just lose compile-time checking.
|
cannam@62
|
342 // Note that this will also change symbol names, so it's important that the library and any clients
|
cannam@62
|
343 // be compiled with the same setting here.
|
cannam@62
|
344 //
|
cannam@62
|
345 // We disable this by default to reduce symbol name size and avoid any possibility of the compiler
|
cannam@62
|
346 // failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this
|
cannam@62
|
347 // during development and testing.
|
cannam@62
|
348
|
cannam@62
|
349 namespace _ { class BitLabel; class ElementLabel; struct WirePointer; }
|
cannam@62
|
350
|
cannam@62
|
351 template <uint width, typename T = uint>
|
cannam@62
|
352 using BitCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::BitLabel>;
|
cannam@62
|
353 template <uint width, typename T = uint>
|
cannam@62
|
354 using ByteCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, byte>;
|
cannam@62
|
355 template <uint width, typename T = uint>
|
cannam@62
|
356 using WordCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, word>;
|
cannam@62
|
357 template <uint width, typename T = uint>
|
cannam@62
|
358 using ElementCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::ElementLabel>;
|
cannam@62
|
359 template <uint width, typename T = uint>
|
cannam@62
|
360 using WirePointerCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::WirePointer>;
|
cannam@62
|
361
|
cannam@62
|
362 typedef BitCountN<8, uint8_t> BitCount8;
|
cannam@62
|
363 typedef BitCountN<16, uint16_t> BitCount16;
|
cannam@62
|
364 typedef BitCountN<32, uint32_t> BitCount32;
|
cannam@62
|
365 typedef BitCountN<64, uint64_t> BitCount64;
|
cannam@62
|
366 typedef BitCountN<sizeof(uint) * 8, uint> BitCount;
|
cannam@62
|
367
|
cannam@62
|
368 typedef ByteCountN<8, uint8_t> ByteCount8;
|
cannam@62
|
369 typedef ByteCountN<16, uint16_t> ByteCount16;
|
cannam@62
|
370 typedef ByteCountN<32, uint32_t> ByteCount32;
|
cannam@62
|
371 typedef ByteCountN<64, uint64_t> ByteCount64;
|
cannam@62
|
372 typedef ByteCountN<sizeof(uint) * 8, uint> ByteCount;
|
cannam@62
|
373
|
cannam@62
|
374 typedef WordCountN<8, uint8_t> WordCount8;
|
cannam@62
|
375 typedef WordCountN<16, uint16_t> WordCount16;
|
cannam@62
|
376 typedef WordCountN<32, uint32_t> WordCount32;
|
cannam@62
|
377 typedef WordCountN<64, uint64_t> WordCount64;
|
cannam@62
|
378 typedef WordCountN<sizeof(uint) * 8, uint> WordCount;
|
cannam@62
|
379
|
cannam@62
|
380 typedef ElementCountN<8, uint8_t> ElementCount8;
|
cannam@62
|
381 typedef ElementCountN<16, uint16_t> ElementCount16;
|
cannam@62
|
382 typedef ElementCountN<32, uint32_t> ElementCount32;
|
cannam@62
|
383 typedef ElementCountN<64, uint64_t> ElementCount64;
|
cannam@62
|
384 typedef ElementCountN<sizeof(uint) * 8, uint> ElementCount;
|
cannam@62
|
385
|
cannam@62
|
386 typedef WirePointerCountN<8, uint8_t> WirePointerCount8;
|
cannam@62
|
387 typedef WirePointerCountN<16, uint16_t> WirePointerCount16;
|
cannam@62
|
388 typedef WirePointerCountN<32, uint32_t> WirePointerCount32;
|
cannam@62
|
389 typedef WirePointerCountN<64, uint64_t> WirePointerCount64;
|
cannam@62
|
390 typedef WirePointerCountN<sizeof(uint) * 8, uint> WirePointerCount;
|
cannam@62
|
391
|
cannam@62
|
392 template <uint width>
|
cannam@62
|
393 using BitsPerElementN = decltype(BitCountN<width>() / ElementCountN<width>());
|
cannam@62
|
394 template <uint width>
|
cannam@62
|
395 using BytesPerElementN = decltype(ByteCountN<width>() / ElementCountN<width>());
|
cannam@62
|
396 template <uint width>
|
cannam@62
|
397 using WordsPerElementN = decltype(WordCountN<width>() / ElementCountN<width>());
|
cannam@62
|
398 template <uint width>
|
cannam@62
|
399 using PointersPerElementN = decltype(WirePointerCountN<width>() / ElementCountN<width>());
|
cannam@62
|
400
|
cannam@62
|
401 using kj::bounded;
|
cannam@62
|
402 using kj::unbound;
|
cannam@62
|
403 using kj::unboundAs;
|
cannam@62
|
404 using kj::unboundMax;
|
cannam@62
|
405 using kj::unboundMaxBits;
|
cannam@62
|
406 using kj::assertMax;
|
cannam@62
|
407 using kj::assertMaxBits;
|
cannam@62
|
408 using kj::upgradeBound;
|
cannam@62
|
409 using kj::ThrowOverflow;
|
cannam@62
|
410 using kj::assumeBits;
|
cannam@62
|
411 using kj::assumeMax;
|
cannam@62
|
412 using kj::subtractChecked;
|
cannam@62
|
413 using kj::trySubtract;
|
cannam@62
|
414
|
cannam@62
|
415 template <typename T, typename U>
|
cannam@62
|
416 inline constexpr U* operator+(U* ptr, kj::Quantity<T, U> offset) {
|
cannam@62
|
417 return ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>());
|
cannam@62
|
418 }
|
cannam@62
|
419 template <typename T, typename U>
|
cannam@62
|
420 inline constexpr const U* operator+(const U* ptr, kj::Quantity<T, U> offset) {
|
cannam@62
|
421 return ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>());
|
cannam@62
|
422 }
|
cannam@62
|
423 template <typename T, typename U>
|
cannam@62
|
424 inline constexpr U* operator+=(U*& ptr, kj::Quantity<T, U> offset) {
|
cannam@62
|
425 return ptr = ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>());
|
cannam@62
|
426 }
|
cannam@62
|
427 template <typename T, typename U>
|
cannam@62
|
428 inline constexpr const U* operator+=(const U*& ptr, kj::Quantity<T, U> offset) {
|
cannam@62
|
429 return ptr = ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>());
|
cannam@62
|
430 }
|
cannam@62
|
431
|
cannam@62
|
432 template <typename T, typename U>
|
cannam@62
|
433 inline constexpr U* operator-(U* ptr, kj::Quantity<T, U> offset) {
|
cannam@62
|
434 return ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>());
|
cannam@62
|
435 }
|
cannam@62
|
436 template <typename T, typename U>
|
cannam@62
|
437 inline constexpr const U* operator-(const U* ptr, kj::Quantity<T, U> offset) {
|
cannam@62
|
438 return ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>());
|
cannam@62
|
439 }
|
cannam@62
|
440 template <typename T, typename U>
|
cannam@62
|
441 inline constexpr U* operator-=(U*& ptr, kj::Quantity<T, U> offset) {
|
cannam@62
|
442 return ptr = ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>());
|
cannam@62
|
443 }
|
cannam@62
|
444 template <typename T, typename U>
|
cannam@62
|
445 inline constexpr const U* operator-=(const U*& ptr, kj::Quantity<T, U> offset) {
|
cannam@62
|
446 return ptr = ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>());
|
cannam@62
|
447 }
|
cannam@62
|
448
|
cannam@62
|
449 constexpr auto BITS = kj::unit<BitCountN<1>>();
|
cannam@62
|
450 constexpr auto BYTES = kj::unit<ByteCountN<1>>();
|
cannam@62
|
451 constexpr auto WORDS = kj::unit<WordCountN<1>>();
|
cannam@62
|
452 constexpr auto ELEMENTS = kj::unit<ElementCountN<1>>();
|
cannam@62
|
453 constexpr auto POINTERS = kj::unit<WirePointerCountN<1>>();
|
cannam@62
|
454
|
cannam@62
|
455 constexpr auto ZERO = kj::bounded<0>();
|
cannam@62
|
456 constexpr auto ONE = kj::bounded<1>();
|
cannam@62
|
457
|
cannam@62
|
458 // GCC 4.7 actually gives unused warnings on these constants in opt mode...
|
cannam@62
|
459 constexpr auto BITS_PER_BYTE KJ_UNUSED = bounded<8>() * BITS / BYTES;
|
cannam@62
|
460 constexpr auto BITS_PER_WORD KJ_UNUSED = bounded<64>() * BITS / WORDS;
|
cannam@62
|
461 constexpr auto BYTES_PER_WORD KJ_UNUSED = bounded<8>() * BYTES / WORDS;
|
cannam@62
|
462
|
cannam@62
|
463 constexpr auto BITS_PER_POINTER KJ_UNUSED = bounded<64>() * BITS / POINTERS;
|
cannam@62
|
464 constexpr auto BYTES_PER_POINTER KJ_UNUSED = bounded<8>() * BYTES / POINTERS;
|
cannam@62
|
465 constexpr auto WORDS_PER_POINTER KJ_UNUSED = ONE * WORDS / POINTERS;
|
cannam@62
|
466
|
cannam@62
|
467 constexpr auto POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER;
|
cannam@62
|
468
|
cannam@62
|
469 constexpr uint SEGMENT_WORD_COUNT_BITS = 29; // Number of words in a segment.
|
cannam@62
|
470 constexpr uint LIST_ELEMENT_COUNT_BITS = 29; // Number of elements in a list.
|
cannam@62
|
471 constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16; // Number of words in a Struct data section.
|
cannam@62
|
472 constexpr uint STRUCT_POINTER_COUNT_BITS = 16; // Number of pointers in a Struct pointer section.
|
cannam@62
|
473 constexpr uint BLOB_SIZE_BITS = 29; // Number of bytes in a blob.
|
cannam@62
|
474
|
cannam@62
|
475 typedef WordCountN<SEGMENT_WORD_COUNT_BITS> SegmentWordCount;
|
cannam@62
|
476 typedef ElementCountN<LIST_ELEMENT_COUNT_BITS> ListElementCount;
|
cannam@62
|
477 typedef WordCountN<STRUCT_DATA_WORD_COUNT_BITS, uint16_t> StructDataWordCount;
|
cannam@62
|
478 typedef WirePointerCountN<STRUCT_POINTER_COUNT_BITS, uint16_t> StructPointerCount;
|
cannam@62
|
479 typedef ByteCountN<BLOB_SIZE_BITS> BlobSize;
|
cannam@62
|
480
|
cannam@62
|
481 constexpr auto MAX_SEGMENT_WORDS =
|
cannam@62
|
482 bounded<kj::maxValueForBits<SEGMENT_WORD_COUNT_BITS>()>() * WORDS;
|
cannam@62
|
483 constexpr auto MAX_LIST_ELEMENTS =
|
cannam@62
|
484 bounded<kj::maxValueForBits<LIST_ELEMENT_COUNT_BITS>()>() * ELEMENTS;
|
cannam@62
|
485 constexpr auto MAX_STUCT_DATA_WORDS =
|
cannam@62
|
486 bounded<kj::maxValueForBits<STRUCT_DATA_WORD_COUNT_BITS>()>() * WORDS;
|
cannam@62
|
487 constexpr auto MAX_STRUCT_POINTER_COUNT =
|
cannam@62
|
488 bounded<kj::maxValueForBits<STRUCT_POINTER_COUNT_BITS>()>() * POINTERS;
|
cannam@62
|
489
|
cannam@62
|
490 using StructDataBitCount = decltype(WordCountN<STRUCT_POINTER_COUNT_BITS>() * BITS_PER_WORD);
|
cannam@62
|
491 // Number of bits in a Struct data segment (should come out to BitCountN<22>).
|
cannam@62
|
492
|
cannam@62
|
493 using StructDataOffset = decltype(StructDataBitCount() * (ONE * ELEMENTS / BITS));
|
cannam@62
|
494 using StructPointerOffset = StructPointerCount;
|
cannam@62
|
495 // Type of a field offset.
|
cannam@62
|
496
|
cannam@62
|
497 inline StructDataOffset assumeDataOffset(uint32_t offset) {
|
cannam@62
|
498 return assumeMax(MAX_STUCT_DATA_WORDS * BITS_PER_WORD * (ONE * ELEMENTS / BITS),
|
cannam@62
|
499 bounded(offset) * ELEMENTS);
|
cannam@62
|
500 }
|
cannam@62
|
501
|
cannam@62
|
502 inline StructPointerOffset assumePointerOffset(uint32_t offset) {
|
cannam@62
|
503 return assumeMax(MAX_STRUCT_POINTER_COUNT, bounded(offset) * POINTERS);
|
cannam@62
|
504 }
|
cannam@62
|
505
|
cannam@62
|
506 constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits<BLOB_SIZE_BITS>() - 1;
|
cannam@62
|
507 typedef kj::Quantity<kj::Bounded<MAX_TEXT_SIZE, uint>, byte> TextSize;
|
cannam@62
|
508 // Not including NUL terminator.
|
cannam@62
|
509
|
cannam@62
|
510 template <typename T>
|
cannam@62
|
511 inline KJ_CONSTEXPR() decltype(bounded<sizeof(T)>() * BYTES / ELEMENTS) bytesPerElement() {
|
cannam@62
|
512 return bounded<sizeof(T)>() * BYTES / ELEMENTS;
|
cannam@62
|
513 }
|
cannam@62
|
514
|
cannam@62
|
515 template <typename T>
|
cannam@62
|
516 inline KJ_CONSTEXPR() decltype(bounded<sizeof(T) * 8>() * BITS / ELEMENTS) bitsPerElement() {
|
cannam@62
|
517 return bounded<sizeof(T) * 8>() * BITS / ELEMENTS;
|
cannam@62
|
518 }
|
cannam@62
|
519
|
cannam@62
|
520 template <typename T, uint maxN>
|
cannam@62
|
521 inline constexpr kj::Quantity<kj::Bounded<maxN, size_t>, T>
|
cannam@62
|
522 intervalLength(const T* a, const T* b, kj::Quantity<kj::BoundedConst<maxN>, T>) {
|
cannam@62
|
523 return kj::assumeMax<maxN>(b - a) * kj::unit<kj::Quantity<kj::BoundedConst<1u>, T>>();
|
cannam@62
|
524 }
|
cannam@62
|
525
|
cannam@62
|
526 template <typename T, typename U>
|
cannam@62
|
527 inline constexpr kj::ArrayPtr<const U> arrayPtr(const U* ptr, kj::Quantity<T, U> size) {
|
cannam@62
|
528 return kj::ArrayPtr<const U>(ptr, unbound(size / kj::unit<kj::Quantity<T, U>>()));
|
cannam@62
|
529 }
|
cannam@62
|
530 template <typename T, typename U>
|
cannam@62
|
531 inline constexpr kj::ArrayPtr<U> arrayPtr(U* ptr, kj::Quantity<T, U> size) {
|
cannam@62
|
532 return kj::ArrayPtr<U>(ptr, unbound(size / kj::unit<kj::Quantity<T, U>>()));
|
cannam@62
|
533 }
|
cannam@62
|
534
|
cannam@62
|
535 #else
|
cannam@62
|
536
|
cannam@62
|
537 template <uint width, typename T = uint>
|
cannam@62
|
538 using BitCountN = T;
|
cannam@62
|
539 template <uint width, typename T = uint>
|
cannam@62
|
540 using ByteCountN = T;
|
cannam@62
|
541 template <uint width, typename T = uint>
|
cannam@62
|
542 using WordCountN = T;
|
cannam@62
|
543 template <uint width, typename T = uint>
|
cannam@62
|
544 using ElementCountN = T;
|
cannam@62
|
545 template <uint width, typename T = uint>
|
cannam@62
|
546 using WirePointerCountN = T;
|
cannam@62
|
547
|
cannam@62
|
548
|
cannam@62
|
549 // XXX
|
cannam@62
|
550 typedef BitCountN<8, uint8_t> BitCount8;
|
cannam@62
|
551 typedef BitCountN<16, uint16_t> BitCount16;
|
cannam@62
|
552 typedef BitCountN<32, uint32_t> BitCount32;
|
cannam@62
|
553 typedef BitCountN<64, uint64_t> BitCount64;
|
cannam@62
|
554 typedef BitCountN<sizeof(uint) * 8, uint> BitCount;
|
cannam@62
|
555
|
cannam@62
|
556 typedef ByteCountN<8, uint8_t> ByteCount8;
|
cannam@62
|
557 typedef ByteCountN<16, uint16_t> ByteCount16;
|
cannam@62
|
558 typedef ByteCountN<32, uint32_t> ByteCount32;
|
cannam@62
|
559 typedef ByteCountN<64, uint64_t> ByteCount64;
|
cannam@62
|
560 typedef ByteCountN<sizeof(uint) * 8, uint> ByteCount;
|
cannam@62
|
561
|
cannam@62
|
562 typedef WordCountN<8, uint8_t> WordCount8;
|
cannam@62
|
563 typedef WordCountN<16, uint16_t> WordCount16;
|
cannam@62
|
564 typedef WordCountN<32, uint32_t> WordCount32;
|
cannam@62
|
565 typedef WordCountN<64, uint64_t> WordCount64;
|
cannam@62
|
566 typedef WordCountN<sizeof(uint) * 8, uint> WordCount;
|
cannam@62
|
567
|
cannam@62
|
568 typedef ElementCountN<8, uint8_t> ElementCount8;
|
cannam@62
|
569 typedef ElementCountN<16, uint16_t> ElementCount16;
|
cannam@62
|
570 typedef ElementCountN<32, uint32_t> ElementCount32;
|
cannam@62
|
571 typedef ElementCountN<64, uint64_t> ElementCount64;
|
cannam@62
|
572 typedef ElementCountN<sizeof(uint) * 8, uint> ElementCount;
|
cannam@62
|
573
|
cannam@62
|
574 typedef WirePointerCountN<8, uint8_t> WirePointerCount8;
|
cannam@62
|
575 typedef WirePointerCountN<16, uint16_t> WirePointerCount16;
|
cannam@62
|
576 typedef WirePointerCountN<32, uint32_t> WirePointerCount32;
|
cannam@62
|
577 typedef WirePointerCountN<64, uint64_t> WirePointerCount64;
|
cannam@62
|
578 typedef WirePointerCountN<sizeof(uint) * 8, uint> WirePointerCount;
|
cannam@62
|
579
|
cannam@62
|
580 template <uint width>
|
cannam@62
|
581 using BitsPerElementN = decltype(BitCountN<width>() / ElementCountN<width>());
|
cannam@62
|
582 template <uint width>
|
cannam@62
|
583 using BytesPerElementN = decltype(ByteCountN<width>() / ElementCountN<width>());
|
cannam@62
|
584 template <uint width>
|
cannam@62
|
585 using WordsPerElementN = decltype(WordCountN<width>() / ElementCountN<width>());
|
cannam@62
|
586 template <uint width>
|
cannam@62
|
587 using PointersPerElementN = decltype(WirePointerCountN<width>() / ElementCountN<width>());
|
cannam@62
|
588
|
cannam@62
|
589 using kj::ThrowOverflow;
|
cannam@62
|
590 // YYY
|
cannam@62
|
591
|
cannam@62
|
592 template <uint i> inline constexpr uint bounded() { return i; }
|
cannam@62
|
593 template <typename T> inline constexpr T bounded(T i) { return i; }
|
cannam@62
|
594 template <typename T> inline constexpr T unbound(T i) { return i; }
|
cannam@62
|
595
|
cannam@62
|
596 template <typename T, typename U> inline constexpr T unboundAs(U i) { return i; }
|
cannam@62
|
597
|
cannam@62
|
598 template <uint64_t requestedMax, typename T> inline constexpr uint unboundMax(T i) { return i; }
|
cannam@62
|
599 template <uint bits, typename T> inline constexpr uint unboundMaxBits(T i) { return i; }
|
cannam@62
|
600
|
cannam@62
|
601 template <uint newMax, typename T, typename ErrorFunc>
|
cannam@62
|
602 inline T assertMax(T value, ErrorFunc&& func) {
|
cannam@62
|
603 if (KJ_UNLIKELY(value > newMax)) func();
|
cannam@62
|
604 return value;
|
cannam@62
|
605 }
|
cannam@62
|
606
|
cannam@62
|
607 template <typename T, typename ErrorFunc>
|
cannam@62
|
608 inline T assertMax(uint newMax, T value, ErrorFunc&& func) {
|
cannam@62
|
609 if (KJ_UNLIKELY(value > newMax)) func();
|
cannam@62
|
610 return value;
|
cannam@62
|
611 }
|
cannam@62
|
612
|
cannam@62
|
613 template <uint bits, typename T, typename ErrorFunc = ThrowOverflow>
|
cannam@62
|
614 inline T assertMaxBits(T value, ErrorFunc&& func = ErrorFunc()) {
|
cannam@62
|
615 if (KJ_UNLIKELY(value > kj::maxValueForBits<bits>())) func();
|
cannam@62
|
616 return value;
|
cannam@62
|
617 }
|
cannam@62
|
618
|
cannam@62
|
619 template <typename T, typename ErrorFunc = ThrowOverflow>
|
cannam@62
|
620 inline T assertMaxBits(uint bits, T value, ErrorFunc&& func = ErrorFunc()) {
|
cannam@62
|
621 if (KJ_UNLIKELY(value > (1ull << bits) - 1)) func();
|
cannam@62
|
622 return value;
|
cannam@62
|
623 }
|
cannam@62
|
624
|
cannam@62
|
625 template <typename T, typename U> inline constexpr T upgradeBound(U i) { return i; }
|
cannam@62
|
626
|
cannam@62
|
627 template <uint bits, typename T> inline constexpr T assumeBits(T i) { return i; }
|
cannam@62
|
628 template <uint64_t max, typename T> inline constexpr T assumeMax(T i) { return i; }
|
cannam@62
|
629
|
cannam@62
|
630 template <typename T, typename U, typename ErrorFunc = ThrowOverflow>
|
cannam@62
|
631 inline auto subtractChecked(T a, U b, ErrorFunc&& errorFunc = ErrorFunc())
|
cannam@62
|
632 -> decltype(a - b) {
|
cannam@62
|
633 if (b > a) errorFunc();
|
cannam@62
|
634 return a - b;
|
cannam@62
|
635 }
|
cannam@62
|
636
|
cannam@62
|
637 template <typename T, typename U>
|
cannam@62
|
638 inline auto trySubtract(T a, U b) -> kj::Maybe<decltype(a - b)> {
|
cannam@62
|
639 if (b > a) {
|
cannam@62
|
640 return nullptr;
|
cannam@62
|
641 } else {
|
cannam@62
|
642 return a - b;
|
cannam@62
|
643 }
|
cannam@62
|
644 }
|
cannam@62
|
645
|
cannam@62
|
646 constexpr uint BITS = 1;
|
cannam@62
|
647 constexpr uint BYTES = 1;
|
cannam@62
|
648 constexpr uint WORDS = 1;
|
cannam@62
|
649 constexpr uint ELEMENTS = 1;
|
cannam@62
|
650 constexpr uint POINTERS = 1;
|
cannam@62
|
651
|
cannam@62
|
652 constexpr uint ZERO = 0;
|
cannam@62
|
653 constexpr uint ONE = 1;
|
cannam@62
|
654
|
cannam@62
|
655 // GCC 4.7 actually gives unused warnings on these constants in opt mode...
|
cannam@62
|
656 constexpr uint BITS_PER_BYTE KJ_UNUSED = 8;
|
cannam@62
|
657 constexpr uint BITS_PER_WORD KJ_UNUSED = 64;
|
cannam@62
|
658 constexpr uint BYTES_PER_WORD KJ_UNUSED = 8;
|
cannam@62
|
659
|
cannam@62
|
660 constexpr uint BITS_PER_POINTER KJ_UNUSED = 64;
|
cannam@62
|
661 constexpr uint BYTES_PER_POINTER KJ_UNUSED = 8;
|
cannam@62
|
662 constexpr uint WORDS_PER_POINTER KJ_UNUSED = 1;
|
cannam@62
|
663
|
cannam@62
|
664 // XXX
|
cannam@62
|
665 constexpr uint POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER;
|
cannam@62
|
666
|
cannam@62
|
667 constexpr uint SEGMENT_WORD_COUNT_BITS = 29; // Number of words in a segment.
|
cannam@62
|
668 constexpr uint LIST_ELEMENT_COUNT_BITS = 29; // Number of elements in a list.
|
cannam@62
|
669 constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16; // Number of words in a Struct data section.
|
cannam@62
|
670 constexpr uint STRUCT_POINTER_COUNT_BITS = 16; // Number of pointers in a Struct pointer section.
|
cannam@62
|
671 constexpr uint BLOB_SIZE_BITS = 29; // Number of bytes in a blob.
|
cannam@62
|
672
|
cannam@62
|
673 typedef WordCountN<SEGMENT_WORD_COUNT_BITS> SegmentWordCount;
|
cannam@62
|
674 typedef ElementCountN<LIST_ELEMENT_COUNT_BITS> ListElementCount;
|
cannam@62
|
675 typedef WordCountN<STRUCT_DATA_WORD_COUNT_BITS, uint16_t> StructDataWordCount;
|
cannam@62
|
676 typedef WirePointerCountN<STRUCT_POINTER_COUNT_BITS, uint16_t> StructPointerCount;
|
cannam@62
|
677 typedef ByteCountN<BLOB_SIZE_BITS> BlobSize;
|
cannam@62
|
678 // YYY
|
cannam@62
|
679
|
cannam@62
|
680 constexpr auto MAX_SEGMENT_WORDS = kj::maxValueForBits<SEGMENT_WORD_COUNT_BITS>();
|
cannam@62
|
681 constexpr auto MAX_LIST_ELEMENTS = kj::maxValueForBits<LIST_ELEMENT_COUNT_BITS>();
|
cannam@62
|
682 constexpr auto MAX_STUCT_DATA_WORDS = kj::maxValueForBits<STRUCT_DATA_WORD_COUNT_BITS>();
|
cannam@62
|
683 constexpr auto MAX_STRUCT_POINTER_COUNT = kj::maxValueForBits<STRUCT_POINTER_COUNT_BITS>();
|
cannam@62
|
684
|
cannam@62
|
685 typedef uint StructDataBitCount;
|
cannam@62
|
686 typedef uint StructDataOffset;
|
cannam@62
|
687 typedef uint StructPointerOffset;
|
cannam@62
|
688
|
cannam@62
|
689 inline StructDataOffset assumeDataOffset(uint32_t offset) { return offset; }
|
cannam@62
|
690 inline StructPointerOffset assumePointerOffset(uint32_t offset) { return offset; }
|
cannam@62
|
691
|
cannam@62
|
692 constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits<BLOB_SIZE_BITS>() - 1;
|
cannam@62
|
693 typedef uint TextSize;
|
cannam@62
|
694
|
cannam@62
|
695 template <typename T>
|
cannam@62
|
696 inline KJ_CONSTEXPR() size_t bytesPerElement() { return sizeof(T); }
|
cannam@62
|
697
|
cannam@62
|
698 template <typename T>
|
cannam@62
|
699 inline KJ_CONSTEXPR() size_t bitsPerElement() { return sizeof(T) * 8; }
|
cannam@62
|
700
|
cannam@62
|
701 template <typename T>
|
cannam@62
|
702 inline constexpr ptrdiff_t intervalLength(const T* a, const T* b, uint) {
|
cannam@62
|
703 return b - a;
|
cannam@62
|
704 }
|
cannam@62
|
705
|
cannam@62
|
706 template <typename T, typename U>
|
cannam@62
|
707 inline constexpr kj::ArrayPtr<const U> arrayPtr(const U* ptr, T size) {
|
cannam@62
|
708 return kj::arrayPtr(ptr, size);
|
cannam@62
|
709 }
|
cannam@62
|
710 template <typename T, typename U>
|
cannam@62
|
711 inline constexpr kj::ArrayPtr<U> arrayPtr(U* ptr, T size) {
|
cannam@62
|
712 return kj::arrayPtr(ptr, size);
|
cannam@62
|
713 }
|
cannam@62
|
714
|
cannam@62
|
715 #endif
|
cannam@62
|
716
|
cannam@62
|
717 } // namespace capnp
|
cannam@62
|
718
|
cannam@62
|
719 #endif // CAPNP_COMMON_H_
|