diff 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
line wrap: on
line diff
--- a/osx/include/capnp/common.h	Mon Mar 06 13:29:58 2017 +0000
+++ b/osx/include/capnp/common.h	Mon May 22 10:01:37 2017 +0100
@@ -1,487 +1,719 @@
-// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
-// Licensed under the MIT License:
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// This file contains types which are intended to help detect incorrect usage at compile
-// time, but should then be optimized down to basic primitives (usually, integers) by the
-// compiler.
-
-#ifndef CAPNP_COMMON_H_
-#define CAPNP_COMMON_H_
-
-#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
-#pragma GCC system_header
-#endif
-
-#include <kj/units.h>
-#include <inttypes.h>
-#include <kj/string.h>
-#include <kj/memory.h>
-
-namespace capnp {
-
-#define CAPNP_VERSION_MAJOR 0
-#define CAPNP_VERSION_MINOR 6
-#define CAPNP_VERSION_MICRO 0
-
-#define CAPNP_VERSION \
-  (CAPNP_VERSION_MAJOR * 1000000 + CAPNP_VERSION_MINOR * 1000 + CAPNP_VERSION_MICRO)
-
-#ifdef _MSC_VER
-#define CAPNP_LITE 1
-// MSVC only supports "lite" mode for now, due to missing C++11 features.
-#endif
-
-#ifndef CAPNP_LITE
-#define CAPNP_LITE 0
-#endif
-
-typedef unsigned int uint;
-
-struct Void {
-  // Type used for Void fields.  Using C++'s "void" type creates a bunch of issues since it behaves
-  // differently from other types.
-
-  inline constexpr bool operator==(Void other) const { return true; }
-  inline constexpr bool operator!=(Void other) const { return false; }
-};
-
-static constexpr Void VOID = Void();
-// Constant value for `Void`,  which is an empty struct.
-
-inline kj::StringPtr KJ_STRINGIFY(Void) { return "void"; }
-
-struct Text;
-struct Data;
-
-enum class Kind: uint8_t {
-  PRIMITIVE,
-  BLOB,
-  ENUM,
-  STRUCT,
-  UNION,
-  INTERFACE,
-  LIST,
-
-  OTHER
-  // Some other type which is often a type parameter to Cap'n Proto templates, but which needs
-  // special handling. This includes types like AnyPointer, Dynamic*, etc.
-};
-
-enum class Style: uint8_t {
-  PRIMITIVE,
-  POINTER,      // other than struct
-  STRUCT,
-  CAPABILITY
-};
-
-enum class ElementSize: uint8_t {
-  // Size of a list element.
-
-  VOID = 0,
-  BIT = 1,
-  BYTE = 2,
-  TWO_BYTES = 3,
-  FOUR_BYTES = 4,
-  EIGHT_BYTES = 5,
-
-  POINTER = 6,
-
-  INLINE_COMPOSITE = 7
-};
-
-enum class PointerType {
-  // Various wire types a pointer field can take
-
-  NULL_,
-  // Should be NULL, but that's #defined in stddef.h
-
-  STRUCT,
-  LIST,
-  CAPABILITY
-};
-
-namespace schemas {
-
-template <typename T>
-struct EnumInfo;
-
-}  // namespace schemas
-
-namespace _ {  // private
-
-template <typename T, typename = void> struct Kind_;
-
-template <> struct Kind_<Void> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<bool> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<int8_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<int16_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<int32_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<int64_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<uint8_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<uint16_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<uint32_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<uint64_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<float> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<double> { static constexpr Kind kind = Kind::PRIMITIVE; };
-template <> struct Kind_<Text> { static constexpr Kind kind = Kind::BLOB; };
-template <> struct Kind_<Data> { static constexpr Kind kind = Kind::BLOB; };
-
-template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsStruct>> {
-  static constexpr Kind kind = Kind::STRUCT;
-};
-template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsInterface>> {
-  static constexpr Kind kind = Kind::INTERFACE;
-};
-template <typename T> struct Kind_<T, kj::VoidSfinae<typename schemas::EnumInfo<T>::IsEnum>> {
-  static constexpr Kind kind = Kind::ENUM;
-};
-
-}  // namespace _ (private)
-
-template <typename T, Kind k = _::Kind_<T>::kind>
-inline constexpr Kind kind() {
-  // This overload of kind() matches types which have a Kind_ specialization.
-
-  return k;
-}
-
-#if CAPNP_LITE
-
-#define CAPNP_KIND(T) ::capnp::_::Kind_<T>::kind
-// Avoid constexpr methods in lite mode (MSVC is bad at constexpr).
-
-#else  // CAPNP_LITE
-
-#define CAPNP_KIND(T) ::capnp::kind<T>()
-// Use this macro rather than kind<T>() in any code which must work in lite mode.
-
-template <typename T, Kind k = kind<T>()>
-inline constexpr Style style() {
-  return k == Kind::PRIMITIVE || k == Kind::ENUM ? Style::PRIMITIVE
-       : k == Kind::STRUCT ? Style::STRUCT
-       : k == Kind::INTERFACE ? Style::CAPABILITY : Style::POINTER;
-}
-
-#endif  // CAPNP_LITE, else
-
-template <typename T, Kind k = CAPNP_KIND(T)>
-struct List;
-
-#if _MSC_VER
-
-template <typename T, Kind k>
-struct List {};
-// For some reason, without this declaration, MSVC will error out on some uses of List
-// claiming that "T" -- as used in the default initializer for the second template param, "k" --
-// is not defined. I do not understand this error, but adding this empty default declaration fixes
-// it.
-
-#endif
-
-template <typename T> struct ListElementType_;
-template <typename T> struct ListElementType_<List<T>> { typedef T Type; };
-template <typename T> using ListElementType = typename ListElementType_<T>::Type;
-
-namespace _ {  // private
-template <typename T, Kind k> struct Kind_<List<T, k>> {
-  static constexpr Kind kind = Kind::LIST;
-};
-}  // namespace _ (private)
-
-template <typename T, Kind k = CAPNP_KIND(T)> struct ReaderFor_ { typedef typename T::Reader Type; };
-template <typename T> struct ReaderFor_<T, Kind::PRIMITIVE> { typedef T Type; };
-template <typename T> struct ReaderFor_<T, Kind::ENUM> { typedef T Type; };
-template <typename T> struct ReaderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
-template <typename T> using ReaderFor = typename ReaderFor_<T>::Type;
-// The type returned by List<T>::Reader::operator[].
-
-template <typename T, Kind k = CAPNP_KIND(T)> struct BuilderFor_ { typedef typename T::Builder Type; };
-template <typename T> struct BuilderFor_<T, Kind::PRIMITIVE> { typedef T Type; };
-template <typename T> struct BuilderFor_<T, Kind::ENUM> { typedef T Type; };
-template <typename T> struct BuilderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
-template <typename T> using BuilderFor = typename BuilderFor_<T>::Type;
-// The type returned by List<T>::Builder::operator[].
-
-template <typename T, Kind k = CAPNP_KIND(T)> struct PipelineFor_ { typedef typename T::Pipeline Type;};
-template <typename T> struct PipelineFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
-template <typename T> using PipelineFor = typename PipelineFor_<T>::Type;
-
-template <typename T, Kind k = CAPNP_KIND(T)> struct TypeIfEnum_;
-template <typename T> struct TypeIfEnum_<T, Kind::ENUM> { typedef T Type; };
-
-template <typename T>
-using TypeIfEnum = typename TypeIfEnum_<kj::Decay<T>>::Type;
-
-template <typename T>
-using FromReader = typename kj::Decay<T>::Reads;
-// FromReader<MyType::Reader> = MyType (for any Cap'n Proto type).
-
-template <typename T>
-using FromBuilder = typename kj::Decay<T>::Builds;
-// FromBuilder<MyType::Builder> = MyType (for any Cap'n Proto type).
-
-template <typename T>
-using FromPipeline = typename kj::Decay<T>::Pipelines;
-// FromBuilder<MyType::Pipeline> = MyType (for any Cap'n Proto type).
-
-template <typename T>
-using FromClient = typename kj::Decay<T>::Calls;
-// FromReader<MyType::Client> = MyType (for any Cap'n Proto interface type).
-
-template <typename T>
-using FromServer = typename kj::Decay<T>::Serves;
-// FromBuilder<MyType::Server> = MyType (for any Cap'n Proto interface type).
-
-template <typename T, typename = void>
-struct FromAny_;
-
-template <typename T>
-struct FromAny_<T, kj::VoidSfinae<FromReader<T>>> {
-  using Type = FromReader<T>;
-};
-
-template <typename T>
-struct FromAny_<T, kj::VoidSfinae<FromBuilder<T>>> {
-  using Type = FromBuilder<T>;
-};
-
-template <typename T>
-struct FromAny_<T, kj::VoidSfinae<FromPipeline<T>>> {
-  using Type = FromPipeline<T>;
-};
-
-// Note that T::Client is covered by FromReader
-
-template <typename T>
-struct FromAny_<kj::Own<T>, kj::VoidSfinae<FromServer<T>>> {
-  using Type = FromServer<T>;
-};
-
-template <typename T>
-struct FromAny_<T,
-    kj::EnableIf<_::Kind_<T>::kind == Kind::PRIMITIVE || _::Kind_<T>::kind == Kind::ENUM>> {
-  // TODO(msvc): Ideally the EnableIf condition would be `style<T>() == Style::PRIMITIVE`, but MSVC
-  // cannot yet use style<T>() in this constexpr context.
-
-  using Type = kj::Decay<T>;
-};
-
-template <typename T>
-using FromAny = typename FromAny_<T>::Type;
-// Given any Cap'n Proto value type as an input, return the Cap'n Proto base type. That is:
-//
-//     Foo::Reader -> Foo
-//     Foo::Builder -> Foo
-//     Foo::Pipeline -> Foo
-//     Foo::Client -> Foo
-//     Own<Foo::Server> -> Foo
-//     uint32_t -> uint32_t
-
-namespace _ {  // private
-
-template <typename T, Kind k = CAPNP_KIND(T)>
-struct PointerHelpers;
-
-#if _MSC_VER
-
-template <typename T, Kind k>
-struct PointerHelpers {};
-// For some reason, without this declaration, MSVC will error out on some uses of PointerHelpers
-// claiming that "T" -- as used in the default initializer for the second template param, "k" --
-// is not defined. I do not understand this error, but adding this empty default declaration fixes
-// it.
-
-#endif
-
-}  // namespace _ (private)
-
-struct MessageSize {
-  // Size of a message.  Every struct type has a method `.totalSize()` that returns this.
-  uint64_t wordCount;
-  uint capCount;
-};
-
-// =======================================================================================
-// Raw memory types and measures
-
-using kj::byte;
-
-class word { uint64_t content KJ_UNUSED_MEMBER; KJ_DISALLOW_COPY(word); public: word() = default; };
-// word is an opaque type with size of 64 bits.  This type is useful only to make pointer
-// arithmetic clearer.  Since the contents are private, the only way to access them is to first
-// reinterpret_cast to some other pointer type.
-//
-// Copying is disallowed because you should always use memcpy().  Otherwise, you may run afoul of
-// aliasing rules.
-//
-// A pointer of type word* should always be word-aligned even if won't actually be dereferenced as
-// that type.
-
-static_assert(sizeof(byte) == 1, "uint8_t is not one byte?");
-static_assert(sizeof(word) == 8, "uint64_t is not 8 bytes?");
-
-#if CAPNP_DEBUG_TYPES
-// Set CAPNP_DEBUG_TYPES to 1 to use kj::Quantity for "count" types.  Otherwise, plain integers are
-// used.  All the code should still operate exactly the same, we just lose compile-time checking.
-// Note that this will also change symbol names, so it's important that the library and any clients
-// be compiled with the same setting here.
-//
-// We disable this by default to reduce symbol name size and avoid any possibility of the compiler
-// failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this
-// during development and testing.
-
-namespace _ { class BitLabel; class ElementLabel; struct WirePointer; }
-
-typedef kj::Quantity<uint, _::BitLabel> BitCount;
-typedef kj::Quantity<uint8_t, _::BitLabel> BitCount8;
-typedef kj::Quantity<uint16_t, _::BitLabel> BitCount16;
-typedef kj::Quantity<uint32_t, _::BitLabel> BitCount32;
-typedef kj::Quantity<uint64_t, _::BitLabel> BitCount64;
-
-typedef kj::Quantity<uint, byte> ByteCount;
-typedef kj::Quantity<uint8_t, byte> ByteCount8;
-typedef kj::Quantity<uint16_t, byte> ByteCount16;
-typedef kj::Quantity<uint32_t, byte> ByteCount32;
-typedef kj::Quantity<uint64_t, byte> ByteCount64;
-
-typedef kj::Quantity<uint, word> WordCount;
-typedef kj::Quantity<uint8_t, word> WordCount8;
-typedef kj::Quantity<uint16_t, word> WordCount16;
-typedef kj::Quantity<uint32_t, word> WordCount32;
-typedef kj::Quantity<uint64_t, word> WordCount64;
-
-typedef kj::Quantity<uint, _::ElementLabel> ElementCount;
-typedef kj::Quantity<uint8_t, _::ElementLabel> ElementCount8;
-typedef kj::Quantity<uint16_t, _::ElementLabel> ElementCount16;
-typedef kj::Quantity<uint32_t, _::ElementLabel> ElementCount32;
-typedef kj::Quantity<uint64_t, _::ElementLabel> ElementCount64;
-
-typedef kj::Quantity<uint, _::WirePointer> WirePointerCount;
-typedef kj::Quantity<uint8_t, _::WirePointer> WirePointerCount8;
-typedef kj::Quantity<uint16_t, _::WirePointer> WirePointerCount16;
-typedef kj::Quantity<uint32_t, _::WirePointer> WirePointerCount32;
-typedef kj::Quantity<uint64_t, _::WirePointer> WirePointerCount64;
-
-template <typename T, typename U>
-inline constexpr U* operator+(U* ptr, kj::Quantity<T, U> offset) {
-  return ptr + offset / kj::unit<kj::Quantity<T, U>>();
-}
-template <typename T, typename U>
-inline constexpr const U* operator+(const U* ptr, kj::Quantity<T, U> offset) {
-  return ptr + offset / kj::unit<kj::Quantity<T, U>>();
-}
-template <typename T, typename U>
-inline constexpr U* operator+=(U*& ptr, kj::Quantity<T, U> offset) {
-  return ptr = ptr + offset / kj::unit<kj::Quantity<T, U>>();
-}
-template <typename T, typename U>
-inline constexpr const U* operator+=(const U*& ptr, kj::Quantity<T, U> offset) {
-  return ptr = ptr + offset / kj::unit<kj::Quantity<T, U>>();
-}
-
-template <typename T, typename U>
-inline constexpr U* operator-(U* ptr, kj::Quantity<T, U> offset) {
-  return ptr - offset / kj::unit<kj::Quantity<T, U>>();
-}
-template <typename T, typename U>
-inline constexpr const U* operator-(const U* ptr, kj::Quantity<T, U> offset) {
-  return ptr - offset / kj::unit<kj::Quantity<T, U>>();
-}
-template <typename T, typename U>
-inline constexpr U* operator-=(U*& ptr, kj::Quantity<T, U> offset) {
-  return ptr = ptr - offset / kj::unit<kj::Quantity<T, U>>();
-}
-template <typename T, typename U>
-inline constexpr const U* operator-=(const U*& ptr, kj::Quantity<T, U> offset) {
-  return ptr = ptr - offset / kj::unit<kj::Quantity<T, U>>();
-}
-
-#else
-
-typedef uint BitCount;
-typedef uint8_t BitCount8;
-typedef uint16_t BitCount16;
-typedef uint32_t BitCount32;
-typedef uint64_t BitCount64;
-
-typedef uint ByteCount;
-typedef uint8_t ByteCount8;
-typedef uint16_t ByteCount16;
-typedef uint32_t ByteCount32;
-typedef uint64_t ByteCount64;
-
-typedef uint WordCount;
-typedef uint8_t WordCount8;
-typedef uint16_t WordCount16;
-typedef uint32_t WordCount32;
-typedef uint64_t WordCount64;
-
-typedef uint ElementCount;
-typedef uint8_t ElementCount8;
-typedef uint16_t ElementCount16;
-typedef uint32_t ElementCount32;
-typedef uint64_t ElementCount64;
-
-typedef uint WirePointerCount;
-typedef uint8_t WirePointerCount8;
-typedef uint16_t WirePointerCount16;
-typedef uint32_t WirePointerCount32;
-typedef uint64_t WirePointerCount64;
-
-#endif
-
-constexpr BitCount BITS = kj::unit<BitCount>();
-constexpr ByteCount BYTES = kj::unit<ByteCount>();
-constexpr WordCount WORDS = kj::unit<WordCount>();
-constexpr ElementCount ELEMENTS = kj::unit<ElementCount>();
-constexpr WirePointerCount POINTERS = kj::unit<WirePointerCount>();
-
-// GCC 4.7 actually gives unused warnings on these constants in opt mode...
-constexpr auto BITS_PER_BYTE KJ_UNUSED = 8 * BITS / BYTES;
-constexpr auto BITS_PER_WORD KJ_UNUSED = 64 * BITS / WORDS;
-constexpr auto BYTES_PER_WORD KJ_UNUSED = 8 * BYTES / WORDS;
-
-constexpr auto BITS_PER_POINTER KJ_UNUSED = 64 * BITS / POINTERS;
-constexpr auto BYTES_PER_POINTER KJ_UNUSED = 8 * BYTES / POINTERS;
-constexpr auto WORDS_PER_POINTER KJ_UNUSED = 1 * WORDS / POINTERS;
-
-constexpr WordCount POINTER_SIZE_IN_WORDS = 1 * POINTERS * WORDS_PER_POINTER;
-
-template <typename T>
-inline KJ_CONSTEXPR() decltype(BYTES / ELEMENTS) bytesPerElement() {
-  return sizeof(T) * BYTES / ELEMENTS;
-}
-
-template <typename T>
-inline KJ_CONSTEXPR() decltype(BITS / ELEMENTS) bitsPerElement() {
-  return sizeof(T) * 8 * BITS / ELEMENTS;
-}
-
-inline constexpr ByteCount intervalLength(const byte* a, const byte* b) {
-  return uint(b - a) * BYTES;
-}
-inline constexpr WordCount intervalLength(const word* a, const word* b) {
-  return uint(b - a) * WORDS;
-}
-
-}  // namespace capnp
-
-#endif  // CAPNP_COMMON_H_
+// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
+// Licensed under the MIT License:
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// This file contains types which are intended to help detect incorrect usage at compile
+// time, but should then be optimized down to basic primitives (usually, integers) by the
+// compiler.
+
+#ifndef CAPNP_COMMON_H_
+#define CAPNP_COMMON_H_
+
+#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
+#pragma GCC system_header
+#endif
+
+#include <inttypes.h>
+#include <kj/string.h>
+#include <kj/memory.h>
+
+#if CAPNP_DEBUG_TYPES
+#include <kj/units.h>
+#endif
+
+namespace capnp {
+
+#define CAPNP_VERSION_MAJOR 0
+#define CAPNP_VERSION_MINOR 6
+#define CAPNP_VERSION_MICRO 0
+
+#define CAPNP_VERSION \
+  (CAPNP_VERSION_MAJOR * 1000000 + CAPNP_VERSION_MINOR * 1000 + CAPNP_VERSION_MICRO)
+
+#ifndef CAPNP_LITE
+#define CAPNP_LITE 0
+#endif
+
+typedef unsigned int uint;
+
+struct Void {
+  // Type used for Void fields.  Using C++'s "void" type creates a bunch of issues since it behaves
+  // differently from other types.
+
+  inline constexpr bool operator==(Void other) const { return true; }
+  inline constexpr bool operator!=(Void other) const { return false; }
+};
+
+static constexpr Void VOID = Void();
+// Constant value for `Void`,  which is an empty struct.
+
+inline kj::StringPtr KJ_STRINGIFY(Void) { return "void"; }
+
+struct Text;
+struct Data;
+
+enum class Kind: uint8_t {
+  PRIMITIVE,
+  BLOB,
+  ENUM,
+  STRUCT,
+  UNION,
+  INTERFACE,
+  LIST,
+
+  OTHER
+  // Some other type which is often a type parameter to Cap'n Proto templates, but which needs
+  // special handling. This includes types like AnyPointer, Dynamic*, etc.
+};
+
+enum class Style: uint8_t {
+  PRIMITIVE,
+  POINTER,      // other than struct
+  STRUCT,
+  CAPABILITY
+};
+
+enum class ElementSize: uint8_t {
+  // Size of a list element.
+
+  VOID = 0,
+  BIT = 1,
+  BYTE = 2,
+  TWO_BYTES = 3,
+  FOUR_BYTES = 4,
+  EIGHT_BYTES = 5,
+
+  POINTER = 6,
+
+  INLINE_COMPOSITE = 7
+};
+
+enum class PointerType {
+  // Various wire types a pointer field can take
+
+  NULL_,
+  // Should be NULL, but that's #defined in stddef.h
+
+  STRUCT,
+  LIST,
+  CAPABILITY
+};
+
+namespace schemas {
+
+template <typename T>
+struct EnumInfo;
+
+}  // namespace schemas
+
+namespace _ {  // private
+
+template <typename T, typename = void> struct Kind_;
+
+template <> struct Kind_<Void> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<bool> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<int8_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<int16_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<int32_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<int64_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<uint8_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<uint16_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<uint32_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<uint64_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<float> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<double> { static constexpr Kind kind = Kind::PRIMITIVE; };
+template <> struct Kind_<Text> { static constexpr Kind kind = Kind::BLOB; };
+template <> struct Kind_<Data> { static constexpr Kind kind = Kind::BLOB; };
+
+template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsStruct>> {
+  static constexpr Kind kind = Kind::STRUCT;
+};
+template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsInterface>> {
+  static constexpr Kind kind = Kind::INTERFACE;
+};
+template <typename T> struct Kind_<T, kj::VoidSfinae<typename schemas::EnumInfo<T>::IsEnum>> {
+  static constexpr Kind kind = Kind::ENUM;
+};
+
+}  // namespace _ (private)
+
+template <typename T, Kind k = _::Kind_<T>::kind>
+inline constexpr Kind kind() {
+  // This overload of kind() matches types which have a Kind_ specialization.
+
+  return k;
+}
+
+#if CAPNP_LITE
+
+#define CAPNP_KIND(T) ::capnp::_::Kind_<T>::kind
+// Avoid constexpr methods in lite mode (MSVC is bad at constexpr).
+
+#else  // CAPNP_LITE
+
+#define CAPNP_KIND(T) ::capnp::kind<T>()
+// Use this macro rather than kind<T>() in any code which must work in lite mode.
+
+template <typename T, Kind k = kind<T>()>
+inline constexpr Style style() {
+  return k == Kind::PRIMITIVE || k == Kind::ENUM ? Style::PRIMITIVE
+       : k == Kind::STRUCT ? Style::STRUCT
+       : k == Kind::INTERFACE ? Style::CAPABILITY : Style::POINTER;
+}
+
+#endif  // CAPNP_LITE, else
+
+template <typename T, Kind k = CAPNP_KIND(T)>
+struct List;
+
+#if _MSC_VER
+
+template <typename T, Kind k>
+struct List {};
+// For some reason, without this declaration, MSVC will error out on some uses of List
+// claiming that "T" -- as used in the default initializer for the second template param, "k" --
+// is not defined. I do not understand this error, but adding this empty default declaration fixes
+// it.
+
+#endif
+
+template <typename T> struct ListElementType_;
+template <typename T> struct ListElementType_<List<T>> { typedef T Type; };
+template <typename T> using ListElementType = typename ListElementType_<T>::Type;
+
+namespace _ {  // private
+template <typename T, Kind k> struct Kind_<List<T, k>> {
+  static constexpr Kind kind = Kind::LIST;
+};
+}  // namespace _ (private)
+
+template <typename T, Kind k = CAPNP_KIND(T)> struct ReaderFor_ { typedef typename T::Reader Type; };
+template <typename T> struct ReaderFor_<T, Kind::PRIMITIVE> { typedef T Type; };
+template <typename T> struct ReaderFor_<T, Kind::ENUM> { typedef T Type; };
+template <typename T> struct ReaderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
+template <typename T> using ReaderFor = typename ReaderFor_<T>::Type;
+// The type returned by List<T>::Reader::operator[].
+
+template <typename T, Kind k = CAPNP_KIND(T)> struct BuilderFor_ { typedef typename T::Builder Type; };
+template <typename T> struct BuilderFor_<T, Kind::PRIMITIVE> { typedef T Type; };
+template <typename T> struct BuilderFor_<T, Kind::ENUM> { typedef T Type; };
+template <typename T> struct BuilderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
+template <typename T> using BuilderFor = typename BuilderFor_<T>::Type;
+// The type returned by List<T>::Builder::operator[].
+
+template <typename T, Kind k = CAPNP_KIND(T)> struct PipelineFor_ { typedef typename T::Pipeline Type;};
+template <typename T> struct PipelineFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; };
+template <typename T> using PipelineFor = typename PipelineFor_<T>::Type;
+
+template <typename T, Kind k = CAPNP_KIND(T)> struct TypeIfEnum_;
+template <typename T> struct TypeIfEnum_<T, Kind::ENUM> { typedef T Type; };
+
+template <typename T>
+using TypeIfEnum = typename TypeIfEnum_<kj::Decay<T>>::Type;
+
+template <typename T>
+using FromReader = typename kj::Decay<T>::Reads;
+// FromReader<MyType::Reader> = MyType (for any Cap'n Proto type).
+
+template <typename T>
+using FromBuilder = typename kj::Decay<T>::Builds;
+// FromBuilder<MyType::Builder> = MyType (for any Cap'n Proto type).
+
+template <typename T>
+using FromPipeline = typename kj::Decay<T>::Pipelines;
+// FromBuilder<MyType::Pipeline> = MyType (for any Cap'n Proto type).
+
+template <typename T>
+using FromClient = typename kj::Decay<T>::Calls;
+// FromReader<MyType::Client> = MyType (for any Cap'n Proto interface type).
+
+template <typename T>
+using FromServer = typename kj::Decay<T>::Serves;
+// FromBuilder<MyType::Server> = MyType (for any Cap'n Proto interface type).
+
+template <typename T, typename = void>
+struct FromAny_;
+
+template <typename T>
+struct FromAny_<T, kj::VoidSfinae<FromReader<T>>> {
+  using Type = FromReader<T>;
+};
+
+template <typename T>
+struct FromAny_<T, kj::VoidSfinae<FromBuilder<T>>> {
+  using Type = FromBuilder<T>;
+};
+
+template <typename T>
+struct FromAny_<T, kj::VoidSfinae<FromPipeline<T>>> {
+  using Type = FromPipeline<T>;
+};
+
+// Note that T::Client is covered by FromReader
+
+template <typename T>
+struct FromAny_<kj::Own<T>, kj::VoidSfinae<FromServer<T>>> {
+  using Type = FromServer<T>;
+};
+
+template <typename T>
+struct FromAny_<T,
+    kj::EnableIf<_::Kind_<T>::kind == Kind::PRIMITIVE || _::Kind_<T>::kind == Kind::ENUM>> {
+  // TODO(msvc): Ideally the EnableIf condition would be `style<T>() == Style::PRIMITIVE`, but MSVC
+  // cannot yet use style<T>() in this constexpr context.
+
+  using Type = kj::Decay<T>;
+};
+
+template <typename T>
+using FromAny = typename FromAny_<T>::Type;
+// Given any Cap'n Proto value type as an input, return the Cap'n Proto base type. That is:
+//
+//     Foo::Reader -> Foo
+//     Foo::Builder -> Foo
+//     Foo::Pipeline -> Foo
+//     Foo::Client -> Foo
+//     Own<Foo::Server> -> Foo
+//     uint32_t -> uint32_t
+
+namespace _ {  // private
+
+template <typename T, Kind k = CAPNP_KIND(T)>
+struct PointerHelpers;
+
+#if _MSC_VER
+
+template <typename T, Kind k>
+struct PointerHelpers {};
+// For some reason, without this declaration, MSVC will error out on some uses of PointerHelpers
+// claiming that "T" -- as used in the default initializer for the second template param, "k" --
+// is not defined. I do not understand this error, but adding this empty default declaration fixes
+// it.
+
+#endif
+
+}  // namespace _ (private)
+
+struct MessageSize {
+  // Size of a message.  Every struct type has a method `.totalSize()` that returns this.
+  uint64_t wordCount;
+  uint capCount;
+};
+
+// =======================================================================================
+// Raw memory types and measures
+
+using kj::byte;
+
+class word { uint64_t content KJ_UNUSED_MEMBER; KJ_DISALLOW_COPY(word); public: word() = default; };
+// word is an opaque type with size of 64 bits.  This type is useful only to make pointer
+// arithmetic clearer.  Since the contents are private, the only way to access them is to first
+// reinterpret_cast to some other pointer type.
+//
+// Copying is disallowed because you should always use memcpy().  Otherwise, you may run afoul of
+// aliasing rules.
+//
+// A pointer of type word* should always be word-aligned even if won't actually be dereferenced as
+// that type.
+
+static_assert(sizeof(byte) == 1, "uint8_t is not one byte?");
+static_assert(sizeof(word) == 8, "uint64_t is not 8 bytes?");
+
+#if CAPNP_DEBUG_TYPES
+// Set CAPNP_DEBUG_TYPES to 1 to use kj::Quantity for "count" types.  Otherwise, plain integers are
+// used.  All the code should still operate exactly the same, we just lose compile-time checking.
+// Note that this will also change symbol names, so it's important that the library and any clients
+// be compiled with the same setting here.
+//
+// We disable this by default to reduce symbol name size and avoid any possibility of the compiler
+// failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this
+// during development and testing.
+
+namespace _ { class BitLabel; class ElementLabel; struct WirePointer; }
+
+template <uint width, typename T = uint>
+using BitCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::BitLabel>;
+template <uint width, typename T = uint>
+using ByteCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, byte>;
+template <uint width, typename T = uint>
+using WordCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, word>;
+template <uint width, typename T = uint>
+using ElementCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::ElementLabel>;
+template <uint width, typename T = uint>
+using WirePointerCountN = kj::Quantity<kj::Bounded<kj::maxValueForBits<width>(), T>, _::WirePointer>;
+
+typedef BitCountN<8, uint8_t> BitCount8;
+typedef BitCountN<16, uint16_t> BitCount16;
+typedef BitCountN<32, uint32_t> BitCount32;
+typedef BitCountN<64, uint64_t> BitCount64;
+typedef BitCountN<sizeof(uint) * 8, uint> BitCount;
+
+typedef ByteCountN<8, uint8_t> ByteCount8;
+typedef ByteCountN<16, uint16_t> ByteCount16;
+typedef ByteCountN<32, uint32_t> ByteCount32;
+typedef ByteCountN<64, uint64_t> ByteCount64;
+typedef ByteCountN<sizeof(uint) * 8, uint> ByteCount;
+
+typedef WordCountN<8, uint8_t> WordCount8;
+typedef WordCountN<16, uint16_t> WordCount16;
+typedef WordCountN<32, uint32_t> WordCount32;
+typedef WordCountN<64, uint64_t> WordCount64;
+typedef WordCountN<sizeof(uint) * 8, uint> WordCount;
+
+typedef ElementCountN<8, uint8_t> ElementCount8;
+typedef ElementCountN<16, uint16_t> ElementCount16;
+typedef ElementCountN<32, uint32_t> ElementCount32;
+typedef ElementCountN<64, uint64_t> ElementCount64;
+typedef ElementCountN<sizeof(uint) * 8, uint> ElementCount;
+
+typedef WirePointerCountN<8, uint8_t> WirePointerCount8;
+typedef WirePointerCountN<16, uint16_t> WirePointerCount16;
+typedef WirePointerCountN<32, uint32_t> WirePointerCount32;
+typedef WirePointerCountN<64, uint64_t> WirePointerCount64;
+typedef WirePointerCountN<sizeof(uint) * 8, uint> WirePointerCount;
+
+template <uint width>
+using BitsPerElementN = decltype(BitCountN<width>() / ElementCountN<width>());
+template <uint width>
+using BytesPerElementN = decltype(ByteCountN<width>() / ElementCountN<width>());
+template <uint width>
+using WordsPerElementN = decltype(WordCountN<width>() / ElementCountN<width>());
+template <uint width>
+using PointersPerElementN = decltype(WirePointerCountN<width>() / ElementCountN<width>());
+
+using kj::bounded;
+using kj::unbound;
+using kj::unboundAs;
+using kj::unboundMax;
+using kj::unboundMaxBits;
+using kj::assertMax;
+using kj::assertMaxBits;
+using kj::upgradeBound;
+using kj::ThrowOverflow;
+using kj::assumeBits;
+using kj::assumeMax;
+using kj::subtractChecked;
+using kj::trySubtract;
+
+template <typename T, typename U>
+inline constexpr U* operator+(U* ptr, kj::Quantity<T, U> offset) {
+  return ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>());
+}
+template <typename T, typename U>
+inline constexpr const U* operator+(const U* ptr, kj::Quantity<T, U> offset) {
+  return ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>());
+}
+template <typename T, typename U>
+inline constexpr U* operator+=(U*& ptr, kj::Quantity<T, U> offset) {
+  return ptr = ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>());
+}
+template <typename T, typename U>
+inline constexpr const U* operator+=(const U*& ptr, kj::Quantity<T, U> offset) {
+  return ptr = ptr + unbound(offset / kj::unit<kj::Quantity<T, U>>());
+}
+
+template <typename T, typename U>
+inline constexpr U* operator-(U* ptr, kj::Quantity<T, U> offset) {
+  return ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>());
+}
+template <typename T, typename U>
+inline constexpr const U* operator-(const U* ptr, kj::Quantity<T, U> offset) {
+  return ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>());
+}
+template <typename T, typename U>
+inline constexpr U* operator-=(U*& ptr, kj::Quantity<T, U> offset) {
+  return ptr = ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>());
+}
+template <typename T, typename U>
+inline constexpr const U* operator-=(const U*& ptr, kj::Quantity<T, U> offset) {
+  return ptr = ptr - unbound(offset / kj::unit<kj::Quantity<T, U>>());
+}
+
+constexpr auto BITS = kj::unit<BitCountN<1>>();
+constexpr auto BYTES = kj::unit<ByteCountN<1>>();
+constexpr auto WORDS = kj::unit<WordCountN<1>>();
+constexpr auto ELEMENTS = kj::unit<ElementCountN<1>>();
+constexpr auto POINTERS = kj::unit<WirePointerCountN<1>>();
+
+constexpr auto ZERO = kj::bounded<0>();
+constexpr auto ONE = kj::bounded<1>();
+
+// GCC 4.7 actually gives unused warnings on these constants in opt mode...
+constexpr auto BITS_PER_BYTE KJ_UNUSED = bounded<8>() * BITS / BYTES;
+constexpr auto BITS_PER_WORD KJ_UNUSED = bounded<64>() * BITS / WORDS;
+constexpr auto BYTES_PER_WORD KJ_UNUSED = bounded<8>() * BYTES / WORDS;
+
+constexpr auto BITS_PER_POINTER KJ_UNUSED = bounded<64>() * BITS / POINTERS;
+constexpr auto BYTES_PER_POINTER KJ_UNUSED = bounded<8>() * BYTES / POINTERS;
+constexpr auto WORDS_PER_POINTER KJ_UNUSED = ONE * WORDS / POINTERS;
+
+constexpr auto POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER;
+
+constexpr uint SEGMENT_WORD_COUNT_BITS = 29;      // Number of words in a segment.
+constexpr uint LIST_ELEMENT_COUNT_BITS = 29;      // Number of elements in a list.
+constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16;  // Number of words in a Struct data section.
+constexpr uint STRUCT_POINTER_COUNT_BITS = 16;    // Number of pointers in a Struct pointer section.
+constexpr uint BLOB_SIZE_BITS = 29;               // Number of bytes in a blob.
+
+typedef WordCountN<SEGMENT_WORD_COUNT_BITS> SegmentWordCount;
+typedef ElementCountN<LIST_ELEMENT_COUNT_BITS> ListElementCount;
+typedef WordCountN<STRUCT_DATA_WORD_COUNT_BITS, uint16_t> StructDataWordCount;
+typedef WirePointerCountN<STRUCT_POINTER_COUNT_BITS, uint16_t> StructPointerCount;
+typedef ByteCountN<BLOB_SIZE_BITS> BlobSize;
+
+constexpr auto MAX_SEGMENT_WORDS =
+    bounded<kj::maxValueForBits<SEGMENT_WORD_COUNT_BITS>()>() * WORDS;
+constexpr auto MAX_LIST_ELEMENTS =
+    bounded<kj::maxValueForBits<LIST_ELEMENT_COUNT_BITS>()>() * ELEMENTS;
+constexpr auto MAX_STUCT_DATA_WORDS =
+    bounded<kj::maxValueForBits<STRUCT_DATA_WORD_COUNT_BITS>()>() * WORDS;
+constexpr auto MAX_STRUCT_POINTER_COUNT =
+    bounded<kj::maxValueForBits<STRUCT_POINTER_COUNT_BITS>()>() * POINTERS;
+
+using StructDataBitCount = decltype(WordCountN<STRUCT_POINTER_COUNT_BITS>() * BITS_PER_WORD);
+// Number of bits in a Struct data segment (should come out to BitCountN<22>).
+
+using StructDataOffset = decltype(StructDataBitCount() * (ONE * ELEMENTS / BITS));
+using StructPointerOffset = StructPointerCount;
+// Type of a field offset.
+
+inline StructDataOffset assumeDataOffset(uint32_t offset) {
+  return assumeMax(MAX_STUCT_DATA_WORDS * BITS_PER_WORD * (ONE * ELEMENTS / BITS),
+                   bounded(offset) * ELEMENTS);
+}
+
+inline StructPointerOffset assumePointerOffset(uint32_t offset) {
+  return assumeMax(MAX_STRUCT_POINTER_COUNT, bounded(offset) * POINTERS);
+}
+
+constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits<BLOB_SIZE_BITS>() - 1;
+typedef kj::Quantity<kj::Bounded<MAX_TEXT_SIZE, uint>, byte> TextSize;
+// Not including NUL terminator.
+
+template <typename T>
+inline KJ_CONSTEXPR() decltype(bounded<sizeof(T)>() * BYTES / ELEMENTS) bytesPerElement() {
+  return bounded<sizeof(T)>() * BYTES / ELEMENTS;
+}
+
+template <typename T>
+inline KJ_CONSTEXPR() decltype(bounded<sizeof(T) * 8>() * BITS / ELEMENTS) bitsPerElement() {
+  return bounded<sizeof(T) * 8>() * BITS / ELEMENTS;
+}
+
+template <typename T, uint maxN>
+inline constexpr kj::Quantity<kj::Bounded<maxN, size_t>, T>
+intervalLength(const T* a, const T* b, kj::Quantity<kj::BoundedConst<maxN>, T>) {
+  return kj::assumeMax<maxN>(b - a) * kj::unit<kj::Quantity<kj::BoundedConst<1u>, T>>();
+}
+
+template <typename T, typename U>
+inline constexpr kj::ArrayPtr<const U> arrayPtr(const U* ptr, kj::Quantity<T, U> size) {
+  return kj::ArrayPtr<const U>(ptr, unbound(size / kj::unit<kj::Quantity<T, U>>()));
+}
+template <typename T, typename U>
+inline constexpr kj::ArrayPtr<U> arrayPtr(U* ptr, kj::Quantity<T, U> size) {
+  return kj::ArrayPtr<U>(ptr, unbound(size / kj::unit<kj::Quantity<T, U>>()));
+}
+
+#else
+
+template <uint width, typename T = uint>
+using BitCountN = T;
+template <uint width, typename T = uint>
+using ByteCountN = T;
+template <uint width, typename T = uint>
+using WordCountN = T;
+template <uint width, typename T = uint>
+using ElementCountN = T;
+template <uint width, typename T = uint>
+using WirePointerCountN = T;
+
+
+// XXX
+typedef BitCountN<8, uint8_t> BitCount8;
+typedef BitCountN<16, uint16_t> BitCount16;
+typedef BitCountN<32, uint32_t> BitCount32;
+typedef BitCountN<64, uint64_t> BitCount64;
+typedef BitCountN<sizeof(uint) * 8, uint> BitCount;
+
+typedef ByteCountN<8, uint8_t> ByteCount8;
+typedef ByteCountN<16, uint16_t> ByteCount16;
+typedef ByteCountN<32, uint32_t> ByteCount32;
+typedef ByteCountN<64, uint64_t> ByteCount64;
+typedef ByteCountN<sizeof(uint) * 8, uint> ByteCount;
+
+typedef WordCountN<8, uint8_t> WordCount8;
+typedef WordCountN<16, uint16_t> WordCount16;
+typedef WordCountN<32, uint32_t> WordCount32;
+typedef WordCountN<64, uint64_t> WordCount64;
+typedef WordCountN<sizeof(uint) * 8, uint> WordCount;
+
+typedef ElementCountN<8, uint8_t> ElementCount8;
+typedef ElementCountN<16, uint16_t> ElementCount16;
+typedef ElementCountN<32, uint32_t> ElementCount32;
+typedef ElementCountN<64, uint64_t> ElementCount64;
+typedef ElementCountN<sizeof(uint) * 8, uint> ElementCount;
+
+typedef WirePointerCountN<8, uint8_t> WirePointerCount8;
+typedef WirePointerCountN<16, uint16_t> WirePointerCount16;
+typedef WirePointerCountN<32, uint32_t> WirePointerCount32;
+typedef WirePointerCountN<64, uint64_t> WirePointerCount64;
+typedef WirePointerCountN<sizeof(uint) * 8, uint> WirePointerCount;
+
+template <uint width>
+using BitsPerElementN = decltype(BitCountN<width>() / ElementCountN<width>());
+template <uint width>
+using BytesPerElementN = decltype(ByteCountN<width>() / ElementCountN<width>());
+template <uint width>
+using WordsPerElementN = decltype(WordCountN<width>() / ElementCountN<width>());
+template <uint width>
+using PointersPerElementN = decltype(WirePointerCountN<width>() / ElementCountN<width>());
+
+using kj::ThrowOverflow;
+// YYY
+
+template <uint i> inline constexpr uint bounded() { return i; }
+template <typename T> inline constexpr T bounded(T i) { return i; }
+template <typename T> inline constexpr T unbound(T i) { return i; }
+
+template <typename T, typename U> inline constexpr T unboundAs(U i) { return i; }
+
+template <uint64_t requestedMax, typename T> inline constexpr uint unboundMax(T i) { return i; }
+template <uint bits, typename T> inline constexpr uint unboundMaxBits(T i) { return i; }
+
+template <uint newMax, typename T, typename ErrorFunc>
+inline T assertMax(T value, ErrorFunc&& func) {
+  if (KJ_UNLIKELY(value > newMax)) func();
+  return value;
+}
+
+template <typename T, typename ErrorFunc>
+inline T assertMax(uint newMax, T value, ErrorFunc&& func) {
+  if (KJ_UNLIKELY(value > newMax)) func();
+  return value;
+}
+
+template <uint bits, typename T, typename ErrorFunc = ThrowOverflow>
+inline T assertMaxBits(T value, ErrorFunc&& func = ErrorFunc()) {
+  if (KJ_UNLIKELY(value > kj::maxValueForBits<bits>())) func();
+  return value;
+}
+
+template <typename T, typename ErrorFunc = ThrowOverflow>
+inline T assertMaxBits(uint bits, T value, ErrorFunc&& func = ErrorFunc()) {
+  if (KJ_UNLIKELY(value > (1ull << bits) - 1)) func();
+  return value;
+}
+
+template <typename T, typename U> inline constexpr T upgradeBound(U i) { return i; }
+
+template <uint bits, typename T> inline constexpr T assumeBits(T i) { return i; }
+template <uint64_t max, typename T> inline constexpr T assumeMax(T i) { return i; }
+
+template <typename T, typename U, typename ErrorFunc = ThrowOverflow>
+inline auto subtractChecked(T a, U b, ErrorFunc&& errorFunc = ErrorFunc())
+    -> decltype(a - b) {
+  if (b > a) errorFunc();
+  return a - b;
+}
+
+template <typename T, typename U>
+inline auto trySubtract(T a, U b) -> kj::Maybe<decltype(a - b)> {
+  if (b > a) {
+    return nullptr;
+  } else {
+    return a - b;
+  }
+}
+
+constexpr uint BITS = 1;
+constexpr uint BYTES = 1;
+constexpr uint WORDS = 1;
+constexpr uint ELEMENTS = 1;
+constexpr uint POINTERS = 1;
+
+constexpr uint ZERO = 0;
+constexpr uint ONE = 1;
+
+// GCC 4.7 actually gives unused warnings on these constants in opt mode...
+constexpr uint BITS_PER_BYTE KJ_UNUSED = 8;
+constexpr uint BITS_PER_WORD KJ_UNUSED = 64;
+constexpr uint BYTES_PER_WORD KJ_UNUSED = 8;
+
+constexpr uint BITS_PER_POINTER KJ_UNUSED = 64;
+constexpr uint BYTES_PER_POINTER KJ_UNUSED = 8;
+constexpr uint WORDS_PER_POINTER KJ_UNUSED = 1;
+
+// XXX
+constexpr uint POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER;
+
+constexpr uint SEGMENT_WORD_COUNT_BITS = 29;      // Number of words in a segment.
+constexpr uint LIST_ELEMENT_COUNT_BITS = 29;      // Number of elements in a list.
+constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16;  // Number of words in a Struct data section.
+constexpr uint STRUCT_POINTER_COUNT_BITS = 16;    // Number of pointers in a Struct pointer section.
+constexpr uint BLOB_SIZE_BITS = 29;               // Number of bytes in a blob.
+
+typedef WordCountN<SEGMENT_WORD_COUNT_BITS> SegmentWordCount;
+typedef ElementCountN<LIST_ELEMENT_COUNT_BITS> ListElementCount;
+typedef WordCountN<STRUCT_DATA_WORD_COUNT_BITS, uint16_t> StructDataWordCount;
+typedef WirePointerCountN<STRUCT_POINTER_COUNT_BITS, uint16_t> StructPointerCount;
+typedef ByteCountN<BLOB_SIZE_BITS> BlobSize;
+// YYY
+
+constexpr auto MAX_SEGMENT_WORDS = kj::maxValueForBits<SEGMENT_WORD_COUNT_BITS>();
+constexpr auto MAX_LIST_ELEMENTS = kj::maxValueForBits<LIST_ELEMENT_COUNT_BITS>();
+constexpr auto MAX_STUCT_DATA_WORDS = kj::maxValueForBits<STRUCT_DATA_WORD_COUNT_BITS>();
+constexpr auto MAX_STRUCT_POINTER_COUNT = kj::maxValueForBits<STRUCT_POINTER_COUNT_BITS>();
+
+typedef uint StructDataBitCount;
+typedef uint StructDataOffset;
+typedef uint StructPointerOffset;
+
+inline StructDataOffset assumeDataOffset(uint32_t offset) { return offset; }
+inline StructPointerOffset assumePointerOffset(uint32_t offset) { return offset; }
+
+constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits<BLOB_SIZE_BITS>() - 1;
+typedef uint TextSize;
+
+template <typename T>
+inline KJ_CONSTEXPR() size_t bytesPerElement() { return sizeof(T); }
+
+template <typename T>
+inline KJ_CONSTEXPR() size_t bitsPerElement() { return sizeof(T) * 8; }
+
+template <typename T>
+inline constexpr ptrdiff_t intervalLength(const T* a, const T* b, uint) {
+  return b - a;
+}
+
+template <typename T, typename U>
+inline constexpr kj::ArrayPtr<const U> arrayPtr(const U* ptr, T size) {
+  return kj::arrayPtr(ptr, size);
+}
+template <typename T, typename U>
+inline constexpr kj::ArrayPtr<U> arrayPtr(U* ptr, T size) {
+  return kj::arrayPtr(ptr, size);
+}
+
+#endif
+
+}  // namespace capnp
+
+#endif  // CAPNP_COMMON_H_