comparison osx/include/capnp/common.h @ 147:45360b968bf4

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 41e769c91eca
children
comparison
equal deleted inserted replaced
146:206f0eb279b8 147:45360b968bf4
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_