annotate win32-mingw/include/capnp/common.h @ 79:91c729825bca pa_catalina

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