Mercurial > hg > sv-dependency-builds
comparison osx/include/capnp/common.h @ 62:0994c39f1e94
Cap'n Proto v0.6 + build for OSX
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Mon, 22 May 2017 10:01:37 +0100 |
parents | 3ab5a40c4e3b |
children |
comparison
equal
deleted
inserted
replaced
61:d101c4099725 | 62:0994c39f1e94 |
---|---|
28 | 28 |
29 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) | 29 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) |
30 #pragma GCC system_header | 30 #pragma GCC system_header |
31 #endif | 31 #endif |
32 | 32 |
33 #include <kj/units.h> | |
34 #include <inttypes.h> | 33 #include <inttypes.h> |
35 #include <kj/string.h> | 34 #include <kj/string.h> |
36 #include <kj/memory.h> | 35 #include <kj/memory.h> |
37 | 36 |
37 #if CAPNP_DEBUG_TYPES | |
38 #include <kj/units.h> | |
39 #endif | |
40 | |
38 namespace capnp { | 41 namespace capnp { |
39 | 42 |
40 #define CAPNP_VERSION_MAJOR 0 | 43 #define CAPNP_VERSION_MAJOR 0 |
41 #define CAPNP_VERSION_MINOR 6 | 44 #define CAPNP_VERSION_MINOR 6 |
42 #define CAPNP_VERSION_MICRO 0 | 45 #define CAPNP_VERSION_MICRO 0 |
43 | 46 |
44 #define CAPNP_VERSION \ | 47 #define CAPNP_VERSION \ |
45 (CAPNP_VERSION_MAJOR * 1000000 + CAPNP_VERSION_MINOR * 1000 + CAPNP_VERSION_MICRO) | 48 (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 | 49 |
52 #ifndef CAPNP_LITE | 50 #ifndef CAPNP_LITE |
53 #define CAPNP_LITE 0 | 51 #define CAPNP_LITE 0 |
54 #endif | 52 #endif |
55 | 53 |
348 // failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this | 346 // failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this |
349 // during development and testing. | 347 // during development and testing. |
350 | 348 |
351 namespace _ { class BitLabel; class ElementLabel; struct WirePointer; } | 349 namespace _ { class BitLabel; class ElementLabel; struct WirePointer; } |
352 | 350 |
353 typedef kj::Quantity<uint, _::BitLabel> BitCount; | 351 template <uint width, typename T = uint> |
354 typedef kj::Quantity<uint8_t, _::BitLabel> BitCount8; | 352 using BitCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::BitLabel>; |
355 typedef kj::Quantity<uint16_t, _::BitLabel> BitCount16; | 353 template <uint width, typename T = uint> |
356 typedef kj::Quantity<uint32_t, _::BitLabel> BitCount32; | 354 using ByteCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, byte>; |
357 typedef kj::Quantity<uint64_t, _::BitLabel> BitCount64; | 355 template <uint width, typename T = uint> |
358 | 356 using WordCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, word>; |
359 typedef kj::Quantity<uint, byte> ByteCount; | 357 template <uint width, typename T = uint> |
360 typedef kj::Quantity<uint8_t, byte> ByteCount8; | 358 using ElementCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::ElementLabel>; |
361 typedef kj::Quantity<uint16_t, byte> ByteCount16; | 359 template <uint width, typename T = uint> |
362 typedef kj::Quantity<uint32_t, byte> ByteCount32; | 360 using WirePointerCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::WirePointer>; |
363 typedef kj::Quantity<uint64_t, byte> ByteCount64; | 361 |
364 | 362 typedef BitCountN<8, uint8_t> BitCount8; |
365 typedef kj::Quantity<uint, word> WordCount; | 363 typedef BitCountN<16, uint16_t> BitCount16; |
366 typedef kj::Quantity<uint8_t, word> WordCount8; | 364 typedef BitCountN<32, uint32_t> BitCount32; |
367 typedef kj::Quantity<uint16_t, word> WordCount16; | 365 typedef BitCountN<64, uint64_t> BitCount64; |
368 typedef kj::Quantity<uint32_t, word> WordCount32; | 366 typedef BitCountN<sizeof(uint) * 8, uint> BitCount; |
369 typedef kj::Quantity<uint64_t, word> WordCount64; | 367 |
370 | 368 typedef ByteCountN<8, uint8_t> ByteCount8; |
371 typedef kj::Quantity<uint, _::ElementLabel> ElementCount; | 369 typedef ByteCountN<16, uint16_t> ByteCount16; |
372 typedef kj::Quantity<uint8_t, _::ElementLabel> ElementCount8; | 370 typedef ByteCountN<32, uint32_t> ByteCount32; |
373 typedef kj::Quantity<uint16_t, _::ElementLabel> ElementCount16; | 371 typedef ByteCountN<64, uint64_t> ByteCount64; |
374 typedef kj::Quantity<uint32_t, _::ElementLabel> ElementCount32; | 372 typedef ByteCountN<sizeof(uint) * 8, uint> ByteCount; |
375 typedef kj::Quantity<uint64_t, _::ElementLabel> ElementCount64; | 373 |
376 | 374 typedef WordCountN<8, uint8_t> WordCount8; |
377 typedef kj::Quantity<uint, _::WirePointer> WirePointerCount; | 375 typedef WordCountN<16, uint16_t> WordCount16; |
378 typedef kj::Quantity<uint8_t, _::WirePointer> WirePointerCount8; | 376 typedef WordCountN<32, uint32_t> WordCount32; |
379 typedef kj::Quantity<uint16_t, _::WirePointer> WirePointerCount16; | 377 typedef WordCountN<64, uint64_t> WordCount64; |
380 typedef kj::Quantity<uint32_t, _::WirePointer> WirePointerCount32; | 378 typedef WordCountN<sizeof(uint) * 8, uint> WordCount; |
381 typedef kj::Quantity<uint64_t, _::WirePointer> WirePointerCount64; | 379 |
380 typedef ElementCountN<8, uint8_t> ElementCount8; | |
381 typedef ElementCountN<16, uint16_t> ElementCount16; | |
382 typedef ElementCountN<32, uint32_t> ElementCount32; | |
383 typedef ElementCountN<64, uint64_t> ElementCount64; | |
384 typedef ElementCountN<sizeof(uint) * 8, uint> ElementCount; | |
385 | |
386 typedef WirePointerCountN<8, uint8_t> WirePointerCount8; | |
387 typedef WirePointerCountN<16, uint16_t> WirePointerCount16; | |
388 typedef WirePointerCountN<32, uint32_t> WirePointerCount32; | |
389 typedef WirePointerCountN<64, uint64_t> WirePointerCount64; | |
390 typedef WirePointerCountN<sizeof(uint) * 8, uint> WirePointerCount; | |
391 | |
392 template <uint width> | |
393 using BitsPerElementN = decltype(BitCountN<width>() / ElementCountN<width>()); | |
394 template <uint width> | |
395 using BytesPerElementN = decltype(ByteCountN<width>() / ElementCountN<width>()); | |
396 template <uint width> | |
397 using WordsPerElementN = decltype(WordCountN<width>() / ElementCountN<width>()); | |
398 template <uint width> | |
399 using PointersPerElementN = decltype(WirePointerCountN<width>() / ElementCountN<width>()); | |
400 | |
401 using kj::bounded; | |
402 using kj::unbound; | |
403 using kj::unboundAs; | |
404 using kj::unboundMax; | |
405 using kj::unboundMaxBits; | |
406 using kj::assertMax; | |
407 using kj::assertMaxBits; | |
408 using kj::upgradeBound; | |
409 using kj::ThrowOverflow; | |
410 using kj::assumeBits; | |
411 using kj::assumeMax; | |
412 using kj::subtractChecked; | |
413 using kj::trySubtract; | |
382 | 414 |
383 template <typename T, typename U> | 415 template <typename T, typename U> |
384 inline constexpr U* operator+(U* ptr, kj::Quantity<T, U> offset) { | 416 inline constexpr U* operator+(U* ptr, kj::Quantity<T, U> offset) { |
385 return ptr + offset / kj::unit<kj::Quantity<T, U>>(); | 417 return ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>()); |
386 } | 418 } |
387 template <typename T, typename U> | 419 template <typename T, typename U> |
388 inline constexpr const U* operator+(const U* ptr, kj::Quantity<T, U> offset) { | 420 inline constexpr const U* operator+(const U* ptr, kj::Quantity<T, U> offset) { |
389 return ptr + offset / kj::unit<kj::Quantity<T, U>>(); | 421 return ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>()); |
390 } | 422 } |
391 template <typename T, typename U> | 423 template <typename T, typename U> |
392 inline constexpr U* operator+=(U*& ptr, kj::Quantity<T, U> offset) { | 424 inline constexpr U* operator+=(U*& ptr, kj::Quantity<T, U> offset) { |
393 return ptr = ptr + offset / kj::unit<kj::Quantity<T, U>>(); | 425 return ptr = ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>()); |
394 } | 426 } |
395 template <typename T, typename U> | 427 template <typename T, typename U> |
396 inline constexpr const U* operator+=(const U*& ptr, kj::Quantity<T, U> offset) { | 428 inline constexpr const U* operator+=(const U*& ptr, kj::Quantity<T, U> offset) { |
397 return ptr = ptr + offset / kj::unit<kj::Quantity<T, U>>(); | 429 return ptr = ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>()); |
398 } | 430 } |
399 | 431 |
400 template <typename T, typename U> | 432 template <typename T, typename U> |
401 inline constexpr U* operator-(U* ptr, kj::Quantity<T, U> offset) { | 433 inline constexpr U* operator-(U* ptr, kj::Quantity<T, U> offset) { |
402 return ptr - offset / kj::unit<kj::Quantity<T, U>>(); | 434 return ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>()); |
403 } | 435 } |
404 template <typename T, typename U> | 436 template <typename T, typename U> |
405 inline constexpr const U* operator-(const U* ptr, kj::Quantity<T, U> offset) { | 437 inline constexpr const U* operator-(const U* ptr, kj::Quantity<T, U> offset) { |
406 return ptr - offset / kj::unit<kj::Quantity<T, U>>(); | 438 return ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>()); |
407 } | 439 } |
408 template <typename T, typename U> | 440 template <typename T, typename U> |
409 inline constexpr U* operator-=(U*& ptr, kj::Quantity<T, U> offset) { | 441 inline constexpr U* operator-=(U*& ptr, kj::Quantity<T, U> offset) { |
410 return ptr = ptr - offset / kj::unit<kj::Quantity<T, U>>(); | 442 return ptr = ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>()); |
411 } | 443 } |
412 template <typename T, typename U> | 444 template <typename T, typename U> |
413 inline constexpr const U* operator-=(const U*& ptr, kj::Quantity<T, U> offset) { | 445 inline constexpr const U* operator-=(const U*& ptr, kj::Quantity<T, U> offset) { |
414 return ptr = ptr - offset / kj::unit<kj::Quantity<T, U>>(); | 446 return ptr = ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>()); |
447 } | |
448 | |
449 constexpr auto BITS = kj::unit<BitCountN<1>>(); | |
450 constexpr auto BYTES = kj::unit<ByteCountN<1>>(); | |
451 constexpr auto WORDS = kj::unit<WordCountN<1>>(); | |
452 constexpr auto ELEMENTS = kj::unit<ElementCountN<1>>(); | |
453 constexpr auto POINTERS = kj::unit<WirePointerCountN<1>>(); | |
454 | |
455 constexpr auto ZERO = kj::bounded<0>(); | |
456 constexpr auto ONE = kj::bounded<1>(); | |
457 | |
458 // GCC 4.7 actually gives unused warnings on these constants in opt mode... | |
459 constexpr auto BITS_PER_BYTE KJ_UNUSED = bounded<8>() * BITS / BYTES; | |
460 constexpr auto BITS_PER_WORD KJ_UNUSED = bounded<64>() * BITS / WORDS; | |
461 constexpr auto BYTES_PER_WORD KJ_UNUSED = bounded<8>() * BYTES / WORDS; | |
462 | |
463 constexpr auto BITS_PER_POINTER KJ_UNUSED = bounded<64>() * BITS / POINTERS; | |
464 constexpr auto BYTES_PER_POINTER KJ_UNUSED = bounded<8>() * BYTES / POINTERS; | |
465 constexpr auto WORDS_PER_POINTER KJ_UNUSED = ONE * WORDS / POINTERS; | |
466 | |
467 constexpr auto POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER; | |
468 | |
469 constexpr uint SEGMENT_WORD_COUNT_BITS = 29; // Number of words in a segment. | |
470 constexpr uint LIST_ELEMENT_COUNT_BITS = 29; // Number of elements in a list. | |
471 constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16; // Number of words in a Struct data section. | |
472 constexpr uint STRUCT_POINTER_COUNT_BITS = 16; // Number of pointers in a Struct pointer section. | |
473 constexpr uint BLOB_SIZE_BITS = 29; // Number of bytes in a blob. | |
474 | |
475 typedef WordCountN<SEGMENT_WORD_COUNT_BITS> SegmentWordCount; | |
476 typedef ElementCountN<LIST_ELEMENT_COUNT_BITS> ListElementCount; | |
477 typedef WordCountN<STRUCT_DATA_WORD_COUNT_BITS, uint16_t> StructDataWordCount; | |
478 typedef WirePointerCountN<STRUCT_POINTER_COUNT_BITS, uint16_t> StructPointerCount; | |
479 typedef ByteCountN<BLOB_SIZE_BITS> BlobSize; | |
480 | |
481 constexpr auto MAX_SEGMENT_WORDS = | |
482 bounded<kj::maxValueForBits<SEGMENT_WORD_COUNT_BITS>()>() * WORDS; | |
483 constexpr auto MAX_LIST_ELEMENTS = | |
484 bounded<kj::maxValueForBits<LIST_ELEMENT_COUNT_BITS>()>() * ELEMENTS; | |
485 constexpr auto MAX_STUCT_DATA_WORDS = | |
486 bounded<kj::maxValueForBits<STRUCT_DATA_WORD_COUNT_BITS>()>() * WORDS; | |
487 constexpr auto MAX_STRUCT_POINTER_COUNT = | |
488 bounded<kj::maxValueForBits<STRUCT_POINTER_COUNT_BITS>()>() * POINTERS; | |
489 | |
490 using StructDataBitCount = decltype(WordCountN<STRUCT_POINTER_COUNT_BITS>() * BITS_PER_WORD); | |
491 // Number of bits in a Struct data segment (should come out to BitCountN<22>). | |
492 | |
493 using StructDataOffset = decltype(StructDataBitCount() * (ONE * ELEMENTS / BITS)); | |
494 using StructPointerOffset = StructPointerCount; | |
495 // Type of a field offset. | |
496 | |
497 inline StructDataOffset assumeDataOffset(uint32_t offset) { | |
498 return assumeMax(MAX_STUCT_DATA_WORDS * BITS_PER_WORD * (ONE * ELEMENTS / BITS), | |
499 bounded(offset) * ELEMENTS); | |
500 } | |
501 | |
502 inline StructPointerOffset assumePointerOffset(uint32_t offset) { | |
503 return assumeMax(MAX_STRUCT_POINTER_COUNT, bounded(offset) * POINTERS); | |
504 } | |
505 | |
506 constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits<BLOB_SIZE_BITS>() - 1; | |
507 typedef kj::Quantity<kj::Bounded<MAX_TEXT_SIZE, uint>, byte> TextSize; | |
508 // Not including NUL terminator. | |
509 | |
510 template <typename T> | |
511 inline KJ_CONSTEXPR() decltype(bounded<sizeof(T)>() * BYTES / ELEMENTS) bytesPerElement() { | |
512 return bounded<sizeof(T)>() * BYTES / ELEMENTS; | |
513 } | |
514 | |
515 template <typename T> | |
516 inline KJ_CONSTEXPR() decltype(bounded<sizeof(T) * 8>() * BITS / ELEMENTS) bitsPerElement() { | |
517 return bounded<sizeof(T) * 8>() * BITS / ELEMENTS; | |
518 } | |
519 | |
520 template <typename T, uint maxN> | |
521 inline constexpr kj::Quantity<kj::Bounded<maxN, size_t>, T> | |
522 intervalLength(const T* a, const T* b, kj::Quantity<kj::BoundedConst<maxN>, T>) { | |
523 return kj::assumeMax<maxN>(b - a) * kj::unit<kj::Quantity<kj::BoundedConst<1u>, T>>(); | |
524 } | |
525 | |
526 template <typename T, typename U> | |
527 inline constexpr kj::ArrayPtr<const U> arrayPtr(const U* ptr, kj::Quantity<T, U> size) { | |
528 return kj::ArrayPtr<const U>(ptr, unbound(size / kj::unit<kj::Quantity<T, U>>())); | |
529 } | |
530 template <typename T, typename U> | |
531 inline constexpr kj::ArrayPtr<U> arrayPtr(U* ptr, kj::Quantity<T, U> size) { | |
532 return kj::ArrayPtr<U>(ptr, unbound(size / kj::unit<kj::Quantity<T, U>>())); | |
415 } | 533 } |
416 | 534 |
417 #else | 535 #else |
418 | 536 |
419 typedef uint BitCount; | 537 template <uint width, typename T = uint> |
420 typedef uint8_t BitCount8; | 538 using BitCountN = T; |
421 typedef uint16_t BitCount16; | 539 template <uint width, typename T = uint> |
422 typedef uint32_t BitCount32; | 540 using ByteCountN = T; |
423 typedef uint64_t BitCount64; | 541 template <uint width, typename T = uint> |
424 | 542 using WordCountN = T; |
425 typedef uint ByteCount; | 543 template <uint width, typename T = uint> |
426 typedef uint8_t ByteCount8; | 544 using ElementCountN = T; |
427 typedef uint16_t ByteCount16; | 545 template <uint width, typename T = uint> |
428 typedef uint32_t ByteCount32; | 546 using WirePointerCountN = T; |
429 typedef uint64_t ByteCount64; | 547 |
430 | 548 |
431 typedef uint WordCount; | 549 // XXX |
432 typedef uint8_t WordCount8; | 550 typedef BitCountN<8, uint8_t> BitCount8; |
433 typedef uint16_t WordCount16; | 551 typedef BitCountN<16, uint16_t> BitCount16; |
434 typedef uint32_t WordCount32; | 552 typedef BitCountN<32, uint32_t> BitCount32; |
435 typedef uint64_t WordCount64; | 553 typedef BitCountN<64, uint64_t> BitCount64; |
436 | 554 typedef BitCountN<sizeof(uint) * 8, uint> BitCount; |
437 typedef uint ElementCount; | 555 |
438 typedef uint8_t ElementCount8; | 556 typedef ByteCountN<8, uint8_t> ByteCount8; |
439 typedef uint16_t ElementCount16; | 557 typedef ByteCountN<16, uint16_t> ByteCount16; |
440 typedef uint32_t ElementCount32; | 558 typedef ByteCountN<32, uint32_t> ByteCount32; |
441 typedef uint64_t ElementCount64; | 559 typedef ByteCountN<64, uint64_t> ByteCount64; |
442 | 560 typedef ByteCountN<sizeof(uint) * 8, uint> ByteCount; |
443 typedef uint WirePointerCount; | 561 |
444 typedef uint8_t WirePointerCount8; | 562 typedef WordCountN<8, uint8_t> WordCount8; |
445 typedef uint16_t WirePointerCount16; | 563 typedef WordCountN<16, uint16_t> WordCount16; |
446 typedef uint32_t WirePointerCount32; | 564 typedef WordCountN<32, uint32_t> WordCount32; |
447 typedef uint64_t WirePointerCount64; | 565 typedef WordCountN<64, uint64_t> WordCount64; |
566 typedef WordCountN<sizeof(uint) * 8, uint> WordCount; | |
567 | |
568 typedef ElementCountN<8, uint8_t> ElementCount8; | |
569 typedef ElementCountN<16, uint16_t> ElementCount16; | |
570 typedef ElementCountN<32, uint32_t> ElementCount32; | |
571 typedef ElementCountN<64, uint64_t> ElementCount64; | |
572 typedef ElementCountN<sizeof(uint) * 8, uint> ElementCount; | |
573 | |
574 typedef WirePointerCountN<8, uint8_t> WirePointerCount8; | |
575 typedef WirePointerCountN<16, uint16_t> WirePointerCount16; | |
576 typedef WirePointerCountN<32, uint32_t> WirePointerCount32; | |
577 typedef WirePointerCountN<64, uint64_t> WirePointerCount64; | |
578 typedef WirePointerCountN<sizeof(uint) * 8, uint> WirePointerCount; | |
579 | |
580 template <uint width> | |
581 using BitsPerElementN = decltype(BitCountN<width>() / ElementCountN<width>()); | |
582 template <uint width> | |
583 using BytesPerElementN = decltype(ByteCountN<width>() / ElementCountN<width>()); | |
584 template <uint width> | |
585 using WordsPerElementN = decltype(WordCountN<width>() / ElementCountN<width>()); | |
586 template <uint width> | |
587 using PointersPerElementN = decltype(WirePointerCountN<width>() / ElementCountN<width>()); | |
588 | |
589 using kj::ThrowOverflow; | |
590 // YYY | |
591 | |
592 template <uint i> inline constexpr uint bounded() { return i; } | |
593 template <typename T> inline constexpr T bounded(T i) { return i; } | |
594 template <typename T> inline constexpr T unbound(T i) { return i; } | |
595 | |
596 template <typename T, typename U> inline constexpr T unboundAs(U i) { return i; } | |
597 | |
598 template <uint64_t requestedMax, typename T> inline constexpr uint unboundMax(T i) { return i; } | |
599 template <uint bits, typename T> inline constexpr uint unboundMaxBits(T i) { return i; } | |
600 | |
601 template <uint newMax, typename T, typename ErrorFunc> | |
602 inline T assertMax(T value, ErrorFunc&& func) { | |
603 if (KJ_UNLIKELY(value > newMax)) func(); | |
604 return value; | |
605 } | |
606 | |
607 template <typename T, typename ErrorFunc> | |
608 inline T assertMax(uint newMax, T value, ErrorFunc&& func) { | |
609 if (KJ_UNLIKELY(value > newMax)) func(); | |
610 return value; | |
611 } | |
612 | |
613 template <uint bits, typename T, typename ErrorFunc = ThrowOverflow> | |
614 inline T assertMaxBits(T value, ErrorFunc&& func = ErrorFunc()) { | |
615 if (KJ_UNLIKELY(value > kj::maxValueForBits<bits>())) func(); | |
616 return value; | |
617 } | |
618 | |
619 template <typename T, typename ErrorFunc = ThrowOverflow> | |
620 inline T assertMaxBits(uint bits, T value, ErrorFunc&& func = ErrorFunc()) { | |
621 if (KJ_UNLIKELY(value > (1ull << bits) - 1)) func(); | |
622 return value; | |
623 } | |
624 | |
625 template <typename T, typename U> inline constexpr T upgradeBound(U i) { return i; } | |
626 | |
627 template <uint bits, typename T> inline constexpr T assumeBits(T i) { return i; } | |
628 template <uint64_t max, typename T> inline constexpr T assumeMax(T i) { return i; } | |
629 | |
630 template <typename T, typename U, typename ErrorFunc = ThrowOverflow> | |
631 inline auto subtractChecked(T a, U b, ErrorFunc&& errorFunc = ErrorFunc()) | |
632 -> decltype(a - b) { | |
633 if (b > a) errorFunc(); | |
634 return a - b; | |
635 } | |
636 | |
637 template <typename T, typename U> | |
638 inline auto trySubtract(T a, U b) -> kj::Maybe<decltype(a - b)> { | |
639 if (b > a) { | |
640 return nullptr; | |
641 } else { | |
642 return a - b; | |
643 } | |
644 } | |
645 | |
646 constexpr uint BITS = 1; | |
647 constexpr uint BYTES = 1; | |
648 constexpr uint WORDS = 1; | |
649 constexpr uint ELEMENTS = 1; | |
650 constexpr uint POINTERS = 1; | |
651 | |
652 constexpr uint ZERO = 0; | |
653 constexpr uint ONE = 1; | |
654 | |
655 // GCC 4.7 actually gives unused warnings on these constants in opt mode... | |
656 constexpr uint BITS_PER_BYTE KJ_UNUSED = 8; | |
657 constexpr uint BITS_PER_WORD KJ_UNUSED = 64; | |
658 constexpr uint BYTES_PER_WORD KJ_UNUSED = 8; | |
659 | |
660 constexpr uint BITS_PER_POINTER KJ_UNUSED = 64; | |
661 constexpr uint BYTES_PER_POINTER KJ_UNUSED = 8; | |
662 constexpr uint WORDS_PER_POINTER KJ_UNUSED = 1; | |
663 | |
664 // XXX | |
665 constexpr uint POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER; | |
666 | |
667 constexpr uint SEGMENT_WORD_COUNT_BITS = 29; // Number of words in a segment. | |
668 constexpr uint LIST_ELEMENT_COUNT_BITS = 29; // Number of elements in a list. | |
669 constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16; // Number of words in a Struct data section. | |
670 constexpr uint STRUCT_POINTER_COUNT_BITS = 16; // Number of pointers in a Struct pointer section. | |
671 constexpr uint BLOB_SIZE_BITS = 29; // Number of bytes in a blob. | |
672 | |
673 typedef WordCountN<SEGMENT_WORD_COUNT_BITS> SegmentWordCount; | |
674 typedef ElementCountN<LIST_ELEMENT_COUNT_BITS> ListElementCount; | |
675 typedef WordCountN<STRUCT_DATA_WORD_COUNT_BITS, uint16_t> StructDataWordCount; | |
676 typedef WirePointerCountN<STRUCT_POINTER_COUNT_BITS, uint16_t> StructPointerCount; | |
677 typedef ByteCountN<BLOB_SIZE_BITS> BlobSize; | |
678 // YYY | |
679 | |
680 constexpr auto MAX_SEGMENT_WORDS = kj::maxValueForBits<SEGMENT_WORD_COUNT_BITS>(); | |
681 constexpr auto MAX_LIST_ELEMENTS = kj::maxValueForBits<LIST_ELEMENT_COUNT_BITS>(); | |
682 constexpr auto MAX_STUCT_DATA_WORDS = kj::maxValueForBits<STRUCT_DATA_WORD_COUNT_BITS>(); | |
683 constexpr auto MAX_STRUCT_POINTER_COUNT = kj::maxValueForBits<STRUCT_POINTER_COUNT_BITS>(); | |
684 | |
685 typedef uint StructDataBitCount; | |
686 typedef uint StructDataOffset; | |
687 typedef uint StructPointerOffset; | |
688 | |
689 inline StructDataOffset assumeDataOffset(uint32_t offset) { return offset; } | |
690 inline StructPointerOffset assumePointerOffset(uint32_t offset) { return offset; } | |
691 | |
692 constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits<BLOB_SIZE_BITS>() - 1; | |
693 typedef uint TextSize; | |
694 | |
695 template <typename T> | |
696 inline KJ_CONSTEXPR() size_t bytesPerElement() { return sizeof(T); } | |
697 | |
698 template <typename T> | |
699 inline KJ_CONSTEXPR() size_t bitsPerElement() { return sizeof(T) * 8; } | |
700 | |
701 template <typename T> | |
702 inline constexpr ptrdiff_t intervalLength(const T* a, const T* b, uint) { | |
703 return b - a; | |
704 } | |
705 | |
706 template <typename T, typename U> | |
707 inline constexpr kj::ArrayPtr<const U> arrayPtr(const U* ptr, T size) { | |
708 return kj::arrayPtr(ptr, size); | |
709 } | |
710 template <typename T, typename U> | |
711 inline constexpr kj::ArrayPtr<U> arrayPtr(U* ptr, T size) { | |
712 return kj::arrayPtr(ptr, size); | |
713 } | |
448 | 714 |
449 #endif | 715 #endif |
450 | 716 |
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 | 717 } // namespace capnp |
486 | 718 |
487 #endif // CAPNP_COMMON_H_ | 719 #endif // CAPNP_COMMON_H_ |