annotate win64-msvc/include/capnp/common.h @ 47:d93140aac40b

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