Mercurial > hg > sv-dependency-builds
comparison osx/include/capnp/common.h @ 49:3ab5a40c4e3b
Add Capnp and KJ builds for OSX
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Tue, 25 Oct 2016 14:48:23 +0100 |
parents | |
children | 0994c39f1e94 |
comparison
equal
deleted
inserted
replaced
48:9530b331f8c1 | 49:3ab5a40c4e3b |
---|---|
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors | |
2 // Licensed under the MIT License: | |
3 // | |
4 // Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 // of this software and associated documentation files (the "Software"), to deal | |
6 // in the Software without restriction, including without limitation the rights | |
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 // copies of the Software, and to permit persons to whom the Software is | |
9 // furnished to do so, subject to the following conditions: | |
10 // | |
11 // The above copyright notice and this permission notice shall be included in | |
12 // all copies or substantial portions of the Software. | |
13 // | |
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
20 // THE SOFTWARE. | |
21 | |
22 // This file contains types which are intended to help detect incorrect usage at compile | |
23 // time, but should then be optimized down to basic primitives (usually, integers) by the | |
24 // compiler. | |
25 | |
26 #ifndef CAPNP_COMMON_H_ | |
27 #define CAPNP_COMMON_H_ | |
28 | |
29 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) | |
30 #pragma GCC system_header | |
31 #endif | |
32 | |
33 #include <kj/units.h> | |
34 #include <inttypes.h> | |
35 #include <kj/string.h> | |
36 #include <kj/memory.h> | |
37 | |
38 namespace capnp { | |
39 | |
40 #define CAPNP_VERSION_MAJOR 0 | |
41 #define CAPNP_VERSION_MINOR 6 | |
42 #define CAPNP_VERSION_MICRO 0 | |
43 | |
44 #define CAPNP_VERSION \ | |
45 (CAPNP_VERSION_MAJOR * 1000000 + CAPNP_VERSION_MINOR * 1000 + CAPNP_VERSION_MICRO) | |
46 | |
47 #ifdef _MSC_VER | |
48 #define CAPNP_LITE 1 | |
49 // MSVC only supports "lite" mode for now, due to missing C++11 features. | |
50 #endif | |
51 | |
52 #ifndef CAPNP_LITE | |
53 #define CAPNP_LITE 0 | |
54 #endif | |
55 | |
56 typedef unsigned int uint; | |
57 | |
58 struct Void { | |
59 // Type used for Void fields. Using C++'s "void" type creates a bunch of issues since it behaves | |
60 // differently from other types. | |
61 | |
62 inline constexpr bool operator==(Void other) const { return true; } | |
63 inline constexpr bool operator!=(Void other) const { return false; } | |
64 }; | |
65 | |
66 static constexpr Void VOID = Void(); | |
67 // Constant value for `Void`, which is an empty struct. | |
68 | |
69 inline kj::StringPtr KJ_STRINGIFY(Void) { return "void"; } | |
70 | |
71 struct Text; | |
72 struct Data; | |
73 | |
74 enum class Kind: uint8_t { | |
75 PRIMITIVE, | |
76 BLOB, | |
77 ENUM, | |
78 STRUCT, | |
79 UNION, | |
80 INTERFACE, | |
81 LIST, | |
82 | |
83 OTHER | |
84 // Some other type which is often a type parameter to Cap'n Proto templates, but which needs | |
85 // special handling. This includes types like AnyPointer, Dynamic*, etc. | |
86 }; | |
87 | |
88 enum class Style: uint8_t { | |
89 PRIMITIVE, | |
90 POINTER, // other than struct | |
91 STRUCT, | |
92 CAPABILITY | |
93 }; | |
94 | |
95 enum class ElementSize: uint8_t { | |
96 // Size of a list element. | |
97 | |
98 VOID = 0, | |
99 BIT = 1, | |
100 BYTE = 2, | |
101 TWO_BYTES = 3, | |
102 FOUR_BYTES = 4, | |
103 EIGHT_BYTES = 5, | |
104 | |
105 POINTER = 6, | |
106 | |
107 INLINE_COMPOSITE = 7 | |
108 }; | |
109 | |
110 enum class PointerType { | |
111 // Various wire types a pointer field can take | |
112 | |
113 NULL_, | |
114 // Should be NULL, but that's #defined in stddef.h | |
115 | |
116 STRUCT, | |
117 LIST, | |
118 CAPABILITY | |
119 }; | |
120 | |
121 namespace schemas { | |
122 | |
123 template <typename T> | |
124 struct EnumInfo; | |
125 | |
126 } // namespace schemas | |
127 | |
128 namespace _ { // private | |
129 | |
130 template <typename T, typename = void> struct Kind_; | |
131 | |
132 template <> struct Kind_<Void> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
133 template <> struct Kind_<bool> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
134 template <> struct Kind_<int8_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
135 template <> struct Kind_<int16_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
136 template <> struct Kind_<int32_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
137 template <> struct Kind_<int64_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
138 template <> struct Kind_<uint8_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
139 template <> struct Kind_<uint16_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
140 template <> struct Kind_<uint32_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
141 template <> struct Kind_<uint64_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
142 template <> struct Kind_<float> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
143 template <> struct Kind_<double> { static constexpr Kind kind = Kind::PRIMITIVE; }; | |
144 template <> struct Kind_<Text> { static constexpr Kind kind = Kind::BLOB; }; | |
145 template <> struct Kind_<Data> { static constexpr Kind kind = Kind::BLOB; }; | |
146 | |
147 template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsStruct>> { | |
148 static constexpr Kind kind = Kind::STRUCT; | |
149 }; | |
150 template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsInterface>> { | |
151 static constexpr Kind kind = Kind::INTERFACE; | |
152 }; | |
153 template <typename T> struct Kind_<T, kj::VoidSfinae<typename schemas::EnumInfo<T>::IsEnum>> { | |
154 static constexpr Kind kind = Kind::ENUM; | |
155 }; | |
156 | |
157 } // namespace _ (private) | |
158 | |
159 template <typename T, Kind k = _::Kind_<T>::kind> | |
160 inline constexpr Kind kind() { | |
161 // This overload of kind() matches types which have a Kind_ specialization. | |
162 | |
163 return k; | |
164 } | |
165 | |
166 #if CAPNP_LITE | |
167 | |
168 #define CAPNP_KIND(T) ::capnp::_::Kind_<T>::kind | |
169 // Avoid constexpr methods in lite mode (MSVC is bad at constexpr). | |
170 | |
171 #else // CAPNP_LITE | |
172 | |
173 #define CAPNP_KIND(T) ::capnp::kind<T>() | |
174 // Use this macro rather than kind<T>() in any code which must work in lite mode. | |
175 | |
176 template <typename T, Kind k = kind<T>()> | |
177 inline constexpr Style style() { | |
178 return k == Kind::PRIMITIVE || k == Kind::ENUM ? Style::PRIMITIVE | |
179 : k == Kind::STRUCT ? Style::STRUCT | |
180 : k == Kind::INTERFACE ? Style::CAPABILITY : Style::POINTER; | |
181 } | |
182 | |
183 #endif // CAPNP_LITE, else | |
184 | |
185 template <typename T, Kind k = CAPNP_KIND(T)> | |
186 struct List; | |
187 | |
188 #if _MSC_VER | |
189 | |
190 template <typename T, Kind k> | |
191 struct List {}; | |
192 // For some reason, without this declaration, MSVC will error out on some uses of List | |
193 // claiming that "T" -- as used in the default initializer for the second template param, "k" -- | |
194 // is not defined. I do not understand this error, but adding this empty default declaration fixes | |
195 // it. | |
196 | |
197 #endif | |
198 | |
199 template <typename T> struct ListElementType_; | |
200 template <typename T> struct ListElementType_<List<T>> { typedef T Type; }; | |
201 template <typename T> using ListElementType = typename ListElementType_<T>::Type; | |
202 | |
203 namespace _ { // private | |
204 template <typename T, Kind k> struct Kind_<List<T, k>> { | |
205 static constexpr Kind kind = Kind::LIST; | |
206 }; | |
207 } // namespace _ (private) | |
208 | |
209 template <typename T, Kind k = CAPNP_KIND(T)> struct ReaderFor_ { typedef typename T::Reader Type; }; | |
210 template <typename T> struct ReaderFor_<T, Kind::PRIMITIVE> { typedef T Type; }; | |
211 template <typename T> struct ReaderFor_<T, Kind::ENUM> { typedef T Type; }; | |
212 template <typename T> struct ReaderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; }; | |
213 template <typename T> using ReaderFor = typename ReaderFor_<T>::Type; | |
214 // The type returned by List<T>::Reader::operator[]. | |
215 | |
216 template <typename T, Kind k = CAPNP_KIND(T)> struct BuilderFor_ { typedef typename T::Builder Type; }; | |
217 template <typename T> struct BuilderFor_<T, Kind::PRIMITIVE> { typedef T Type; }; | |
218 template <typename T> struct BuilderFor_<T, Kind::ENUM> { typedef T Type; }; | |
219 template <typename T> struct BuilderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; }; | |
220 template <typename T> using BuilderFor = typename BuilderFor_<T>::Type; | |
221 // The type returned by List<T>::Builder::operator[]. | |
222 | |
223 template <typename T, Kind k = CAPNP_KIND(T)> struct PipelineFor_ { typedef typename T::Pipeline Type;}; | |
224 template <typename T> struct PipelineFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; }; | |
225 template <typename T> using PipelineFor = typename PipelineFor_<T>::Type; | |
226 | |
227 template <typename T, Kind k = CAPNP_KIND(T)> struct TypeIfEnum_; | |
228 template <typename T> struct TypeIfEnum_<T, Kind::ENUM> { typedef T Type; }; | |
229 | |
230 template <typename T> | |
231 using TypeIfEnum = typename TypeIfEnum_<kj::Decay<T>>::Type; | |
232 | |
233 template <typename T> | |
234 using FromReader = typename kj::Decay<T>::Reads; | |
235 // FromReader<MyType::Reader> = MyType (for any Cap'n Proto type). | |
236 | |
237 template <typename T> | |
238 using FromBuilder = typename kj::Decay<T>::Builds; | |
239 // FromBuilder<MyType::Builder> = MyType (for any Cap'n Proto type). | |
240 | |
241 template <typename T> | |
242 using FromPipeline = typename kj::Decay<T>::Pipelines; | |
243 // FromBuilder<MyType::Pipeline> = MyType (for any Cap'n Proto type). | |
244 | |
245 template <typename T> | |
246 using FromClient = typename kj::Decay<T>::Calls; | |
247 // FromReader<MyType::Client> = MyType (for any Cap'n Proto interface type). | |
248 | |
249 template <typename T> | |
250 using FromServer = typename kj::Decay<T>::Serves; | |
251 // FromBuilder<MyType::Server> = MyType (for any Cap'n Proto interface type). | |
252 | |
253 template <typename T, typename = void> | |
254 struct FromAny_; | |
255 | |
256 template <typename T> | |
257 struct FromAny_<T, kj::VoidSfinae<FromReader<T>>> { | |
258 using Type = FromReader<T>; | |
259 }; | |
260 | |
261 template <typename T> | |
262 struct FromAny_<T, kj::VoidSfinae<FromBuilder<T>>> { | |
263 using Type = FromBuilder<T>; | |
264 }; | |
265 | |
266 template <typename T> | |
267 struct FromAny_<T, kj::VoidSfinae<FromPipeline<T>>> { | |
268 using Type = FromPipeline<T>; | |
269 }; | |
270 | |
271 // Note that T::Client is covered by FromReader | |
272 | |
273 template <typename T> | |
274 struct FromAny_<kj::Own<T>, kj::VoidSfinae<FromServer<T>>> { | |
275 using Type = FromServer<T>; | |
276 }; | |
277 | |
278 template <typename T> | |
279 struct FromAny_<T, | |
280 kj::EnableIf<_::Kind_<T>::kind == Kind::PRIMITIVE || _::Kind_<T>::kind == Kind::ENUM>> { | |
281 // TODO(msvc): Ideally the EnableIf condition would be `style<T>() == Style::PRIMITIVE`, but MSVC | |
282 // cannot yet use style<T>() in this constexpr context. | |
283 | |
284 using Type = kj::Decay<T>; | |
285 }; | |
286 | |
287 template <typename T> | |
288 using FromAny = typename FromAny_<T>::Type; | |
289 // Given any Cap'n Proto value type as an input, return the Cap'n Proto base type. That is: | |
290 // | |
291 // Foo::Reader -> Foo | |
292 // Foo::Builder -> Foo | |
293 // Foo::Pipeline -> Foo | |
294 // Foo::Client -> Foo | |
295 // Own<Foo::Server> -> Foo | |
296 // uint32_t -> uint32_t | |
297 | |
298 namespace _ { // private | |
299 | |
300 template <typename T, Kind k = CAPNP_KIND(T)> | |
301 struct PointerHelpers; | |
302 | |
303 #if _MSC_VER | |
304 | |
305 template <typename T, Kind k> | |
306 struct PointerHelpers {}; | |
307 // For some reason, without this declaration, MSVC will error out on some uses of PointerHelpers | |
308 // claiming that "T" -- as used in the default initializer for the second template param, "k" -- | |
309 // is not defined. I do not understand this error, but adding this empty default declaration fixes | |
310 // it. | |
311 | |
312 #endif | |
313 | |
314 } // namespace _ (private) | |
315 | |
316 struct MessageSize { | |
317 // Size of a message. Every struct type has a method `.totalSize()` that returns this. | |
318 uint64_t wordCount; | |
319 uint capCount; | |
320 }; | |
321 | |
322 // ======================================================================================= | |
323 // Raw memory types and measures | |
324 | |
325 using kj::byte; | |
326 | |
327 class word { uint64_t content KJ_UNUSED_MEMBER; KJ_DISALLOW_COPY(word); public: word() = default; }; | |
328 // word is an opaque type with size of 64 bits. This type is useful only to make pointer | |
329 // arithmetic clearer. Since the contents are private, the only way to access them is to first | |
330 // reinterpret_cast to some other pointer type. | |
331 // | |
332 // Copying is disallowed because you should always use memcpy(). Otherwise, you may run afoul of | |
333 // aliasing rules. | |
334 // | |
335 // A pointer of type word* should always be word-aligned even if won't actually be dereferenced as | |
336 // that type. | |
337 | |
338 static_assert(sizeof(byte) == 1, "uint8_t is not one byte?"); | |
339 static_assert(sizeof(word) == 8, "uint64_t is not 8 bytes?"); | |
340 | |
341 #if CAPNP_DEBUG_TYPES | |
342 // Set CAPNP_DEBUG_TYPES to 1 to use kj::Quantity for "count" types. Otherwise, plain integers are | |
343 // used. All the code should still operate exactly the same, we just lose compile-time checking. | |
344 // Note that this will also change symbol names, so it's important that the library and any clients | |
345 // be compiled with the same setting here. | |
346 // | |
347 // We disable this by default to reduce symbol name size and avoid any possibility of the compiler | |
348 // failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this | |
349 // during development and testing. | |
350 | |
351 namespace _ { class BitLabel; class ElementLabel; struct WirePointer; } | |
352 | |
353 typedef kj::Quantity<uint, _::BitLabel> BitCount; | |
354 typedef kj::Quantity<uint8_t, _::BitLabel> BitCount8; | |
355 typedef kj::Quantity<uint16_t, _::BitLabel> BitCount16; | |
356 typedef kj::Quantity<uint32_t, _::BitLabel> BitCount32; | |
357 typedef kj::Quantity<uint64_t, _::BitLabel> BitCount64; | |
358 | |
359 typedef kj::Quantity<uint, byte> ByteCount; | |
360 typedef kj::Quantity<uint8_t, byte> ByteCount8; | |
361 typedef kj::Quantity<uint16_t, byte> ByteCount16; | |
362 typedef kj::Quantity<uint32_t, byte> ByteCount32; | |
363 typedef kj::Quantity<uint64_t, byte> ByteCount64; | |
364 | |
365 typedef kj::Quantity<uint, word> WordCount; | |
366 typedef kj::Quantity<uint8_t, word> WordCount8; | |
367 typedef kj::Quantity<uint16_t, word> WordCount16; | |
368 typedef kj::Quantity<uint32_t, word> WordCount32; | |
369 typedef kj::Quantity<uint64_t, word> WordCount64; | |
370 | |
371 typedef kj::Quantity<uint, _::ElementLabel> ElementCount; | |
372 typedef kj::Quantity<uint8_t, _::ElementLabel> ElementCount8; | |
373 typedef kj::Quantity<uint16_t, _::ElementLabel> ElementCount16; | |
374 typedef kj::Quantity<uint32_t, _::ElementLabel> ElementCount32; | |
375 typedef kj::Quantity<uint64_t, _::ElementLabel> ElementCount64; | |
376 | |
377 typedef kj::Quantity<uint, _::WirePointer> WirePointerCount; | |
378 typedef kj::Quantity<uint8_t, _::WirePointer> WirePointerCount8; | |
379 typedef kj::Quantity<uint16_t, _::WirePointer> WirePointerCount16; | |
380 typedef kj::Quantity<uint32_t, _::WirePointer> WirePointerCount32; | |
381 typedef kj::Quantity<uint64_t, _::WirePointer> WirePointerCount64; | |
382 | |
383 template <typename T, typename U> | |
384 inline constexpr U* operator+(U* ptr, kj::Quantity<T, U> offset) { | |
385 return ptr + offset / kj::unit<kj::Quantity<T, U>>(); | |
386 } | |
387 template <typename T, typename U> | |
388 inline constexpr const U* operator+(const U* ptr, kj::Quantity<T, U> offset) { | |
389 return ptr + offset / kj::unit<kj::Quantity<T, U>>(); | |
390 } | |
391 template <typename T, typename U> | |
392 inline constexpr U* operator+=(U*& ptr, kj::Quantity<T, U> offset) { | |
393 return ptr = ptr + offset / kj::unit<kj::Quantity<T, U>>(); | |
394 } | |
395 template <typename T, typename U> | |
396 inline constexpr const U* operator+=(const U*& ptr, kj::Quantity<T, U> offset) { | |
397 return ptr = ptr + offset / kj::unit<kj::Quantity<T, U>>(); | |
398 } | |
399 | |
400 template <typename T, typename U> | |
401 inline constexpr U* operator-(U* ptr, kj::Quantity<T, U> offset) { | |
402 return ptr - offset / kj::unit<kj::Quantity<T, U>>(); | |
403 } | |
404 template <typename T, typename U> | |
405 inline constexpr const U* operator-(const U* ptr, kj::Quantity<T, U> offset) { | |
406 return ptr - offset / kj::unit<kj::Quantity<T, U>>(); | |
407 } | |
408 template <typename T, typename U> | |
409 inline constexpr U* operator-=(U*& ptr, kj::Quantity<T, U> offset) { | |
410 return ptr = ptr - offset / kj::unit<kj::Quantity<T, U>>(); | |
411 } | |
412 template <typename T, typename U> | |
413 inline constexpr const U* operator-=(const U*& ptr, kj::Quantity<T, U> offset) { | |
414 return ptr = ptr - offset / kj::unit<kj::Quantity<T, U>>(); | |
415 } | |
416 | |
417 #else | |
418 | |
419 typedef uint BitCount; | |
420 typedef uint8_t BitCount8; | |
421 typedef uint16_t BitCount16; | |
422 typedef uint32_t BitCount32; | |
423 typedef uint64_t BitCount64; | |
424 | |
425 typedef uint ByteCount; | |
426 typedef uint8_t ByteCount8; | |
427 typedef uint16_t ByteCount16; | |
428 typedef uint32_t ByteCount32; | |
429 typedef uint64_t ByteCount64; | |
430 | |
431 typedef uint WordCount; | |
432 typedef uint8_t WordCount8; | |
433 typedef uint16_t WordCount16; | |
434 typedef uint32_t WordCount32; | |
435 typedef uint64_t WordCount64; | |
436 | |
437 typedef uint ElementCount; | |
438 typedef uint8_t ElementCount8; | |
439 typedef uint16_t ElementCount16; | |
440 typedef uint32_t ElementCount32; | |
441 typedef uint64_t ElementCount64; | |
442 | |
443 typedef uint WirePointerCount; | |
444 typedef uint8_t WirePointerCount8; | |
445 typedef uint16_t WirePointerCount16; | |
446 typedef uint32_t WirePointerCount32; | |
447 typedef uint64_t WirePointerCount64; | |
448 | |
449 #endif | |
450 | |
451 constexpr BitCount BITS = kj::unit<BitCount>(); | |
452 constexpr ByteCount BYTES = kj::unit<ByteCount>(); | |
453 constexpr WordCount WORDS = kj::unit<WordCount>(); | |
454 constexpr ElementCount ELEMENTS = kj::unit<ElementCount>(); | |
455 constexpr WirePointerCount POINTERS = kj::unit<WirePointerCount>(); | |
456 | |
457 // GCC 4.7 actually gives unused warnings on these constants in opt mode... | |
458 constexpr auto BITS_PER_BYTE KJ_UNUSED = 8 * BITS / BYTES; | |
459 constexpr auto BITS_PER_WORD KJ_UNUSED = 64 * BITS / WORDS; | |
460 constexpr auto BYTES_PER_WORD KJ_UNUSED = 8 * BYTES / WORDS; | |
461 | |
462 constexpr auto BITS_PER_POINTER KJ_UNUSED = 64 * BITS / POINTERS; | |
463 constexpr auto BYTES_PER_POINTER KJ_UNUSED = 8 * BYTES / POINTERS; | |
464 constexpr auto WORDS_PER_POINTER KJ_UNUSED = 1 * WORDS / POINTERS; | |
465 | |
466 constexpr WordCount POINTER_SIZE_IN_WORDS = 1 * POINTERS * WORDS_PER_POINTER; | |
467 | |
468 template <typename T> | |
469 inline KJ_CONSTEXPR() decltype(BYTES / ELEMENTS) bytesPerElement() { | |
470 return sizeof(T) * BYTES / ELEMENTS; | |
471 } | |
472 | |
473 template <typename T> | |
474 inline KJ_CONSTEXPR() decltype(BITS / ELEMENTS) bitsPerElement() { | |
475 return sizeof(T) * 8 * BITS / ELEMENTS; | |
476 } | |
477 | |
478 inline constexpr ByteCount intervalLength(const byte* a, const byte* b) { | |
479 return uint(b - a) * BYTES; | |
480 } | |
481 inline constexpr WordCount intervalLength(const word* a, const word* b) { | |
482 return uint(b - a) * WORDS; | |
483 } | |
484 | |
485 } // namespace capnp | |
486 | |
487 #endif // CAPNP_COMMON_H_ |