annotate win32-mingw/include/capnp/common.h @ 141:1b5b6dfd0d0e

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