# HG changeset patch # User Chris Cannam # Date 1495527414 -3600 # Node ID 279b18cc7785bf3c04d1f43a0da432868574ff98 # Parent b4bfdf10c4b31f8808c0014470ce58d2ff408577 Update Win32 capnp builds to v0.6 diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/bin/capnp.exe Binary file win32-mingw/bin/capnp.exe has changed diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/bin/capnpc-c++.exe Binary file win32-mingw/bin/capnpc-c++.exe has changed diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/bin/capnpc-capnp.exe Binary file win32-mingw/bin/capnpc-capnp.exe has changed diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/any.h --- a/win32-mingw/include/capnp/any.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/any.h Tue May 23 09:16:54 2017 +0100 @@ -1,1047 +1,1073 @@ -// 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. - -#ifndef CAPNP_ANY_H_ -#define CAPNP_ANY_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" -#include "pointer-helpers.h" -#include "orphan.h" -#include "list.h" - -namespace capnp { - -class StructSchema; -class ListSchema; -class InterfaceSchema; -class Orphanage; -class ClientHook; -class PipelineHook; -struct PipelineOp; -struct AnyPointer; - -struct AnyList { - AnyList() = delete; - - class Reader; - class Builder; -}; - -struct AnyStruct { - AnyStruct() = delete; - - class Reader; - class Builder; - class Pipeline; -}; - -template<> -struct List { - List() = delete; - - class Reader; - class Builder; -}; - -namespace _ { // private -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -} // namespace _ (private) - -// ======================================================================================= -// AnyPointer! - -enum class Equality { - NOT_EQUAL, - EQUAL, - UNKNOWN_CONTAINS_CAPS -}; - -kj::StringPtr KJ_STRINGIFY(Equality res); - -struct AnyPointer { - // Reader/Builder for the `AnyPointer` field type, i.e. a pointer that can point to an arbitrary - // object. - - AnyPointer() = delete; - - class Reader { - public: - typedef AnyPointer Reads; - - Reader() = default; - inline Reader(_::PointerReader reader): reader(reader) {} - - inline MessageSize targetSize() const; - // Get the total size of the target object and all its children. - - inline PointerType getPointerType() const; - - inline bool isNull() const { return getPointerType() == PointerType::NULL_; } - inline bool isStruct() const { return getPointerType() == PointerType::STRUCT; } - inline bool isList() const { return getPointerType() == PointerType::LIST; } - inline bool isCapability() const { return getPointerType() == PointerType::CAPABILITY; } - - Equality equals(AnyPointer::Reader right); - bool operator==(AnyPointer::Reader right); - inline bool operator!=(AnyPointer::Reader right) { - return !(*this == right); - } - - template - inline ReaderFor getAs() const; - // Valid for T = any generated struct type, interface type, List, Text, or Data. - - template - inline ReaderFor getAs(StructSchema schema) const; - // Only valid for T = DynamicStruct. Requires `#include `. - - template - inline ReaderFor getAs(ListSchema schema) const; - // Only valid for T = DynamicList. Requires `#include `. - - template - inline ReaderFor getAs(InterfaceSchema schema) const; - // Only valid for T = DynamicCapability. Requires `#include `. - -#if !CAPNP_LITE - kj::Own getPipelinedCap(kj::ArrayPtr ops) const; - // Used by RPC system to implement pipelining. Applications generally shouldn't use this - // directly. -#endif // !CAPNP_LITE - - private: - _::PointerReader reader; - friend struct AnyPointer; - friend class Orphanage; - friend class CapReaderContext; - friend struct _::PointerHelpers; - }; - - class Builder { - public: - typedef AnyPointer Builds; - - Builder() = delete; - inline Builder(decltype(nullptr)) {} - inline Builder(_::PointerBuilder builder): builder(builder) {} - - inline MessageSize targetSize() const; - // Get the total size of the target object and all its children. - - inline PointerType getPointerType(); - - inline bool isNull() { return getPointerType() == PointerType::NULL_; } - inline bool isStruct() { return getPointerType() == PointerType::STRUCT; } - inline bool isList() { return getPointerType() == PointerType::LIST; } - inline bool isCapability() { return getPointerType() == PointerType::CAPABILITY; } - - inline Equality equals(AnyPointer::Reader right) { - return asReader().equals(right); - } - inline bool operator==(AnyPointer::Reader right) { - return asReader() == right; - } - inline bool operator!=(AnyPointer::Reader right) { - return !(*this == right); - } - - inline void clear(); - // Set to null. - - template - inline BuilderFor getAs(); - // Valid for T = any generated struct type, List, Text, or Data. - - template - inline BuilderFor getAs(StructSchema schema); - // Only valid for T = DynamicStruct. Requires `#include `. - - template - inline BuilderFor getAs(ListSchema schema); - // Only valid for T = DynamicList. Requires `#include `. - - template - inline BuilderFor getAs(InterfaceSchema schema); - // Only valid for T = DynamicCapability. Requires `#include `. - - template - inline BuilderFor initAs(); - // Valid for T = any generated struct type. - - template - inline BuilderFor initAs(uint elementCount); - // Valid for T = List, Text, or Data. - - template - inline BuilderFor initAs(StructSchema schema); - // Only valid for T = DynamicStruct. Requires `#include `. - - template - inline BuilderFor initAs(ListSchema schema, uint elementCount); - // Only valid for T = DynamicList. Requires `#include `. - - inline AnyList::Builder initAsAnyList(ElementSize elementSize, uint elementCount); - // Note: Does not accept INLINE_COMPOSITE for elementSize. - - inline List::Builder initAsListOfAnyStruct( - uint dataWordCount, uint pointerCount, uint elementCount); - - inline AnyStruct::Builder initAsAnyStruct(uint dataWordCount, uint pointerCount); - - template - inline void setAs(ReaderFor value); - // Valid for ReaderType = T::Reader for T = any generated struct type, List, Text, Data, - // DynamicStruct, or DynamicList (the dynamic types require `#include `). - - template - inline void setAs(std::initializer_list>> list); - // Valid for T = List. - - template - inline void setCanonicalAs(ReaderFor value); - - inline void set(Reader value) { builder.copyFrom(value.reader); } - // Set to a copy of another AnyPointer. - - inline void setCanonical(Reader value) { builder.copyFrom(value.reader, true); } - - template - inline void adopt(Orphan&& orphan); - // Valid for T = any generated struct type, List, Text, Data, DynamicList, DynamicStruct, - // or DynamicValue (the dynamic types require `#include `). - - template - inline Orphan disownAs(); - // Valid for T = any generated struct type, List, Text, Data. - - template - inline Orphan disownAs(StructSchema schema); - // Only valid for T = DynamicStruct. Requires `#include `. - - template - inline Orphan disownAs(ListSchema schema); - // Only valid for T = DynamicList. Requires `#include `. - - template - inline Orphan disownAs(InterfaceSchema schema); - // Only valid for T = DynamicCapability. Requires `#include `. - - inline Orphan disown(); - // Disown without a type. - - inline Reader asReader() const { return Reader(builder.asReader()); } - inline operator Reader() const { return Reader(builder.asReader()); } - - private: - _::PointerBuilder builder; - friend class Orphanage; - friend class CapBuilderContext; - friend struct _::PointerHelpers; - }; - -#if !CAPNP_LITE - class Pipeline { - public: - typedef AnyPointer Pipelines; - - inline Pipeline(decltype(nullptr)) {} - inline explicit Pipeline(kj::Own&& hook): hook(kj::mv(hook)) {} - - Pipeline noop(); - // Just make a copy. - - Pipeline getPointerField(uint16_t pointerIndex); - // Deprecated. In the future, we should use .asAnyStruct.getPointerField. - - inline AnyStruct::Pipeline asAnyStruct(); - - kj::Own asCap(); - // Expect that the result is a capability and construct a pipelined version of it now. - - inline kj::Own releasePipelineHook() { return kj::mv(hook); } - // For use by RPC implementations. - - template ) == Kind::INTERFACE>> - inline operator T() { return T(asCap()); } - - private: - kj::Own hook; - kj::Array ops; - - inline Pipeline(kj::Own&& hook, kj::Array&& ops) - : hook(kj::mv(hook)), ops(kj::mv(ops)) {} - - friend class LocalClient; - friend class PipelineHook; - friend class AnyStruct::Pipeline; - }; -#endif // !CAPNP_LITE -}; - -template <> -class Orphan { - // An orphaned object of unknown type. - -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - inline Orphan(_::OrphanBuilder&& builder) - : builder(kj::mv(builder)) {} - - Orphan& operator=(Orphan&&) = default; - - template - inline Orphan(Orphan&& other): builder(kj::mv(other.builder)) {} - template - inline Orphan& operator=(Orphan&& other) { builder = kj::mv(other.builder); return *this; } - // Cast from typed orphan. - - // It's not possible to get an AnyPointer::{Reader,Builder} directly since there is no - // underlying pointer (the pointer would normally live in the parent, but this object is - // orphaned). It is possible, however, to request typed readers/builders. - - template - inline BuilderFor getAs(); - template - inline BuilderFor getAs(StructSchema schema); - template - inline BuilderFor getAs(ListSchema schema); - template - inline typename T::Client getAs(InterfaceSchema schema); - template - inline ReaderFor getAsReader() const; - template - inline ReaderFor getAsReader(StructSchema schema) const; - template - inline ReaderFor getAsReader(ListSchema schema) const; - template - inline typename T::Client getAsReader(InterfaceSchema schema) const; - - template - inline Orphan releaseAs(); - template - inline Orphan releaseAs(StructSchema schema); - template - inline Orphan releaseAs(ListSchema schema); - template - inline Orphan releaseAs(InterfaceSchema schema); - // Down-cast the orphan to a specific type. - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - -private: - _::OrphanBuilder builder; - - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend class Orphan; - friend class AnyPointer::Builder; -}; - -template struct AnyTypeFor_; -template <> struct AnyTypeFor_ { typedef AnyStruct Type; }; -template <> struct AnyTypeFor_ { typedef AnyList Type; }; - -template -using AnyTypeFor = typename AnyTypeFor_::Type; - -template -inline ReaderFor>> toAny(T&& value) { - return ReaderFor>>( - _::PointerHelpers>::getInternalReader(value)); -} -template -inline BuilderFor>> toAny(T&& value) { - return BuilderFor>>( - _::PointerHelpers>::getInternalBuilder(kj::mv(value))); -} - -template <> -struct List { - // Note: This cannot be used for a list of structs, since such lists are not encoded as pointer - // lists! Use List. - - List() = delete; - - class Reader { - public: - typedef List Reads; - - inline Reader(): reader(ElementSize::POINTER) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return reader.size() / ELEMENTS; } - inline AnyPointer::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return AnyPointer::Reader(reader.getPointerElement(index * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - Builder() = delete; - inline Builder(decltype(nullptr)): builder(ElementSize::POINTER) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return builder.size() / ELEMENTS; } - inline AnyPointer::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return AnyPointer::Builder(builder.getPointerElement(index * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; -}; - -class AnyStruct::Reader { -public: - typedef AnyStruct Reads; - - Reader() = default; - inline Reader(_::StructReader reader): _reader(reader) {} - - template ) == Kind::STRUCT>> - inline Reader(T&& value) - : _reader(_::PointerHelpers>::getInternalReader(kj::fwd(value))) {} - - kj::ArrayPtr getDataSection() { - return _reader.getDataSectionAsBlob(); - } - List::Reader getPointerSection() { - return List::Reader(_reader.getPointerSectionAsList()); - } - - kj::Array canonicalize() { - return _reader.canonicalize(); - } - - Equality equals(AnyStruct::Reader right); - bool operator==(AnyStruct::Reader right); - inline bool operator!=(AnyStruct::Reader right) { - return !(*this == right); - } - - template - ReaderFor as() const { - // T must be a struct type. - return typename T::Reader(_reader); - } -private: - _::StructReader _reader; - - template - friend struct _::PointerHelpers; - friend class Orphanage; -}; - -class AnyStruct::Builder { -public: - typedef AnyStruct Builds; - - inline Builder(decltype(nullptr)) {} - inline Builder(_::StructBuilder builder): _builder(builder) {} - -#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. - template ) == Kind::STRUCT>> - inline Builder(T&& value) - : _builder(_::PointerHelpers>::getInternalBuilder(kj::fwd(value))) {} -#endif - - inline kj::ArrayPtr getDataSection() { - return _builder.getDataSectionAsBlob(); - } - List::Builder getPointerSection() { - return List::Builder(_builder.getPointerSectionAsList()); - } - - inline Equality equals(AnyStruct::Reader right) { - return asReader().equals(right); - } - inline bool operator==(AnyStruct::Reader right) { - return asReader() == right; - } - inline bool operator!=(AnyStruct::Reader right) { - return !(*this == right); - } - - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return Reader(_builder.asReader()); } - - template - BuilderFor as() { - // T must be a struct type. - return typename T::Builder(_builder); - } -private: - _::StructBuilder _builder; - friend class Orphanage; - friend class CapBuilderContext; -}; - -#if !CAPNP_LITE -class AnyStruct::Pipeline { -public: - inline Pipeline(decltype(nullptr)): typeless(nullptr) {} - inline explicit Pipeline(AnyPointer::Pipeline&& typeless) - : typeless(kj::mv(typeless)) {} - - inline AnyPointer::Pipeline getPointerField(uint16_t pointerIndex) { - // Return a new Promise representing a sub-object of the result. `pointerIndex` is the index - // of the sub-object within the pointer section of the result (the result must be a struct). - // - // TODO(perf): On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies. - // Also make `ops` into a Vector to optimize this. - return typeless.getPointerField(pointerIndex); - } - -private: - AnyPointer::Pipeline typeless; -}; -#endif // !CAPNP_LITE - -class List::Reader { -public: - typedef List Reads; - - inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return reader.size() / ELEMENTS; } - inline AnyStruct::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return AnyStruct::Reader(reader.getStructElement(index * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; -}; - -class List::Builder { -public: - typedef List Builds; - - Builder() = delete; - inline Builder(decltype(nullptr)): builder(ElementSize::INLINE_COMPOSITE) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return builder.size() / ELEMENTS; } - inline AnyStruct::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return AnyStruct::Builder(builder.getStructElement(index * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - -private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; -}; - -class AnyList::Reader { -public: - typedef AnyList Reads; - - inline Reader(): _reader(ElementSize::VOID) {} - inline Reader(_::ListReader reader): _reader(reader) {} - -#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. - template ) == Kind::LIST>> - inline Reader(T&& value) - : _reader(_::PointerHelpers>::getInternalReader(kj::fwd(value))) {} -#endif - - inline ElementSize getElementSize() { return _reader.getElementSize(); } - inline uint size() { return _reader.size() / ELEMENTS; } - - inline kj::ArrayPtr getRawBytes() { return _reader.asRawBytes(); } - - Equality equals(AnyList::Reader right); - bool operator==(AnyList::Reader right); - inline bool operator!=(AnyList::Reader right) { - return !(*this == right); - } - - template ReaderFor as() { - // T must be List. - return ReaderFor(_reader); - } -private: - _::ListReader _reader; - - template - friend struct _::PointerHelpers; - friend class Orphanage; -}; - -class AnyList::Builder { -public: - typedef AnyList Builds; - - inline Builder(decltype(nullptr)): _builder(ElementSize::VOID) {} - inline Builder(_::ListBuilder builder): _builder(builder) {} - -#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. - template ) == Kind::LIST>> - inline Builder(T&& value) - : _builder(_::PointerHelpers>::getInternalBuilder(kj::fwd(value))) {} -#endif - - inline ElementSize getElementSize() { return _builder.getElementSize(); } - inline uint size() { return _builder.size() / ELEMENTS; } - - Equality equals(AnyList::Reader right); - inline bool operator==(AnyList::Reader right) { - return asReader() == right; - } - inline bool operator!=(AnyList::Reader right) { - return !(*this == right); - } - - template BuilderFor as() { - // T must be List. - return BuilderFor(_builder); - } - - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return Reader(_builder.asReader()); } - -private: - _::ListBuilder _builder; - - friend class Orphanage; -}; - -// ======================================================================================= -// Pipeline helpers -// -// These relate to capabilities, but we don't declare them in capability.h because generated code -// for structs needs to know about these, even in files that contain no interfaces. - -#if !CAPNP_LITE - -struct PipelineOp { - // Corresponds to rpc.capnp's PromisedAnswer.Op. - - enum Type { - NOOP, // for convenience - - GET_POINTER_FIELD - - // There may be other types in the future... - }; - - Type type; - union { - uint16_t pointerIndex; // for GET_POINTER_FIELD - }; -}; - -class PipelineHook { - // Represents a currently-running call, and implements pipelined requests on its result. - -public: - virtual kj::Own addRef() = 0; - // Increment this object's reference count. - - virtual kj::Own getPipelinedCap(kj::ArrayPtr ops) = 0; - // Extract a promised Capability from the results. - - virtual kj::Own getPipelinedCap(kj::Array&& ops); - // Version of getPipelinedCap() passing the array by move. May avoid a copy in some cases. - // Default implementation just calls the other version. - - template > - static inline kj::Own from(Pipeline&& pipeline); - -private: - template struct FromImpl; -}; - -#endif // !CAPNP_LITE - -// ======================================================================================= -// Inline implementation details - -inline MessageSize AnyPointer::Reader::targetSize() const { - return reader.targetSize().asPublic(); -} - -inline PointerType AnyPointer::Reader::getPointerType() const { - return reader.getPointerType(); -} - -template -inline ReaderFor AnyPointer::Reader::getAs() const { - return _::PointerHelpers::get(reader); -} - -inline MessageSize AnyPointer::Builder::targetSize() const { - return asReader().targetSize(); -} - -inline PointerType AnyPointer::Builder::getPointerType() { - return builder.getPointerType(); -} - -inline void AnyPointer::Builder::clear() { - return builder.clear(); -} - -template -inline BuilderFor AnyPointer::Builder::getAs() { - return _::PointerHelpers::get(builder); -} - -template -inline BuilderFor AnyPointer::Builder::initAs() { - return _::PointerHelpers::init(builder); -} - -template -inline BuilderFor AnyPointer::Builder::initAs(uint elementCount) { - return _::PointerHelpers::init(builder, elementCount); -} - -inline AnyList::Builder AnyPointer::Builder::initAsAnyList( - ElementSize elementSize, uint elementCount) { - return AnyList::Builder(builder.initList(elementSize, elementCount * ELEMENTS)); -} - -inline List::Builder AnyPointer::Builder::initAsListOfAnyStruct( - uint dataWordCount, uint pointerCount, uint elementCount) { - return List::Builder(builder.initStructList(elementCount * ELEMENTS, - _::StructSize(dataWordCount * WORDS, pointerCount * POINTERS))); -} - -inline AnyStruct::Builder AnyPointer::Builder::initAsAnyStruct(uint dataWordCount, uint pointerCount) { - return AnyStruct::Builder(builder.initStruct( - _::StructSize(dataWordCount * WORDS, pointerCount * POINTERS))); -} - -template -inline void AnyPointer::Builder::setAs(ReaderFor value) { - return _::PointerHelpers::set(builder, value); -} - -template -inline void AnyPointer::Builder::setCanonicalAs(ReaderFor value) { - return _::PointerHelpers::setCanonical(builder, value); -} - -template -inline void AnyPointer::Builder::setAs( - std::initializer_list>> list) { - return _::PointerHelpers::set(builder, list); -} - -template -inline void AnyPointer::Builder::adopt(Orphan&& orphan) { - _::PointerHelpers::adopt(builder, kj::mv(orphan)); -} - -template -inline Orphan AnyPointer::Builder::disownAs() { - return _::PointerHelpers::disown(builder); -} - -inline Orphan AnyPointer::Builder::disown() { - return Orphan(builder.disown()); -} - -template <> struct ReaderFor_ { typedef AnyPointer::Reader Type; }; -template <> struct BuilderFor_ { typedef AnyPointer::Builder Type; }; -template <> struct ReaderFor_ { typedef AnyStruct::Reader Type; }; -template <> struct BuilderFor_ { typedef AnyStruct::Builder Type; }; - -template <> -struct Orphanage::GetInnerReader { - static inline _::PointerReader apply(const AnyPointer::Reader& t) { - return t.reader; - } -}; - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::PointerBuilder apply(AnyPointer::Builder& t) { - return t.builder; - } -}; - -template <> -struct Orphanage::GetInnerReader { - static inline _::StructReader apply(const AnyStruct::Reader& t) { - return t._reader; - } -}; - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::StructBuilder apply(AnyStruct::Builder& t) { - return t._builder; - } -}; - -template <> -struct Orphanage::GetInnerReader { - static inline _::ListReader apply(const AnyList::Reader& t) { - return t._reader; - } -}; - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::ListBuilder apply(AnyList::Builder& t) { - return t._builder; - } -}; - -template -inline BuilderFor Orphan::getAs() { - return _::OrphanGetImpl::apply(builder); -} -template -inline ReaderFor Orphan::getAsReader() const { - return _::OrphanGetImpl::applyReader(builder); -} -template -inline Orphan Orphan::releaseAs() { - return Orphan(kj::mv(builder)); -} - -// Using AnyPointer as the template type should work... - -template <> -inline typename AnyPointer::Reader AnyPointer::Reader::getAs() const { - return *this; -} -template <> -inline typename AnyPointer::Builder AnyPointer::Builder::getAs() { - return *this; -} -template <> -inline typename AnyPointer::Builder AnyPointer::Builder::initAs() { - clear(); - return *this; -} -template <> -inline void AnyPointer::Builder::setAs(AnyPointer::Reader value) { - return builder.copyFrom(value.reader); -} -template <> -inline void AnyPointer::Builder::adopt(Orphan&& orphan) { - builder.adopt(kj::mv(orphan.builder)); -} -template <> -inline Orphan AnyPointer::Builder::disownAs() { - return Orphan(builder.disown()); -} -template <> -inline Orphan Orphan::releaseAs() { - return kj::mv(*this); -} - -namespace _ { // private - -// Specialize PointerHelpers for AnyPointer. - -template <> -struct PointerHelpers { - static inline AnyPointer::Reader get(PointerReader reader, - const void* defaultValue = nullptr, - uint defaultBytes = 0) { - return AnyPointer::Reader(reader); - } - static inline AnyPointer::Builder get(PointerBuilder builder, - const void* defaultValue = nullptr, - uint defaultBytes = 0) { - return AnyPointer::Builder(builder); - } - static inline void set(PointerBuilder builder, AnyPointer::Reader value) { - AnyPointer::Builder(builder).set(value); - } - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } - static inline _::PointerReader getInternalReader(const AnyPointer::Reader& reader) { - return reader.reader; - } - static inline _::PointerBuilder getInternalBuilder(AnyPointer::Builder&& builder) { - return builder.builder; - } -}; - -template <> -struct PointerHelpers { - static inline AnyStruct::Reader get( - PointerReader reader, const word* defaultValue = nullptr) { - return AnyStruct::Reader(reader.getStruct(defaultValue)); - } - static inline AnyStruct::Builder get( - PointerBuilder builder, const word* defaultValue = nullptr) { - // TODO(someday): Allow specifying the size somehow? - return AnyStruct::Builder(builder.getStruct( - _::StructSize(0 * WORDS, 0 * POINTERS), defaultValue)); - } - static inline void set(PointerBuilder builder, AnyStruct::Reader value) { - builder.setStruct(value._reader); - } - static inline AnyStruct::Builder init( - PointerBuilder builder, uint dataWordCount, uint pointerCount) { - return AnyStruct::Builder(builder.initStruct( - StructSize(dataWordCount * WORDS, pointerCount * POINTERS))); - } - - // TODO(soon): implement these - static void adopt(PointerBuilder builder, Orphan&& value); - static Orphan disown(PointerBuilder builder); -}; - -template <> -struct PointerHelpers { - static inline AnyList::Reader get( - PointerReader reader, const word* defaultValue = nullptr) { - return AnyList::Reader(reader.getListAnySize(defaultValue)); - } - static inline AnyList::Builder get( - PointerBuilder builder, const word* defaultValue = nullptr) { - return AnyList::Builder(builder.getListAnySize(defaultValue)); - } - static inline void set(PointerBuilder builder, AnyList::Reader value) { - builder.setList(value._reader); - } - static inline AnyList::Builder init( - PointerBuilder builder, ElementSize elementSize, uint elementCount) { - return AnyList::Builder(builder.initList(elementSize, elementCount * ELEMENTS)); - } - static inline AnyList::Builder init( - PointerBuilder builder, uint dataWordCount, uint pointerCount, uint elementCount) { - return AnyList::Builder(builder.initStructList( - elementCount * ELEMENTS, StructSize(dataWordCount * WORDS, pointerCount * POINTERS))); - } - - // TODO(soon): implement these - static void adopt(PointerBuilder builder, Orphan&& value); - static Orphan disown(PointerBuilder builder); -}; - -template <> -struct OrphanGetImpl { - static inline AnyStruct::Builder apply(_::OrphanBuilder& builder) { - return AnyStruct::Builder(builder.asStruct(_::StructSize(0 * WORDS, 0 * POINTERS))); - } - static inline AnyStruct::Reader applyReader(const _::OrphanBuilder& builder) { - return AnyStruct::Reader(builder.asStructReader(_::StructSize(0 * WORDS, 0 * POINTERS))); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, _::StructSize(0 * WORDS, 0 * POINTERS)); - } -}; - -} // namespace _ (private) - -#if !CAPNP_LITE - -template -struct PipelineHook::FromImpl { - static inline kj::Own apply(typename T::Pipeline&& pipeline) { - return from(kj::mv(pipeline._typeless)); - } -}; - -template <> -struct PipelineHook::FromImpl { - static inline kj::Own apply(AnyPointer::Pipeline&& pipeline) { - return kj::mv(pipeline.hook); - } -}; - -template -inline kj::Own PipelineHook::from(Pipeline&& pipeline) { - return FromImpl::apply(kj::fwd(pipeline)); -} - -#endif // !CAPNP_LITE - -} // namespace capnp - -#endif // CAPNP_ANY_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. + +#ifndef CAPNP_ANY_H_ +#define CAPNP_ANY_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" +#include "pointer-helpers.h" +#include "orphan.h" +#include "list.h" + +namespace capnp { + +class StructSchema; +class ListSchema; +class InterfaceSchema; +class Orphanage; +class ClientHook; +class PipelineHook; +struct PipelineOp; +struct AnyPointer; + +struct AnyList { + AnyList() = delete; + + class Reader; + class Builder; +}; + +struct AnyStruct { + AnyStruct() = delete; + + class Reader; + class Builder; + class Pipeline; +}; + +template<> +struct List { + List() = delete; + + class Reader; + class Builder; +}; + +namespace _ { // private +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +} // namespace _ (private) + +// ======================================================================================= +// AnyPointer! + +enum class Equality { + NOT_EQUAL, + EQUAL, + UNKNOWN_CONTAINS_CAPS +}; + +kj::StringPtr KJ_STRINGIFY(Equality res); + +struct AnyPointer { + // Reader/Builder for the `AnyPointer` field type, i.e. a pointer that can point to an arbitrary + // object. + + AnyPointer() = delete; + + class Reader { + public: + typedef AnyPointer Reads; + + Reader() = default; + inline Reader(_::PointerReader reader): reader(reader) {} + + inline MessageSize targetSize() const; + // Get the total size of the target object and all its children. + + inline PointerType getPointerType() const; + + inline bool isNull() const { return getPointerType() == PointerType::NULL_; } + inline bool isStruct() const { return getPointerType() == PointerType::STRUCT; } + inline bool isList() const { return getPointerType() == PointerType::LIST; } + inline bool isCapability() const { return getPointerType() == PointerType::CAPABILITY; } + + Equality equals(AnyPointer::Reader right); + bool operator==(AnyPointer::Reader right); + inline bool operator!=(AnyPointer::Reader right) { + return !(*this == right); + } + + template + inline ReaderFor getAs() const; + // Valid for T = any generated struct type, interface type, List, Text, or Data. + + template + inline ReaderFor getAs(StructSchema schema) const; + // Only valid for T = DynamicStruct. Requires `#include `. + + template + inline ReaderFor getAs(ListSchema schema) const; + // Only valid for T = DynamicList. Requires `#include `. + + template + inline ReaderFor getAs(InterfaceSchema schema) const; + // Only valid for T = DynamicCapability. Requires `#include `. + +#if !CAPNP_LITE + kj::Own getPipelinedCap(kj::ArrayPtr ops) const; + // Used by RPC system to implement pipelining. Applications generally shouldn't use this + // directly. +#endif // !CAPNP_LITE + + private: + _::PointerReader reader; + friend struct AnyPointer; + friend class Orphanage; + friend class CapReaderContext; + friend struct _::PointerHelpers; + }; + + class Builder { + public: + typedef AnyPointer Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)) {} + inline Builder(_::PointerBuilder builder): builder(builder) {} + + inline MessageSize targetSize() const; + // Get the total size of the target object and all its children. + + inline PointerType getPointerType(); + + inline bool isNull() { return getPointerType() == PointerType::NULL_; } + inline bool isStruct() { return getPointerType() == PointerType::STRUCT; } + inline bool isList() { return getPointerType() == PointerType::LIST; } + inline bool isCapability() { return getPointerType() == PointerType::CAPABILITY; } + + inline Equality equals(AnyPointer::Reader right) { + return asReader().equals(right); + } + inline bool operator==(AnyPointer::Reader right) { + return asReader() == right; + } + inline bool operator!=(AnyPointer::Reader right) { + return !(*this == right); + } + + inline void clear(); + // Set to null. + + template + inline BuilderFor getAs(); + // Valid for T = any generated struct type, List, Text, or Data. + + template + inline BuilderFor getAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include `. + + template + inline BuilderFor getAs(ListSchema schema); + // Only valid for T = DynamicList. Requires `#include `. + + template + inline BuilderFor getAs(InterfaceSchema schema); + // Only valid for T = DynamicCapability. Requires `#include `. + + template + inline BuilderFor initAs(); + // Valid for T = any generated struct type. + + template + inline BuilderFor initAs(uint elementCount); + // Valid for T = List, Text, or Data. + + template + inline BuilderFor initAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include `. + + template + inline BuilderFor initAs(ListSchema schema, uint elementCount); + // Only valid for T = DynamicList. Requires `#include `. + + inline AnyList::Builder initAsAnyList(ElementSize elementSize, uint elementCount); + // Note: Does not accept INLINE_COMPOSITE for elementSize. + + inline List::Builder initAsListOfAnyStruct( + uint16_t dataWordCount, uint16_t pointerCount, uint elementCount); + + inline AnyStruct::Builder initAsAnyStruct(uint16_t dataWordCount, uint16_t pointerCount); + + template + inline void setAs(ReaderFor value); + // Valid for ReaderType = T::Reader for T = any generated struct type, List, Text, Data, + // DynamicStruct, or DynamicList (the dynamic types require `#include `). + + template + inline void setAs(std::initializer_list>> list); + // Valid for T = List. + + template + inline void setCanonicalAs(ReaderFor value); + + inline void set(Reader value) { builder.copyFrom(value.reader); } + // Set to a copy of another AnyPointer. + + inline void setCanonical(Reader value) { builder.copyFrom(value.reader, true); } + + template + inline void adopt(Orphan&& orphan); + // Valid for T = any generated struct type, List, Text, Data, DynamicList, DynamicStruct, + // or DynamicValue (the dynamic types require `#include `). + + template + inline Orphan disownAs(); + // Valid for T = any generated struct type, List, Text, Data. + + template + inline Orphan disownAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include `. + + template + inline Orphan disownAs(ListSchema schema); + // Only valid for T = DynamicList. Requires `#include `. + + template + inline Orphan disownAs(InterfaceSchema schema); + // Only valid for T = DynamicCapability. Requires `#include `. + + inline Orphan disown(); + // Disown without a type. + + inline Reader asReader() const { return Reader(builder.asReader()); } + inline operator Reader() const { return Reader(builder.asReader()); } + + private: + _::PointerBuilder builder; + friend class Orphanage; + friend class CapBuilderContext; + friend struct _::PointerHelpers; + }; + +#if !CAPNP_LITE + class Pipeline { + public: + typedef AnyPointer Pipelines; + + inline Pipeline(decltype(nullptr)) {} + inline explicit Pipeline(kj::Own&& hook): hook(kj::mv(hook)) {} + + Pipeline noop(); + // Just make a copy. + + Pipeline getPointerField(uint16_t pointerIndex); + // Deprecated. In the future, we should use .asAnyStruct.getPointerField. + + inline AnyStruct::Pipeline asAnyStruct(); + + kj::Own asCap(); + // Expect that the result is a capability and construct a pipelined version of it now. + + inline kj::Own releasePipelineHook() { return kj::mv(hook); } + // For use by RPC implementations. + + template ) == Kind::INTERFACE>> + inline operator T() { return T(asCap()); } + + private: + kj::Own hook; + kj::Array ops; + + inline Pipeline(kj::Own&& hook, kj::Array&& ops) + : hook(kj::mv(hook)), ops(kj::mv(ops)) {} + + friend class LocalClient; + friend class PipelineHook; + friend class AnyStruct::Pipeline; + }; +#endif // !CAPNP_LITE +}; + +template <> +class Orphan { + // An orphaned object of unknown type. + +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + inline Orphan(_::OrphanBuilder&& builder) + : builder(kj::mv(builder)) {} + + Orphan& operator=(Orphan&&) = default; + + template + inline Orphan(Orphan&& other): builder(kj::mv(other.builder)) {} + template + inline Orphan& operator=(Orphan&& other) { builder = kj::mv(other.builder); return *this; } + // Cast from typed orphan. + + // It's not possible to get an AnyPointer::{Reader,Builder} directly since there is no + // underlying pointer (the pointer would normally live in the parent, but this object is + // orphaned). It is possible, however, to request typed readers/builders. + + template + inline BuilderFor getAs(); + template + inline BuilderFor getAs(StructSchema schema); + template + inline BuilderFor getAs(ListSchema schema); + template + inline typename T::Client getAs(InterfaceSchema schema); + template + inline ReaderFor getAsReader() const; + template + inline ReaderFor getAsReader(StructSchema schema) const; + template + inline ReaderFor getAsReader(ListSchema schema) const; + template + inline typename T::Client getAsReader(InterfaceSchema schema) const; + + template + inline Orphan releaseAs(); + template + inline Orphan releaseAs(StructSchema schema); + template + inline Orphan releaseAs(ListSchema schema); + template + inline Orphan releaseAs(InterfaceSchema schema); + // Down-cast the orphan to a specific type. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + _::OrphanBuilder builder; + + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend class Orphan; + friend class AnyPointer::Builder; +}; + +template struct AnyTypeFor_; +template <> struct AnyTypeFor_ { typedef AnyStruct Type; }; +template <> struct AnyTypeFor_ { typedef AnyList Type; }; + +template +using AnyTypeFor = typename AnyTypeFor_::Type; + +template +inline ReaderFor>> toAny(T&& value) { + return ReaderFor>>( + _::PointerHelpers>::getInternalReader(value)); +} +template +inline BuilderFor>> toAny(T&& value) { + return BuilderFor>>( + _::PointerHelpers>::getInternalBuilder(kj::mv(value))); +} + +template <> +struct List { + // Note: This cannot be used for a list of structs, since such lists are not encoded as pointer + // lists! Use List. + + List() = delete; + + class Reader { + public: + typedef List Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline AnyPointer::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return AnyPointer::Reader(reader.getPointerElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)): builder(ElementSize::POINTER) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline AnyPointer::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return AnyPointer::Builder(builder.getPointerElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; +}; + +class AnyStruct::Reader { +public: + typedef AnyStruct Reads; + + Reader() = default; + inline Reader(_::StructReader reader): _reader(reader) {} + + template ) == Kind::STRUCT>> + inline Reader(T&& value) + : _reader(_::PointerHelpers>::getInternalReader(kj::fwd(value))) {} + + kj::ArrayPtr getDataSection() { + return _reader.getDataSectionAsBlob(); + } + List::Reader getPointerSection() { + return List::Reader(_reader.getPointerSectionAsList()); + } + + kj::Array canonicalize() { + return _reader.canonicalize(); + } + + Equality equals(AnyStruct::Reader right); + bool operator==(AnyStruct::Reader right); + inline bool operator!=(AnyStruct::Reader right) { + return !(*this == right); + } + + template + ReaderFor as() const { + // T must be a struct type. + return typename T::Reader(_reader); + } +private: + _::StructReader _reader; + + template + friend struct _::PointerHelpers; + friend class Orphanage; +}; + +class AnyStruct::Builder { +public: + typedef AnyStruct Builds; + + inline Builder(decltype(nullptr)) {} + inline Builder(_::StructBuilder builder): _builder(builder) {} + +#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template ) == Kind::STRUCT>> + inline Builder(T&& value) + : _builder(_::PointerHelpers>::getInternalBuilder(kj::fwd(value))) {} +#endif + + inline kj::ArrayPtr getDataSection() { + return _builder.getDataSectionAsBlob(); + } + List::Builder getPointerSection() { + return List::Builder(_builder.getPointerSectionAsList()); + } + + inline Equality equals(AnyStruct::Reader right) { + return asReader().equals(right); + } + inline bool operator==(AnyStruct::Reader right) { + return asReader() == right; + } + inline bool operator!=(AnyStruct::Reader right) { + return !(*this == right); + } + + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return Reader(_builder.asReader()); } + + template + BuilderFor as() { + // T must be a struct type. + return typename T::Builder(_builder); + } +private: + _::StructBuilder _builder; + friend class Orphanage; + friend class CapBuilderContext; +}; + +#if !CAPNP_LITE +class AnyStruct::Pipeline { +public: + inline Pipeline(decltype(nullptr)): typeless(nullptr) {} + inline explicit Pipeline(AnyPointer::Pipeline&& typeless) + : typeless(kj::mv(typeless)) {} + + inline AnyPointer::Pipeline getPointerField(uint16_t pointerIndex) { + // Return a new Promise representing a sub-object of the result. `pointerIndex` is the index + // of the sub-object within the pointer section of the result (the result must be a struct). + // + // TODO(perf): On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies. + // Also make `ops` into a Vector to optimize this. + return typeless.getPointerField(pointerIndex); + } + +private: + AnyPointer::Pipeline typeless; +}; +#endif // !CAPNP_LITE + +class List::Reader { +public: + typedef List Reads; + + inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline AnyStruct::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return AnyStruct::Reader(reader.getStructElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; +}; + +class List::Builder { +public: + typedef List Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)): builder(ElementSize::INLINE_COMPOSITE) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline AnyStruct::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return AnyStruct::Builder(builder.getStructElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + +private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; +}; + +class AnyList::Reader { +public: + typedef AnyList Reads; + + inline Reader(): _reader(ElementSize::VOID) {} + inline Reader(_::ListReader reader): _reader(reader) {} + +#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template ) == Kind::LIST>> + inline Reader(T&& value) + : _reader(_::PointerHelpers>::getInternalReader(kj::fwd(value))) {} +#endif + + inline ElementSize getElementSize() { return _reader.getElementSize(); } + inline uint size() { return unbound(_reader.size() / ELEMENTS); } + + inline kj::ArrayPtr getRawBytes() { return _reader.asRawBytes(); } + + Equality equals(AnyList::Reader right); + bool operator==(AnyList::Reader right); + inline bool operator!=(AnyList::Reader right) { + return !(*this == right); + } + + template ReaderFor as() { + // T must be List. + return ReaderFor(_reader); + } +private: + _::ListReader _reader; + + template + friend struct _::PointerHelpers; + friend class Orphanage; +}; + +class AnyList::Builder { +public: + typedef AnyList Builds; + + inline Builder(decltype(nullptr)): _builder(ElementSize::VOID) {} + inline Builder(_::ListBuilder builder): _builder(builder) {} + +#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template ) == Kind::LIST>> + inline Builder(T&& value) + : _builder(_::PointerHelpers>::getInternalBuilder(kj::fwd(value))) {} +#endif + + inline ElementSize getElementSize() { return _builder.getElementSize(); } + inline uint size() { return unbound(_builder.size() / ELEMENTS); } + + Equality equals(AnyList::Reader right); + inline bool operator==(AnyList::Reader right) { + return asReader() == right; + } + inline bool operator!=(AnyList::Reader right) { + return !(*this == right); + } + + template BuilderFor as() { + // T must be List. + return BuilderFor(_builder); + } + + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return Reader(_builder.asReader()); } + +private: + _::ListBuilder _builder; + + friend class Orphanage; +}; + +// ======================================================================================= +// Pipeline helpers +// +// These relate to capabilities, but we don't declare them in capability.h because generated code +// for structs needs to know about these, even in files that contain no interfaces. + +#if !CAPNP_LITE + +struct PipelineOp { + // Corresponds to rpc.capnp's PromisedAnswer.Op. + + enum Type { + NOOP, // for convenience + + GET_POINTER_FIELD + + // There may be other types in the future... + }; + + Type type; + union { + uint16_t pointerIndex; // for GET_POINTER_FIELD + }; +}; + +class PipelineHook { + // Represents a currently-running call, and implements pipelined requests on its result. + +public: + virtual kj::Own addRef() = 0; + // Increment this object's reference count. + + virtual kj::Own getPipelinedCap(kj::ArrayPtr ops) = 0; + // Extract a promised Capability from the results. + + virtual kj::Own getPipelinedCap(kj::Array&& ops); + // Version of getPipelinedCap() passing the array by move. May avoid a copy in some cases. + // Default implementation just calls the other version. + + template > + static inline kj::Own from(Pipeline&& pipeline); + +private: + template struct FromImpl; +}; + +#endif // !CAPNP_LITE + +// ======================================================================================= +// Inline implementation details + +inline MessageSize AnyPointer::Reader::targetSize() const { + return reader.targetSize().asPublic(); +} + +inline PointerType AnyPointer::Reader::getPointerType() const { + return reader.getPointerType(); +} + +template +inline ReaderFor AnyPointer::Reader::getAs() const { + return _::PointerHelpers::get(reader); +} + +inline MessageSize AnyPointer::Builder::targetSize() const { + return asReader().targetSize(); +} + +inline PointerType AnyPointer::Builder::getPointerType() { + return builder.getPointerType(); +} + +inline void AnyPointer::Builder::clear() { + return builder.clear(); +} + +template +inline BuilderFor AnyPointer::Builder::getAs() { + return _::PointerHelpers::get(builder); +} + +template +inline BuilderFor AnyPointer::Builder::initAs() { + return _::PointerHelpers::init(builder); +} + +template +inline BuilderFor AnyPointer::Builder::initAs(uint elementCount) { + return _::PointerHelpers::init(builder, elementCount); +} + +inline AnyList::Builder AnyPointer::Builder::initAsAnyList( + ElementSize elementSize, uint elementCount) { + return AnyList::Builder(builder.initList(elementSize, bounded(elementCount) * ELEMENTS)); +} + +inline List::Builder AnyPointer::Builder::initAsListOfAnyStruct( + uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) { + return List::Builder(builder.initStructList(bounded(elementCount) * ELEMENTS, + _::StructSize(bounded(dataWordCount) * WORDS, + bounded(pointerCount) * POINTERS))); +} + +inline AnyStruct::Builder AnyPointer::Builder::initAsAnyStruct( + uint16_t dataWordCount, uint16_t pointerCount) { + return AnyStruct::Builder(builder.initStruct( + _::StructSize(bounded(dataWordCount) * WORDS, + bounded(pointerCount) * POINTERS))); +} + +template +inline void AnyPointer::Builder::setAs(ReaderFor value) { + return _::PointerHelpers::set(builder, value); +} + +template +inline void AnyPointer::Builder::setCanonicalAs(ReaderFor value) { + return _::PointerHelpers::setCanonical(builder, value); +} + +template +inline void AnyPointer::Builder::setAs( + std::initializer_list>> list) { + return _::PointerHelpers::set(builder, list); +} + +template +inline void AnyPointer::Builder::adopt(Orphan&& orphan) { + _::PointerHelpers::adopt(builder, kj::mv(orphan)); +} + +template +inline Orphan AnyPointer::Builder::disownAs() { + return _::PointerHelpers::disown(builder); +} + +inline Orphan AnyPointer::Builder::disown() { + return Orphan(builder.disown()); +} + +template <> struct ReaderFor_ { typedef AnyPointer::Reader Type; }; +template <> struct BuilderFor_ { typedef AnyPointer::Builder Type; }; +template <> struct ReaderFor_ { typedef AnyStruct::Reader Type; }; +template <> struct BuilderFor_ { typedef AnyStruct::Builder Type; }; + +template <> +struct Orphanage::GetInnerReader { + static inline _::PointerReader apply(const AnyPointer::Reader& t) { + return t.reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::PointerBuilder apply(AnyPointer::Builder& t) { + return t.builder; + } +}; + +template <> +struct Orphanage::GetInnerReader { + static inline _::StructReader apply(const AnyStruct::Reader& t) { + return t._reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::StructBuilder apply(AnyStruct::Builder& t) { + return t._builder; + } +}; + +template <> +struct Orphanage::GetInnerReader { + static inline _::ListReader apply(const AnyList::Reader& t) { + return t._reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::ListBuilder apply(AnyList::Builder& t) { + return t._builder; + } +}; + +template +inline BuilderFor Orphan::getAs() { + return _::OrphanGetImpl::apply(builder); +} +template +inline ReaderFor Orphan::getAsReader() const { + return _::OrphanGetImpl::applyReader(builder); +} +template +inline Orphan Orphan::releaseAs() { + return Orphan(kj::mv(builder)); +} + +// Using AnyPointer as the template type should work... + +template <> +inline typename AnyPointer::Reader AnyPointer::Reader::getAs() const { + return *this; +} +template <> +inline typename AnyPointer::Builder AnyPointer::Builder::getAs() { + return *this; +} +template <> +inline typename AnyPointer::Builder AnyPointer::Builder::initAs() { + clear(); + return *this; +} +template <> +inline void AnyPointer::Builder::setAs(AnyPointer::Reader value) { + return builder.copyFrom(value.reader); +} +template <> +inline void AnyPointer::Builder::adopt(Orphan&& orphan) { + builder.adopt(kj::mv(orphan.builder)); +} +template <> +inline Orphan AnyPointer::Builder::disownAs() { + return Orphan(builder.disown()); +} +template <> +inline Orphan Orphan::releaseAs() { + return kj::mv(*this); +} + +namespace _ { // private + +// Specialize PointerHelpers for AnyPointer. + +template <> +struct PointerHelpers { + static inline AnyPointer::Reader get(PointerReader reader, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return AnyPointer::Reader(reader); + } + static inline AnyPointer::Builder get(PointerBuilder builder, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return AnyPointer::Builder(builder); + } + static inline void set(PointerBuilder builder, AnyPointer::Reader value) { + AnyPointer::Builder(builder).set(value); + } + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } + static inline _::PointerReader getInternalReader(const AnyPointer::Reader& reader) { + return reader.reader; + } + static inline _::PointerBuilder getInternalBuilder(AnyPointer::Builder&& builder) { + return builder.builder; + } +}; + +template <> +struct PointerHelpers { + static inline AnyStruct::Reader get( + PointerReader reader, const word* defaultValue = nullptr) { + return AnyStruct::Reader(reader.getStruct(defaultValue)); + } + static inline AnyStruct::Builder get( + PointerBuilder builder, const word* defaultValue = nullptr) { + // TODO(someday): Allow specifying the size somehow? + return AnyStruct::Builder(builder.getStruct( + _::StructSize(ZERO * WORDS, ZERO * POINTERS), defaultValue)); + } + static inline void set(PointerBuilder builder, AnyStruct::Reader value) { + builder.setStruct(value._reader); + } + static inline AnyStruct::Builder init( + PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount) { + return AnyStruct::Builder(builder.initStruct( + StructSize(bounded(dataWordCount) * WORDS, + bounded(pointerCount) * POINTERS))); + } + + static void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } +}; + +template <> +struct PointerHelpers { + static inline AnyList::Reader get( + PointerReader reader, const word* defaultValue = nullptr) { + return AnyList::Reader(reader.getListAnySize(defaultValue)); + } + static inline AnyList::Builder get( + PointerBuilder builder, const word* defaultValue = nullptr) { + return AnyList::Builder(builder.getListAnySize(defaultValue)); + } + static inline void set(PointerBuilder builder, AnyList::Reader value) { + builder.setList(value._reader); + } + static inline AnyList::Builder init( + PointerBuilder builder, ElementSize elementSize, uint elementCount) { + return AnyList::Builder(builder.initList( + elementSize, bounded(elementCount) * ELEMENTS)); + } + static inline AnyList::Builder init( + PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) { + return AnyList::Builder(builder.initStructList( + bounded(elementCount) * ELEMENTS, + StructSize(bounded(dataWordCount) * WORDS, + bounded(pointerCount) * POINTERS))); + } + + static void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } +}; + +template <> +struct OrphanGetImpl { + static inline AnyStruct::Builder apply(_::OrphanBuilder& builder) { + return AnyStruct::Builder(builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); + } + static inline AnyStruct::Reader applyReader(const _::OrphanBuilder& builder) { + return AnyStruct::Reader(builder.asStructReader(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::StructSize(ZERO * WORDS, ZERO * POINTERS)); + } +}; + +template <> +struct OrphanGetImpl { + static inline AnyList::Builder apply(_::OrphanBuilder& builder) { + return AnyList::Builder(builder.asListAnySize()); + } + static inline AnyList::Reader applyReader(const _::OrphanBuilder& builder) { + return AnyList::Reader(builder.asListReaderAnySize()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +} // namespace _ (private) + +#if !CAPNP_LITE + +template +struct PipelineHook::FromImpl { + static inline kj::Own apply(typename T::Pipeline&& pipeline) { + return from(kj::mv(pipeline._typeless)); + } +}; + +template <> +struct PipelineHook::FromImpl { + static inline kj::Own apply(AnyPointer::Pipeline&& pipeline) { + return kj::mv(pipeline.hook); + } +}; + +template +inline kj::Own PipelineHook::from(Pipeline&& pipeline) { + return FromImpl::apply(kj::fwd(pipeline)); +} + +#endif // !CAPNP_LITE + +} // namespace capnp + +#endif // CAPNP_ANY_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/arena.h --- a/win32-mingw/include/capnp/arena.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/arena.h Tue May 23 09:16:54 2017 +0100 @@ -1,457 +1,496 @@ -// 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. - -#ifndef CAPNP_ARENA_H_ -#define CAPNP_ARENA_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#ifndef CAPNP_PRIVATE -#error "This header is only meant to be included by Cap'n Proto's own source code." -#endif - -#include -#include -#include -#include -#include "common.h" -#include "message.h" -#include "layout.h" -#include - -#if !CAPNP_LITE -#include "capability.h" -#endif // !CAPNP_LITE - -namespace capnp { - -#if !CAPNP_LITE -class ClientHook; -#endif // !CAPNP_LITE - -namespace _ { // private - -class SegmentReader; -class SegmentBuilder; -class Arena; -class BuilderArena; -class ReadLimiter; - -class Segment; -typedef kj::Id SegmentId; - -class ReadLimiter { - // Used to keep track of how much data has been processed from a message, and cut off further - // processing if and when a particular limit is reached. This is primarily intended to guard - // against maliciously-crafted messages which contain cycles or overlapping structures. Cycles - // and overlapping are not permitted by the Cap'n Proto format because in many cases they could - // be used to craft a deceptively small message which could consume excessive server resources to - // process, perhaps even sending it into an infinite loop. Actually detecting overlaps would be - // time-consuming, so instead we just keep track of how many words worth of data structures the - // receiver has actually dereferenced and error out if this gets too high. - // - // This counting takes place as you call getters (for non-primitive values) on the message - // readers. If you call the same getter twice, the data it returns may be double-counted. This - // should not be a big deal in most cases -- just set the read limit high enough that it will - // only trigger in unreasonable cases. - // - // This class is "safe" to use from multiple threads for its intended use case. Threads may - // overwrite each others' changes to the counter, but this is OK because it only means that the - // limit is enforced a bit less strictly -- it will still kick in eventually. - -public: - inline explicit ReadLimiter(); // No limit. - inline explicit ReadLimiter(WordCount64 limit); // Limit to the given number of words. - - inline void reset(WordCount64 limit); - - KJ_ALWAYS_INLINE(bool canRead(WordCount amount, Arena* arena)); - - void unread(WordCount64 amount); - // Adds back some words to the limit. Useful when the caller knows they are double-reading - // some data. - -private: - volatile uint64_t limit; - // Current limit, decremented each time catRead() is called. Volatile because multiple threads - // could be trying to modify it at once. (This is not real thread-safety, but good enough for - // the purpose of this class. See class comment.) - - KJ_DISALLOW_COPY(ReadLimiter); -}; - -#if !CAPNP_LITE -class BrokenCapFactory { - // Callback for constructing broken caps. We use this so that we can avoid arena.c++ having a - // link-time dependency on capability code that lives in libcapnp-rpc. - -public: - virtual kj::Own newBrokenCap(kj::StringPtr description) = 0; - virtual kj::Own newNullCap() = 0; -}; -#endif // !CAPNP_LITE - -class SegmentReader { -public: - inline SegmentReader(Arena* arena, SegmentId id, kj::ArrayPtr ptr, - ReadLimiter* readLimiter); - - KJ_ALWAYS_INLINE(bool containsInterval(const void* from, const void* to)); - - KJ_ALWAYS_INLINE(bool amplifiedRead(WordCount virtualAmount)); - // Indicates that the reader should pretend that `virtualAmount` additional data was read even - // though no actual pointer was traversed. This is used e.g. when reading a struct list pointer - // where the element sizes are zero -- the sender could set the list size arbitrarily high and - // cause the receiver to iterate over this list even though the message itself is small, so we - // need to defend against DoS attacks based on this. - - inline Arena* getArena(); - inline SegmentId getSegmentId(); - - inline const word* getStartPtr(); - inline WordCount getOffsetTo(const word* ptr); - inline WordCount getSize(); - - inline kj::ArrayPtr getArray(); - - inline void unread(WordCount64 amount); - // Add back some words to the ReadLimiter. - -private: - Arena* arena; - SegmentId id; - kj::ArrayPtr ptr; - ReadLimiter* readLimiter; - - KJ_DISALLOW_COPY(SegmentReader); - - friend class SegmentBuilder; -}; - -class SegmentBuilder: public SegmentReader { -public: - inline SegmentBuilder(BuilderArena* arena, SegmentId id, kj::ArrayPtr ptr, - ReadLimiter* readLimiter, size_t wordsUsed = 0); - inline SegmentBuilder(BuilderArena* arena, SegmentId id, kj::ArrayPtr ptr, - ReadLimiter* readLimiter); - inline SegmentBuilder(BuilderArena* arena, SegmentId id, decltype(nullptr), - ReadLimiter* readLimiter); - - KJ_ALWAYS_INLINE(word* allocate(WordCount amount)); - - KJ_ALWAYS_INLINE(void checkWritable()); - // Throw an exception if the segment is read-only (meaning it is a reference to external data). - - KJ_ALWAYS_INLINE(word* getPtrUnchecked(WordCount offset)); - // Get a writable pointer into the segment. Throws an exception if the segment is read-only (i.e. - // a reference to external immutable data). - - inline BuilderArena* getArena(); - - inline kj::ArrayPtr currentlyAllocated(); - - inline void reset(); - - inline bool isWritable() { return !readOnly; } - - inline void tryTruncate(word* from, word* to); - // If `from` points just past the current end of the segment, then move the end back to `to`. - // Otherwise, do nothing. - - inline bool tryExtend(word* from, word* to); - // If `from` points just past the current end of the segment, and `to` is within the segment - // boundaries, then move the end up to `to` and return true. Otherwise, do nothing and return - // false. - -private: - word* pos; - // Pointer to a pointer to the current end point of the segment, i.e. the location where the - // next object should be allocated. - - bool readOnly; - - void throwNotWritable(); - - KJ_DISALLOW_COPY(SegmentBuilder); -}; - -class Arena { -public: - virtual ~Arena() noexcept(false); - - virtual SegmentReader* tryGetSegment(SegmentId id) = 0; - // Gets the segment with the given ID, or return nullptr if no such segment exists. - - virtual void reportReadLimitReached() = 0; - // Called to report that the read limit has been reached. See ReadLimiter, below. This invokes - // the VALIDATE_INPUT() macro which may throw an exception; if it returns normally, the caller - // will need to continue with default values. -}; - -class ReaderArena final: public Arena { -public: - ReaderArena(MessageReader* message); - ~ReaderArena() noexcept(false); - KJ_DISALLOW_COPY(ReaderArena); - - // implements Arena ------------------------------------------------ - SegmentReader* tryGetSegment(SegmentId id) override; - void reportReadLimitReached() override; - -private: - MessageReader* message; - ReadLimiter readLimiter; - - // Optimize for single-segment messages so that small messages are handled quickly. - SegmentReader segment0; - - typedef std::unordered_map> SegmentMap; - kj::MutexGuarded>> moreSegments; - // We need to mutex-guard the segment map because we lazily initialize segments when they are - // first requested, but a Reader is allowed to be used concurrently in multiple threads. Luckily - // this only applies to large messages. - // - // TODO(perf): Thread-local thing instead? Some kind of lockless map? Or do sharing of data - // in a different way, where you have to construct a new MessageReader in each thread (but - // possibly backed by the same data)? -}; - -class BuilderArena final: public Arena { - // A BuilderArena that does not allow the injection of capabilities. - -public: - explicit BuilderArena(MessageBuilder* message); - BuilderArena(MessageBuilder* message, kj::ArrayPtr segments); - ~BuilderArena() noexcept(false); - KJ_DISALLOW_COPY(BuilderArena); - - inline SegmentBuilder* getRootSegment() { return &segment0; } - - kj::ArrayPtr> getSegmentsForOutput(); - // Get an array of all the segments, suitable for writing out. This only returns the allocated - // portion of each segment, whereas tryGetSegment() returns something that includes - // not-yet-allocated space. - - inline CapTableBuilder* getLocalCapTable() { - // Return a CapTableBuilder that merely implements local loopback. That is, you can set - // capabilities, then read the same capabilities back, but there is no intent ever to transmit - // these capabilities. A MessageBuilder that isn't imbued with some other CapTable uses this - // by default. - // - // TODO(cleanup): It's sort of a hack that this exists. In theory, perhaps, unimbued - // MessageBuilders should throw exceptions on any attempt to access capability fields, like - // unimbued MessageReaders do. However, lots of code exists which uses MallocMessageBuilder - // as a temporary holder for data to be copied in and out (without being serialized), and it - // is expected that such data can include capabilities, which is admittedly reasonable. - // Therefore, all MessageBuilders must have a cap table by default. Arguably we should - // deprecate this usage and instead define a new helper type for this exact purpose. - - return &localCapTable; - } - - SegmentBuilder* getSegment(SegmentId id); - // Get the segment with the given id. Crashes or throws an exception if no such segment exists. - - struct AllocateResult { - SegmentBuilder* segment; - word* words; - }; - - AllocateResult allocate(WordCount amount); - // Find a segment with at least the given amount of space available and allocate the space. - // Note that allocating directly from a particular segment is much faster, but allocating from - // the arena is guaranteed to succeed. Therefore callers should try to allocate from a specific - // segment first if there is one, then fall back to the arena. - - SegmentBuilder* addExternalSegment(kj::ArrayPtr content); - // Add a new segment to the arena which points to some existing memory region. The segment is - // assumed to be completley full; the arena will never allocate from it. In fact, the segment - // is considered read-only. Any attempt to get a Builder pointing into this segment will throw - // an exception. Readers are allowed, however. - // - // This can be used to inject some external data into a message without a copy, e.g. embedding a - // large mmap'd file into a message as `Data` without forcing that data to actually be read in - // from disk (until the message itself is written out). `Orphanage` provides the public API for - // this feature. - - // implements Arena ------------------------------------------------ - SegmentReader* tryGetSegment(SegmentId id) override; - void reportReadLimitReached() override; - -private: - MessageBuilder* message; - ReadLimiter dummyLimiter; - - class LocalCapTable: public CapTableBuilder { -#if !CAPNP_LITE - public: - kj::Maybe> extractCap(uint index) override; - uint injectCap(kj::Own&& cap) override; - void dropCap(uint index) override; - - private: - kj::Vector>> capTable; -#endif // ! CAPNP_LITE - }; - - LocalCapTable localCapTable; - - SegmentBuilder segment0; - kj::ArrayPtr segment0ForOutput; - - struct MultiSegmentState { - kj::Vector> builders; - kj::Vector> forOutput; - }; - kj::Maybe> moreSegments; - - SegmentBuilder* segmentWithSpace = nullptr; - // When allocating, look for space in this segment first before resorting to allocating a new - // segment. This is not necessarily the last segment because addExternalSegment() may add a - // segment that is already-full, in which case we don't update this pointer. - - template // Can be `word` or `const word`. - SegmentBuilder* addSegmentInternal(kj::ArrayPtr content); -}; - -// ======================================================================================= - -inline ReadLimiter::ReadLimiter() - : limit(kj::maxValue) {} - -inline ReadLimiter::ReadLimiter(WordCount64 limit): limit(limit / WORDS) {} - -inline void ReadLimiter::reset(WordCount64 limit) { this->limit = limit / WORDS; } - -inline bool ReadLimiter::canRead(WordCount amount, Arena* arena) { - // Be careful not to store an underflowed value into `limit`, even if multiple threads are - // decrementing it. - uint64_t current = limit; - if (KJ_UNLIKELY(amount / WORDS > current)) { - arena->reportReadLimitReached(); - return false; - } else { - limit = current - amount / WORDS; - return true; - } -} - -// ------------------------------------------------------------------- - -inline SegmentReader::SegmentReader(Arena* arena, SegmentId id, kj::ArrayPtr ptr, - ReadLimiter* readLimiter) - : arena(arena), id(id), ptr(ptr), readLimiter(readLimiter) {} - -inline bool SegmentReader::containsInterval(const void* from, const void* to) { - return from >= this->ptr.begin() && to <= this->ptr.end() && from <= to && - readLimiter->canRead( - intervalLength(reinterpret_cast(from), - reinterpret_cast(to)) / BYTES_PER_WORD, - arena); -} - -inline bool SegmentReader::amplifiedRead(WordCount virtualAmount) { - return readLimiter->canRead(virtualAmount, arena); -} - -inline Arena* SegmentReader::getArena() { return arena; } -inline SegmentId SegmentReader::getSegmentId() { return id; } -inline const word* SegmentReader::getStartPtr() { return ptr.begin(); } -inline WordCount SegmentReader::getOffsetTo(const word* ptr) { - return intervalLength(this->ptr.begin(), ptr); -} -inline WordCount SegmentReader::getSize() { return ptr.size() * WORDS; } -inline kj::ArrayPtr SegmentReader::getArray() { return ptr; } -inline void SegmentReader::unread(WordCount64 amount) { readLimiter->unread(amount); } - -// ------------------------------------------------------------------- - -inline SegmentBuilder::SegmentBuilder( - BuilderArena* arena, SegmentId id, kj::ArrayPtr ptr, ReadLimiter* readLimiter, - size_t wordsUsed) - : SegmentReader(arena, id, ptr, readLimiter), pos(ptr.begin() + wordsUsed), readOnly(false) {} -inline SegmentBuilder::SegmentBuilder( - BuilderArena* arena, SegmentId id, kj::ArrayPtr ptr, ReadLimiter* readLimiter) - : SegmentReader(arena, id, ptr, readLimiter), - // const_cast is safe here because the member won't ever be dereferenced because it appears - // to point to the end of the segment anyway. - pos(const_cast(ptr.end())), - readOnly(true) {} -inline SegmentBuilder::SegmentBuilder(BuilderArena* arena, SegmentId id, decltype(nullptr), - ReadLimiter* readLimiter) - : SegmentReader(arena, id, nullptr, readLimiter), pos(nullptr), readOnly(false) {} - -inline word* SegmentBuilder::allocate(WordCount amount) { - if (intervalLength(pos, ptr.end()) < amount) { - // Not enough space in the segment for this allocation. - return nullptr; - } else { - // Success. - word* result = pos; - pos = pos + amount; - return result; - } -} - -inline void SegmentBuilder::checkWritable() { - if (KJ_UNLIKELY(readOnly)) throwNotWritable(); -} - -inline word* SegmentBuilder::getPtrUnchecked(WordCount offset) { - return const_cast(ptr.begin() + offset); -} - -inline BuilderArena* SegmentBuilder::getArena() { - // Down-cast safe because SegmentBuilder's constructor always initializes its SegmentReader base - // class with an Arena pointer that actually points to a BuilderArena. - return static_cast(arena); -} - -inline kj::ArrayPtr SegmentBuilder::currentlyAllocated() { - return kj::arrayPtr(ptr.begin(), pos - ptr.begin()); -} - -inline void SegmentBuilder::reset() { - word* start = getPtrUnchecked(0 * WORDS); - memset(start, 0, (pos - start) * sizeof(word)); - pos = start; -} - -inline void SegmentBuilder::tryTruncate(word* from, word* to) { - if (pos == from) pos = to; -} - -inline bool SegmentBuilder::tryExtend(word* from, word* to) { - // Careful about overflow. - if (pos == from && to <= ptr.end() && to >= from) { - pos = to; - return true; - } else { - return false; - } -} - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_ARENA_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. + +#ifndef CAPNP_ARENA_H_ +#define CAPNP_ARENA_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#ifndef CAPNP_PRIVATE +#error "This header is only meant to be included by Cap'n Proto's own source code." +#endif + +#include +#include +#include +#include +#include +#include "common.h" +#include "message.h" +#include "layout.h" +#include + +#if !CAPNP_LITE +#include "capability.h" +#endif // !CAPNP_LITE + +namespace capnp { + +#if !CAPNP_LITE +class ClientHook; +#endif // !CAPNP_LITE + +namespace _ { // private + +class SegmentReader; +class SegmentBuilder; +class Arena; +class BuilderArena; +class ReadLimiter; + +class Segment; +typedef kj::Id SegmentId; + +class ReadLimiter { + // Used to keep track of how much data has been processed from a message, and cut off further + // processing if and when a particular limit is reached. This is primarily intended to guard + // against maliciously-crafted messages which contain cycles or overlapping structures. Cycles + // and overlapping are not permitted by the Cap'n Proto format because in many cases they could + // be used to craft a deceptively small message which could consume excessive server resources to + // process, perhaps even sending it into an infinite loop. Actually detecting overlaps would be + // time-consuming, so instead we just keep track of how many words worth of data structures the + // receiver has actually dereferenced and error out if this gets too high. + // + // This counting takes place as you call getters (for non-primitive values) on the message + // readers. If you call the same getter twice, the data it returns may be double-counted. This + // should not be a big deal in most cases -- just set the read limit high enough that it will + // only trigger in unreasonable cases. + // + // This class is "safe" to use from multiple threads for its intended use case. Threads may + // overwrite each others' changes to the counter, but this is OK because it only means that the + // limit is enforced a bit less strictly -- it will still kick in eventually. + +public: + inline explicit ReadLimiter(); // No limit. + inline explicit ReadLimiter(WordCount64 limit); // Limit to the given number of words. + + inline void reset(WordCount64 limit); + + KJ_ALWAYS_INLINE(bool canRead(WordCount64 amount, Arena* arena)); + + void unread(WordCount64 amount); + // Adds back some words to the limit. Useful when the caller knows they are double-reading + // some data. + +private: + volatile uint64_t limit; + // Current limit, decremented each time catRead() is called. Volatile because multiple threads + // could be trying to modify it at once. (This is not real thread-safety, but good enough for + // the purpose of this class. See class comment.) + + KJ_DISALLOW_COPY(ReadLimiter); +}; + +#if !CAPNP_LITE +class BrokenCapFactory { + // Callback for constructing broken caps. We use this so that we can avoid arena.c++ having a + // link-time dependency on capability code that lives in libcapnp-rpc. + +public: + virtual kj::Own newBrokenCap(kj::StringPtr description) = 0; + virtual kj::Own newNullCap() = 0; +}; +#endif // !CAPNP_LITE + +class SegmentReader { +public: + inline SegmentReader(Arena* arena, SegmentId id, const word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter); + + KJ_ALWAYS_INLINE(const word* checkOffset(const word* from, ptrdiff_t offset)); + // Adds the given offset to the given pointer, checks that it is still within the bounds of the + // segment, then returns it. Note that the "end" pointer of the segment (which technically points + // to the word after the last in the segment) is considered in-bounds for this purpose, so you + // can't necessarily dereference it. You must call checkObject() next to check that the object + // you want to read is entirely in-bounds. + // + // If `from + offset` is out-of-range, this returns a pointer to the end of the segment. Thus, + // any non-zero-sized object will fail `checkObject()`. We do this instead of throwing to save + // some code footprint. + + KJ_ALWAYS_INLINE(bool checkObject(const word* start, WordCountN<31> size)); + // Assuming that `start` is in-bounds for this segment (probably checked using `checkOffset()`), + // check that `start + size` is also in-bounds, and hence the whole area in-between is valid. + + KJ_ALWAYS_INLINE(bool amplifiedRead(WordCount virtualAmount)); + // Indicates that the reader should pretend that `virtualAmount` additional data was read even + // though no actual pointer was traversed. This is used e.g. when reading a struct list pointer + // where the element sizes are zero -- the sender could set the list size arbitrarily high and + // cause the receiver to iterate over this list even though the message itself is small, so we + // need to defend against DoS attacks based on this. + + inline Arena* getArena(); + inline SegmentId getSegmentId(); + + inline const word* getStartPtr(); + inline SegmentWordCount getOffsetTo(const word* ptr); + inline SegmentWordCount getSize(); + + inline kj::ArrayPtr getArray(); + + inline void unread(WordCount64 amount); + // Add back some words to the ReadLimiter. + +private: + Arena* arena; + SegmentId id; + kj::ArrayPtr ptr; // size guaranteed to fit in SEGMENT_WORD_COUNT_BITS bits + ReadLimiter* readLimiter; + + KJ_DISALLOW_COPY(SegmentReader); + + friend class SegmentBuilder; + + static void abortCheckObjectFault(); + // Called in debug mode in cases that would segfault in opt mode. (Should be impossible!) +}; + +class SegmentBuilder: public SegmentReader { +public: + inline SegmentBuilder(BuilderArena* arena, SegmentId id, word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter, SegmentWordCount wordsUsed = ZERO * WORDS); + inline SegmentBuilder(BuilderArena* arena, SegmentId id, const word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter); + inline SegmentBuilder(BuilderArena* arena, SegmentId id, decltype(nullptr), + ReadLimiter* readLimiter); + + KJ_ALWAYS_INLINE(word* allocate(SegmentWordCount amount)); + + KJ_ALWAYS_INLINE(void checkWritable()); + // Throw an exception if the segment is read-only (meaning it is a reference to external data). + + KJ_ALWAYS_INLINE(word* getPtrUnchecked(SegmentWordCount offset)); + // Get a writable pointer into the segment. Throws an exception if the segment is read-only (i.e. + // a reference to external immutable data). + + inline BuilderArena* getArena(); + + inline kj::ArrayPtr currentlyAllocated(); + + inline void reset(); + + inline bool isWritable() { return !readOnly; } + + inline void tryTruncate(word* from, word* to); + // If `from` points just past the current end of the segment, then move the end back to `to`. + // Otherwise, do nothing. + + inline bool tryExtend(word* from, word* to); + // If `from` points just past the current end of the segment, and `to` is within the segment + // boundaries, then move the end up to `to` and return true. Otherwise, do nothing and return + // false. + +private: + word* pos; + // Pointer to a pointer to the current end point of the segment, i.e. the location where the + // next object should be allocated. + + bool readOnly; + + void throwNotWritable(); + + KJ_DISALLOW_COPY(SegmentBuilder); +}; + +class Arena { +public: + virtual ~Arena() noexcept(false); + + virtual SegmentReader* tryGetSegment(SegmentId id) = 0; + // Gets the segment with the given ID, or return nullptr if no such segment exists. + + virtual void reportReadLimitReached() = 0; + // Called to report that the read limit has been reached. See ReadLimiter, below. This invokes + // the VALIDATE_INPUT() macro which may throw an exception; if it returns normally, the caller + // will need to continue with default values. +}; + +class ReaderArena final: public Arena { +public: + explicit ReaderArena(MessageReader* message); + ~ReaderArena() noexcept(false); + KJ_DISALLOW_COPY(ReaderArena); + + // implements Arena ------------------------------------------------ + SegmentReader* tryGetSegment(SegmentId id) override; + void reportReadLimitReached() override; + +private: + MessageReader* message; + ReadLimiter readLimiter; + + // Optimize for single-segment messages so that small messages are handled quickly. + SegmentReader segment0; + + typedef std::unordered_map> SegmentMap; + kj::MutexGuarded>> moreSegments; + // We need to mutex-guard the segment map because we lazily initialize segments when they are + // first requested, but a Reader is allowed to be used concurrently in multiple threads. Luckily + // this only applies to large messages. + // + // TODO(perf): Thread-local thing instead? Some kind of lockless map? Or do sharing of data + // in a different way, where you have to construct a new MessageReader in each thread (but + // possibly backed by the same data)? + + ReaderArena(MessageReader* message, kj::ArrayPtr firstSegment); + ReaderArena(MessageReader* message, const word* firstSegment, SegmentWordCount firstSegmentSize); +}; + +class BuilderArena final: public Arena { + // A BuilderArena that does not allow the injection of capabilities. + +public: + explicit BuilderArena(MessageBuilder* message); + BuilderArena(MessageBuilder* message, kj::ArrayPtr segments); + ~BuilderArena() noexcept(false); + KJ_DISALLOW_COPY(BuilderArena); + + inline SegmentBuilder* getRootSegment() { return &segment0; } + + kj::ArrayPtr> getSegmentsForOutput(); + // Get an array of all the segments, suitable for writing out. This only returns the allocated + // portion of each segment, whereas tryGetSegment() returns something that includes + // not-yet-allocated space. + + inline CapTableBuilder* getLocalCapTable() { + // Return a CapTableBuilder that merely implements local loopback. That is, you can set + // capabilities, then read the same capabilities back, but there is no intent ever to transmit + // these capabilities. A MessageBuilder that isn't imbued with some other CapTable uses this + // by default. + // + // TODO(cleanup): It's sort of a hack that this exists. In theory, perhaps, unimbued + // MessageBuilders should throw exceptions on any attempt to access capability fields, like + // unimbued MessageReaders do. However, lots of code exists which uses MallocMessageBuilder + // as a temporary holder for data to be copied in and out (without being serialized), and it + // is expected that such data can include capabilities, which is admittedly reasonable. + // Therefore, all MessageBuilders must have a cap table by default. Arguably we should + // deprecate this usage and instead define a new helper type for this exact purpose. + + return &localCapTable; + } + + SegmentBuilder* getSegment(SegmentId id); + // Get the segment with the given id. Crashes or throws an exception if no such segment exists. + + struct AllocateResult { + SegmentBuilder* segment; + word* words; + }; + + AllocateResult allocate(SegmentWordCount amount); + // Find a segment with at least the given amount of space available and allocate the space. + // Note that allocating directly from a particular segment is much faster, but allocating from + // the arena is guaranteed to succeed. Therefore callers should try to allocate from a specific + // segment first if there is one, then fall back to the arena. + + SegmentBuilder* addExternalSegment(kj::ArrayPtr content); + // Add a new segment to the arena which points to some existing memory region. The segment is + // assumed to be completley full; the arena will never allocate from it. In fact, the segment + // is considered read-only. Any attempt to get a Builder pointing into this segment will throw + // an exception. Readers are allowed, however. + // + // This can be used to inject some external data into a message without a copy, e.g. embedding a + // large mmap'd file into a message as `Data` without forcing that data to actually be read in + // from disk (until the message itself is written out). `Orphanage` provides the public API for + // this feature. + + // implements Arena ------------------------------------------------ + SegmentReader* tryGetSegment(SegmentId id) override; + void reportReadLimitReached() override; + +private: + MessageBuilder* message; + ReadLimiter dummyLimiter; + + class LocalCapTable: public CapTableBuilder { +#if !CAPNP_LITE + public: + kj::Maybe> extractCap(uint index) override; + uint injectCap(kj::Own&& cap) override; + void dropCap(uint index) override; + + private: + kj::Vector>> capTable; +#endif // ! CAPNP_LITE + }; + + LocalCapTable localCapTable; + + SegmentBuilder segment0; + kj::ArrayPtr segment0ForOutput; + + struct MultiSegmentState { + kj::Vector> builders; + kj::Vector> forOutput; + }; + kj::Maybe> moreSegments; + + SegmentBuilder* segmentWithSpace = nullptr; + // When allocating, look for space in this segment first before resorting to allocating a new + // segment. This is not necessarily the last segment because addExternalSegment() may add a + // segment that is already-full, in which case we don't update this pointer. + + template // Can be `word` or `const word`. + SegmentBuilder* addSegmentInternal(kj::ArrayPtr content); +}; + +// ======================================================================================= + +inline ReadLimiter::ReadLimiter() + : limit(kj::maxValue) {} + +inline ReadLimiter::ReadLimiter(WordCount64 limit): limit(unbound(limit / WORDS)) {} + +inline void ReadLimiter::reset(WordCount64 limit) { this->limit = unbound(limit / WORDS); } + +inline bool ReadLimiter::canRead(WordCount64 amount, Arena* arena) { + // Be careful not to store an underflowed value into `limit`, even if multiple threads are + // decrementing it. + uint64_t current = limit; + if (KJ_UNLIKELY(unbound(amount / WORDS) > current)) { + arena->reportReadLimitReached(); + return false; + } else { + limit = current - unbound(amount / WORDS); + return true; + } +} + +// ------------------------------------------------------------------- + +inline SegmentReader::SegmentReader(Arena* arena, SegmentId id, const word* ptr, + SegmentWordCount size, ReadLimiter* readLimiter) + : arena(arena), id(id), ptr(kj::arrayPtr(ptr, unbound(size / WORDS))), + readLimiter(readLimiter) {} + +inline const word* SegmentReader::checkOffset(const word* from, ptrdiff_t offset) { + ptrdiff_t min = ptr.begin() - from; + ptrdiff_t max = ptr.end() - from; + if (offset >= min && offset <= max) { + return from + offset; + } else { + return ptr.end(); + } +} + +inline bool SegmentReader::checkObject(const word* start, WordCountN<31> size) { + auto startOffset = intervalLength(ptr.begin(), start, MAX_SEGMENT_WORDS); +#ifdef KJ_DEBUG + if (startOffset > bounded(ptr.size()) * WORDS) { + abortCheckObjectFault(); + } +#endif + return startOffset + size <= bounded(ptr.size()) * WORDS && + readLimiter->canRead(size, arena); +} + +inline bool SegmentReader::amplifiedRead(WordCount virtualAmount) { + return readLimiter->canRead(virtualAmount, arena); +} + +inline Arena* SegmentReader::getArena() { return arena; } +inline SegmentId SegmentReader::getSegmentId() { return id; } +inline const word* SegmentReader::getStartPtr() { return ptr.begin(); } +inline SegmentWordCount SegmentReader::getOffsetTo(const word* ptr) { + KJ_IREQUIRE(this->ptr.begin() <= ptr && ptr <= this->ptr.end()); + return intervalLength(this->ptr.begin(), ptr, MAX_SEGMENT_WORDS); +} +inline SegmentWordCount SegmentReader::getSize() { + return assumeBits(ptr.size()) * WORDS; +} +inline kj::ArrayPtr SegmentReader::getArray() { return ptr; } +inline void SegmentReader::unread(WordCount64 amount) { readLimiter->unread(amount); } + +// ------------------------------------------------------------------- + +inline SegmentBuilder::SegmentBuilder( + BuilderArena* arena, SegmentId id, word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter, SegmentWordCount wordsUsed) + : SegmentReader(arena, id, ptr, size, readLimiter), + pos(ptr + wordsUsed), readOnly(false) {} +inline SegmentBuilder::SegmentBuilder( + BuilderArena* arena, SegmentId id, const word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter) + : SegmentReader(arena, id, ptr, size, readLimiter), + // const_cast is safe here because the member won't ever be dereferenced because it appears + // to point to the end of the segment anyway. + pos(const_cast(ptr + size)), readOnly(true) {} +inline SegmentBuilder::SegmentBuilder(BuilderArena* arena, SegmentId id, decltype(nullptr), + ReadLimiter* readLimiter) + : SegmentReader(arena, id, nullptr, ZERO * WORDS, readLimiter), + pos(nullptr), readOnly(false) {} + +inline word* SegmentBuilder::allocate(SegmentWordCount amount) { + if (intervalLength(pos, ptr.end(), MAX_SEGMENT_WORDS) < amount) { + // Not enough space in the segment for this allocation. + return nullptr; + } else { + // Success. + word* result = pos; + pos = pos + amount; + return result; + } +} + +inline void SegmentBuilder::checkWritable() { + if (KJ_UNLIKELY(readOnly)) throwNotWritable(); +} + +inline word* SegmentBuilder::getPtrUnchecked(SegmentWordCount offset) { + return const_cast(ptr.begin() + offset); +} + +inline BuilderArena* SegmentBuilder::getArena() { + // Down-cast safe because SegmentBuilder's constructor always initializes its SegmentReader base + // class with an Arena pointer that actually points to a BuilderArena. + return static_cast(arena); +} + +inline kj::ArrayPtr SegmentBuilder::currentlyAllocated() { + return kj::arrayPtr(ptr.begin(), pos - ptr.begin()); +} + +inline void SegmentBuilder::reset() { + word* start = getPtrUnchecked(ZERO * WORDS); + memset(start, 0, (pos - start) * sizeof(word)); + pos = start; +} + +inline void SegmentBuilder::tryTruncate(word* from, word* to) { + if (pos == from) pos = to; +} + +inline bool SegmentBuilder::tryExtend(word* from, word* to) { + // Careful about overflow. + if (pos == from && to <= ptr.end() && to >= from) { + pos = to; + return true; + } else { + return false; + } +} + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_ARENA_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/blob.h --- a/win32-mingw/include/capnp/blob.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/blob.h Tue May 23 09:16:54 2017 +0100 @@ -1,220 +1,220 @@ -// 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. - -#ifndef CAPNP_BLOB_H_ -#define CAPNP_BLOB_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include -#include "common.h" -#include - -namespace capnp { - -struct Data { - Data() = delete; - class Reader; - class Builder; - class Pipeline {}; -}; - -struct Text { - Text() = delete; - class Reader; - class Builder; - class Pipeline {}; -}; - -class Data::Reader: public kj::ArrayPtr { - // Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple - // pointer which does not own its target, can be passed by value, etc. - -public: - typedef Data Reads; - - Reader() = default; - inline Reader(decltype(nullptr)): ArrayPtr(nullptr) {} - inline Reader(const byte* value, size_t size): ArrayPtr(value, size) {} - inline Reader(const kj::Array& value): ArrayPtr(value) {} - inline Reader(const ArrayPtr& value): ArrayPtr(value) {} - inline Reader(const kj::Array& value): ArrayPtr(value) {} - inline Reader(const ArrayPtr& value): ArrayPtr(value) {} -}; - -class Text::Reader: public kj::StringPtr { - // Like Data::Reader, but points at NUL-terminated UTF-8 text. The NUL terminator is not counted - // in the size but must be present immediately after the last byte. - // - // Text::Reader's interface contract is that its data MUST be NUL-terminated. The producer of - // the Text::Reader must guarantee this, so that the consumer need not check. The data SHOULD - // also be valid UTF-8, but this is NOT guaranteed -- the consumer must verify if it cares. - -public: - typedef Text Reads; - - Reader() = default; - inline Reader(decltype(nullptr)): StringPtr(nullptr) {} - inline Reader(const char* value): StringPtr(value) {} - inline Reader(const char* value, size_t size): StringPtr(value, size) {} - inline Reader(const kj::String& value): StringPtr(value) {} - inline Reader(const StringPtr& value): StringPtr(value) {} - -#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP - template ().c_str())> - inline Reader(const T& t): StringPtr(t) {} - // Allow implicit conversion from any class that has a c_str() method (namely, std::string). - // We use a template trick to detect std::string in order to avoid including the header for - // those who don't want it. -#endif -}; - -class Data::Builder: public kj::ArrayPtr { - // Like Data::Reader except the pointers aren't const. - -public: - typedef Data Builds; - - Builder() = default; - inline Builder(decltype(nullptr)): ArrayPtr(nullptr) {} - inline Builder(byte* value, size_t size): ArrayPtr(value, size) {} - inline Builder(kj::Array& value): ArrayPtr(value) {} - inline Builder(ArrayPtr value): ArrayPtr(value) {} - - inline Data::Reader asReader() const { return Data::Reader(*this); } - inline operator Reader() const { return asReader(); } -}; - -class Text::Builder: public kj::DisallowConstCopy { - // Basically identical to kj::StringPtr, except that the contents are non-const. - -public: - inline Builder(): content(nulstr, 1) {} - inline Builder(decltype(nullptr)): content(nulstr, 1) {} - inline Builder(char* value): content(value, strlen(value) + 1) {} - inline Builder(char* value, size_t size): content(value, size + 1) { - KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); - } - - inline Reader asReader() const { return Reader(content.begin(), content.size() - 1); } - inline operator Reader() const { return asReader(); } - - inline operator kj::ArrayPtr(); - inline kj::ArrayPtr asArray(); - inline operator kj::ArrayPtr() const; - inline kj::ArrayPtr asArray() const; - inline kj::ArrayPtr asBytes() { return asArray().asBytes(); } - inline kj::ArrayPtr asBytes() const { return asArray().asBytes(); } - // Result does not include NUL terminator. - - inline operator kj::StringPtr() const; - inline kj::StringPtr asString() const; - - inline const char* cStr() const { return content.begin(); } - // Returns NUL-terminated string. - - inline size_t size() const { return content.size() - 1; } - // Result does not include NUL terminator. - - inline char operator[](size_t index) const { return content[index]; } - inline char& operator[](size_t index) { return content[index]; } - - inline char* begin() { return content.begin(); } - inline char* end() { return content.end() - 1; } - inline const char* begin() const { return content.begin(); } - inline const char* end() const { return content.end() - 1; } - - inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } - inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } - - inline bool operator==(Builder other) const { return asString() == other.asString(); } - inline bool operator!=(Builder other) const { return asString() != other.asString(); } - inline bool operator< (Builder other) const { return asString() < other.asString(); } - inline bool operator> (Builder other) const { return asString() > other.asString(); } - inline bool operator<=(Builder other) const { return asString() <= other.asString(); } - inline bool operator>=(Builder other) const { return asString() >= other.asString(); } - - inline kj::StringPtr slice(size_t start) const; - inline kj::ArrayPtr slice(size_t start, size_t end) const; - inline Builder slice(size_t start); - inline kj::ArrayPtr slice(size_t start, size_t end); - // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter - // version that assumes end = size(). - -private: - inline explicit Builder(kj::ArrayPtr content): content(content) {} - - kj::ArrayPtr content; - - static char nulstr[1]; -}; - -inline kj::StringPtr KJ_STRINGIFY(Text::Builder builder) { - return builder.asString(); -} - -inline bool operator==(const char* a, const Text::Builder& b) { return a == b.asString(); } -inline bool operator!=(const char* a, const Text::Builder& b) { return a != b.asString(); } - -inline Text::Builder::operator kj::StringPtr() const { - return kj::StringPtr(content.begin(), content.size() - 1); -} - -inline kj::StringPtr Text::Builder::asString() const { - return kj::StringPtr(content.begin(), content.size() - 1); -} - -inline Text::Builder::operator kj::ArrayPtr() { - return content.slice(0, content.size() - 1); -} - -inline kj::ArrayPtr Text::Builder::asArray() { - return content.slice(0, content.size() - 1); -} - -inline Text::Builder::operator kj::ArrayPtr() const { - return content.slice(0, content.size() - 1); -} - -inline kj::ArrayPtr Text::Builder::asArray() const { - return content.slice(0, content.size() - 1); -} - -inline kj::StringPtr Text::Builder::slice(size_t start) const { - return asReader().slice(start); -} -inline kj::ArrayPtr Text::Builder::slice(size_t start, size_t end) const { - return content.slice(start, end); -} - -inline Text::Builder Text::Builder::slice(size_t start) { - return Text::Builder(content.slice(start, content.size())); -} -inline kj::ArrayPtr Text::Builder::slice(size_t start, size_t end) { - return content.slice(start, end); -} - -} // namespace capnp - -#endif // CAPNP_BLOB_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. + +#ifndef CAPNP_BLOB_H_ +#define CAPNP_BLOB_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include +#include +#include "common.h" +#include + +namespace capnp { + +struct Data { + Data() = delete; + class Reader; + class Builder; + class Pipeline {}; +}; + +struct Text { + Text() = delete; + class Reader; + class Builder; + class Pipeline {}; +}; + +class Data::Reader: public kj::ArrayPtr { + // Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple + // pointer which does not own its target, can be passed by value, etc. + +public: + typedef Data Reads; + + Reader() = default; + inline Reader(decltype(nullptr)): ArrayPtr(nullptr) {} + inline Reader(const byte* value, size_t size): ArrayPtr(value, size) {} + inline Reader(const kj::Array& value): ArrayPtr(value) {} + inline Reader(const ArrayPtr& value): ArrayPtr(value) {} + inline Reader(const kj::Array& value): ArrayPtr(value) {} + inline Reader(const ArrayPtr& value): ArrayPtr(value) {} +}; + +class Text::Reader: public kj::StringPtr { + // Like Data::Reader, but points at NUL-terminated UTF-8 text. The NUL terminator is not counted + // in the size but must be present immediately after the last byte. + // + // Text::Reader's interface contract is that its data MUST be NUL-terminated. The producer of + // the Text::Reader must guarantee this, so that the consumer need not check. The data SHOULD + // also be valid UTF-8, but this is NOT guaranteed -- the consumer must verify if it cares. + +public: + typedef Text Reads; + + Reader() = default; + inline Reader(decltype(nullptr)): StringPtr(nullptr) {} + inline Reader(const char* value): StringPtr(value) {} + inline Reader(const char* value, size_t size): StringPtr(value, size) {} + inline Reader(const kj::String& value): StringPtr(value) {} + inline Reader(const StringPtr& value): StringPtr(value) {} + +#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP + template ().c_str())> + inline Reader(const T& t): StringPtr(t) {} + // Allow implicit conversion from any class that has a c_str() method (namely, std::string). + // We use a template trick to detect std::string in order to avoid including the header for + // those who don't want it. +#endif +}; + +class Data::Builder: public kj::ArrayPtr { + // Like Data::Reader except the pointers aren't const. + +public: + typedef Data Builds; + + Builder() = default; + inline Builder(decltype(nullptr)): ArrayPtr(nullptr) {} + inline Builder(byte* value, size_t size): ArrayPtr(value, size) {} + inline Builder(kj::Array& value): ArrayPtr(value) {} + inline Builder(ArrayPtr value): ArrayPtr(value) {} + + inline Data::Reader asReader() const { return Data::Reader(*this); } + inline operator Reader() const { return asReader(); } +}; + +class Text::Builder: public kj::DisallowConstCopy { + // Basically identical to kj::StringPtr, except that the contents are non-const. + +public: + inline Builder(): content(nulstr, 1) {} + inline Builder(decltype(nullptr)): content(nulstr, 1) {} + inline Builder(char* value): content(value, strlen(value) + 1) {} + inline Builder(char* value, size_t size): content(value, size + 1) { + KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); + } + + inline Reader asReader() const { return Reader(content.begin(), content.size() - 1); } + inline operator Reader() const { return asReader(); } + + inline operator kj::ArrayPtr(); + inline kj::ArrayPtr asArray(); + inline operator kj::ArrayPtr() const; + inline kj::ArrayPtr asArray() const; + inline kj::ArrayPtr asBytes() { return asArray().asBytes(); } + inline kj::ArrayPtr asBytes() const { return asArray().asBytes(); } + // Result does not include NUL terminator. + + inline operator kj::StringPtr() const; + inline kj::StringPtr asString() const; + + inline const char* cStr() const { return content.begin(); } + // Returns NUL-terminated string. + + inline size_t size() const { return content.size() - 1; } + // Result does not include NUL terminator. + + inline char operator[](size_t index) const { return content[index]; } + inline char& operator[](size_t index) { return content[index]; } + + inline char* begin() { return content.begin(); } + inline char* end() { return content.end() - 1; } + inline const char* begin() const { return content.begin(); } + inline const char* end() const { return content.end() - 1; } + + inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } + inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } + + inline bool operator==(Builder other) const { return asString() == other.asString(); } + inline bool operator!=(Builder other) const { return asString() != other.asString(); } + inline bool operator< (Builder other) const { return asString() < other.asString(); } + inline bool operator> (Builder other) const { return asString() > other.asString(); } + inline bool operator<=(Builder other) const { return asString() <= other.asString(); } + inline bool operator>=(Builder other) const { return asString() >= other.asString(); } + + inline kj::StringPtr slice(size_t start) const; + inline kj::ArrayPtr slice(size_t start, size_t end) const; + inline Builder slice(size_t start); + inline kj::ArrayPtr slice(size_t start, size_t end); + // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter + // version that assumes end = size(). + +private: + inline explicit Builder(kj::ArrayPtr content): content(content) {} + + kj::ArrayPtr content; + + static char nulstr[1]; +}; + +inline kj::StringPtr KJ_STRINGIFY(Text::Builder builder) { + return builder.asString(); +} + +inline bool operator==(const char* a, const Text::Builder& b) { return a == b.asString(); } +inline bool operator!=(const char* a, const Text::Builder& b) { return a != b.asString(); } + +inline Text::Builder::operator kj::StringPtr() const { + return kj::StringPtr(content.begin(), content.size() - 1); +} + +inline kj::StringPtr Text::Builder::asString() const { + return kj::StringPtr(content.begin(), content.size() - 1); +} + +inline Text::Builder::operator kj::ArrayPtr() { + return content.slice(0, content.size() - 1); +} + +inline kj::ArrayPtr Text::Builder::asArray() { + return content.slice(0, content.size() - 1); +} + +inline Text::Builder::operator kj::ArrayPtr() const { + return content.slice(0, content.size() - 1); +} + +inline kj::ArrayPtr Text::Builder::asArray() const { + return content.slice(0, content.size() - 1); +} + +inline kj::StringPtr Text::Builder::slice(size_t start) const { + return asReader().slice(start); +} +inline kj::ArrayPtr Text::Builder::slice(size_t start, size_t end) const { + return content.slice(start, end); +} + +inline Text::Builder Text::Builder::slice(size_t start) { + return Text::Builder(content.slice(start, content.size())); +} +inline kj::ArrayPtr Text::Builder::slice(size_t start, size_t end) { + return content.slice(start, end); +} + +} // namespace capnp + +#endif // CAPNP_BLOB_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/c++.capnp.h --- a/win32-mingw/include/capnp/c++.capnp.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/c++.capnp.h Tue May 23 09:16:54 2017 +0100 @@ -1,33 +1,33 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: c++.capnp - -#ifndef CAPNP_INCLUDED_bdf87d7bb8304e81_ -#define CAPNP_INCLUDED_bdf87d7bb8304e81_ - -#include - -#if CAPNP_VERSION != 6000 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(b9c6f99ebf805f2c); -CAPNP_DECLARE_SCHEMA(f264a779fef191ce); - -} // namespace schemas -} // namespace capnp - -namespace capnp { -namespace annotations { - -// ======================================================================================= - -// ======================================================================================= - -} // namespace -} // namespace - -#endif // CAPNP_INCLUDED_bdf87d7bb8304e81_ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: c++.capnp + +#ifndef CAPNP_INCLUDED_bdf87d7bb8304e81_ +#define CAPNP_INCLUDED_bdf87d7bb8304e81_ + +#include + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(b9c6f99ebf805f2c); +CAPNP_DECLARE_SCHEMA(f264a779fef191ce); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace annotations { + +// ======================================================================================= + +// ======================================================================================= + +} // namespace +} // namespace + +#endif // CAPNP_INCLUDED_bdf87d7bb8304e81_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/capability.h --- a/win32-mingw/include/capnp/capability.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/capability.h Tue May 23 09:16:54 2017 +0100 @@ -1,885 +1,884 @@ -// 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. - -#ifndef CAPNP_CAPABILITY_H_ -#define CAPNP_CAPABILITY_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#if CAPNP_LITE -#error "RPC APIs, including this header, are not available in lite mode." -#endif - -#include -#include -#include "any.h" -#include "pointer-helpers.h" - -namespace capnp { - -template -class Response; - -template -class RemotePromise: public kj::Promise>, public T::Pipeline { - // A Promise which supports pipelined calls. T is typically a struct type. T must declare - // an inner "mix-in" type "Pipeline" which implements pipelining; RemotePromise simply - // multiply-inherits that type along with Promise>. T::Pipeline must be movable, - // but does not need to be copyable (i.e. just like Promise). - // - // The promise is for an owned pointer so that the RPC system can allocate the MessageReader - // itself. - -public: - inline RemotePromise(kj::Promise>&& promise, typename T::Pipeline&& pipeline) - : kj::Promise>(kj::mv(promise)), - T::Pipeline(kj::mv(pipeline)) {} - inline RemotePromise(decltype(nullptr)) - : kj::Promise>(nullptr), - T::Pipeline(nullptr) {} - KJ_DISALLOW_COPY(RemotePromise); - RemotePromise(RemotePromise&& other) = default; - RemotePromise& operator=(RemotePromise&& other) = default; -}; - -class LocalClient; -namespace _ { // private -struct RawSchema; -struct RawBrandedSchema; -extern const RawSchema NULL_INTERFACE_SCHEMA; // defined in schema.c++ -class CapabilityServerSetBase; -} // namespace _ (private) - -struct Capability { - // A capability without type-safe methods. Typed capability clients wrap `Client` and typed - // capability servers subclass `Server` to dispatch to the regular, typed methods. - - class Client; - class Server; - - struct _capnpPrivate { - struct IsInterface; - static constexpr uint64_t typeId = 0x3; - static constexpr Kind kind = Kind::INTERFACE; - static constexpr _::RawSchema const* schema = &_::NULL_INTERFACE_SCHEMA; - - static const _::RawBrandedSchema* const brand; - // Can't quite declare this one inline without including generated-header-support.h. Avoiding - // for now by declaring out-of-line. - // TODO(cleanup): Split RawSchema stuff into its own header that can be included here, or - // something. - }; -}; - -// ======================================================================================= -// Capability clients - -class RequestHook; -class ResponseHook; -class PipelineHook; -class ClientHook; - -template -class Request: public Params::Builder { - // A call that hasn't been sent yet. This class extends a Builder for the call's "Params" - // structure with a method send() that actually sends it. - // - // Given a Cap'n Proto method `foo(a :A, b :B): C`, the generated client interface will have - // a method `Request fooRequest()` (as well as a convenience method - // `RemotePromise foo(A::Reader a, B::Reader b)`). - -public: - inline Request(typename Params::Builder builder, kj::Own&& hook) - : Params::Builder(builder), hook(kj::mv(hook)) {} - inline Request(decltype(nullptr)): Params::Builder(nullptr) {} - - RemotePromise send() KJ_WARN_UNUSED_RESULT; - // Send the call and return a promise for the results. - -private: - kj::Own hook; - - friend class Capability::Client; - friend struct DynamicCapability; - template - friend class CallContext; - friend class RequestHook; -}; - -template -class Response: public Results::Reader { - // A completed call. This class extends a Reader for the call's answer structure. The Response - // is move-only -- once it goes out-of-scope, the underlying message will be freed. - -public: - inline Response(typename Results::Reader reader, kj::Own&& hook) - : Results::Reader(reader), hook(kj::mv(hook)) {} - -private: - kj::Own hook; - - template - friend class Request; - friend class ResponseHook; -}; - -class Capability::Client { - // Base type for capability clients. - -public: - typedef Capability Reads; - typedef Capability Calls; - - Client(decltype(nullptr)); - // If you need to declare a Client before you have anything to assign to it (perhaps because - // the assignment is going to occur in an if/else scope), you can start by initializing it to - // `nullptr`. The resulting client is not meant to be called and throws exceptions from all - // methods. - - template ()>> - Client(kj::Own&& server); - // Make a client capability that wraps the given server capability. The server's methods will - // only be executed in the given EventLoop, regardless of what thread calls the client's methods. - - template ()>> - Client(kj::Promise&& promise); - // Make a client from a promise for a future client. The resulting client queues calls until the - // promise resolves. - - Client(kj::Exception&& exception); - // Make a broken client that throws the given exception from all calls. - - Client(Client& other); - Client& operator=(Client& other); - // Copies by reference counting. Warning: This refcounting is not thread-safe. All copies of - // the client must remain in one thread. - - Client(Client&&) = default; - Client& operator=(Client&&) = default; - // Move constructor avoids reference counting. - - explicit Client(kj::Own&& hook); - // For use by the RPC implementation: Wrap a ClientHook. - - template - typename T::Client castAs(); - // Reinterpret the capability as implementing the given interface. Note that no error will occur - // here if the capability does not actually implement this interface, but later method calls will - // fail. It's up to the application to decide how indicate that additional interfaces are - // supported. - // - // TODO(perf): GCC 4.8 / Clang 3.3: rvalue-qualified version for better performance. - - template - typename T::Client castAs(InterfaceSchema schema); - // Dynamic version. `T` must be `DynamicCapability`, and you must `#include `. - - kj::Promise whenResolved(); - // If the capability is actually only a promise, the returned promise resolves once the - // capability itself has resolved to its final destination (or propagates the exception if - // the capability promise is rejected). This is mainly useful for error-checking in the case - // where no calls are being made. There is no reason to wait for this before making calls; if - // the capability does not resolve, the call results will propagate the error. - - Request typelessRequest( - uint64_t interfaceId, uint16_t methodId, - kj::Maybe sizeHint); - // Make a request without knowing the types of the params or results. You specify the type ID - // and method number manually. - - // TODO(someday): method(s) for Join - -protected: - Client() = default; - - template - Request newCall(uint64_t interfaceId, uint16_t methodId, - kj::Maybe sizeHint); - -private: - kj::Own hook; - - static kj::Own makeLocalClient(kj::Own&& server); - - template - friend struct _::PointerHelpers; - friend struct DynamicCapability; - friend class Orphanage; - friend struct DynamicStruct; - friend struct DynamicList; - template - friend struct List; - friend class _::CapabilityServerSetBase; - friend class ClientHook; -}; - -// ======================================================================================= -// Capability servers - -class CallContextHook; - -template -class CallContext: public kj::DisallowConstCopy { - // Wrapper around CallContextHook with a specific return type. - // - // Methods of this class may only be called from within the server's event loop, not from other - // threads. - // - // The CallContext becomes invalid as soon as the call reports completion. - -public: - explicit CallContext(CallContextHook& hook); - - typename Params::Reader getParams(); - // Get the params payload. - - void releaseParams(); - // Release the params payload. getParams() will throw an exception after this is called. - // Releasing the params may allow the RPC system to free up buffer space to handle other - // requests. Long-running asynchronous methods should try to call this as early as is - // convenient. - - typename Results::Builder getResults(kj::Maybe sizeHint = nullptr); - typename Results::Builder initResults(kj::Maybe sizeHint = nullptr); - void setResults(typename Results::Reader value); - void adoptResults(Orphan&& value); - Orphanage getResultsOrphanage(kj::Maybe sizeHint = nullptr); - // Manipulate the results payload. The "Return" message (part of the RPC protocol) will - // typically be allocated the first time one of these is called. Some RPC systems may - // allocate these messages in a limited space (such as a shared memory segment), therefore the - // application should delay calling these as long as is convenient to do so (but don't delay - // if doing so would require extra copies later). - // - // `sizeHint` indicates a guess at the message size. This will usually be used to decide how - // much space to allocate for the first message segment (don't worry: only space that is actually - // used will be sent on the wire). If omitted, the system decides. The message root pointer - // should not be included in the size. So, if you are simply going to copy some existing message - // directly into the results, just call `.totalSize()` and pass that in. - - template - kj::Promise tailCall(Request&& tailRequest); - // Resolve the call by making a tail call. `tailRequest` is a request that has been filled in - // but not yet sent. The context will send the call, then fill in the results with the result - // of the call. If tailCall() is used, {get,init,set,adopt}Results (above) *must not* be called. - // - // The RPC implementation may be able to optimize a tail call to another machine such that the - // results never actually pass through this machine. Even if no such optimization is possible, - // `tailCall()` may allow pipelined calls to be forwarded optimistically to the new call site. - // - // In general, this should be the last thing a method implementation calls, and the promise - // returned from `tailCall()` should then be returned by the method implementation. - - void allowCancellation(); - // Indicate that it is OK for the RPC system to discard its Promise for this call's result if - // the caller cancels the call, thereby transitively canceling any asynchronous operations the - // call implementation was performing. This is not done by default because it could represent a - // security risk: applications must be carefully written to ensure that they do not end up in - // a bad state if an operation is canceled at an arbitrary point. However, for long-running - // method calls that hold significant resources, prompt cancellation is often useful. - // - // Keep in mind that asynchronous cancellation cannot occur while the method is synchronously - // executing on a local thread. The method must perform an asynchronous operation or call - // `EventLoop::current().evalLater()` to yield control. - // - // Note: You might think that we should offer `onCancel()` and/or `isCanceled()` methods that - // provide notification when the caller cancels the request without forcefully killing off the - // promise chain. Unfortunately, this composes poorly with promise forking: the canceled - // path may be just one branch of a fork of the result promise. The other branches still want - // the call to continue. Promise forking is used within the Cap'n Proto implementation -- in - // particular each pipelined call forks the result promise. So, if a caller made a pipelined - // call and then dropped the original object, the call should not be canceled, but it would be - // excessively complicated for the framework to avoid notififying of cancellation as long as - // pipelined calls still exist. - -private: - CallContextHook* hook; - - friend class Capability::Server; - friend struct DynamicCapability; -}; - -class Capability::Server { - // Objects implementing a Cap'n Proto interface must subclass this. Typically, such objects - // will instead subclass a typed Server interface which will take care of implementing - // dispatchCall(). - -public: - typedef Capability Serves; - - virtual kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, - CallContext context) = 0; - // Call the given method. `params` is the input struct, and should be released as soon as it - // is no longer needed. `context` may be used to allocate the output struct and deal with - // cancellation. - - // TODO(someday): Method which can optionally be overridden to implement Join when the object is - // a proxy. - -protected: - inline Capability::Client thisCap(); - // Get a capability pointing to this object, much like the `this` keyword. - // - // The effect of this method is undefined if: - // - No capability client has been created pointing to this object. (This is always the case in - // the server's constructor.) - // - The capability client pointing at this object has been destroyed. (This is always the case - // in the server's destructor.) - // - Multiple capability clients have been created around the same server (possible if the server - // is refcounted, which is not recommended since the client itself provides refcounting). - - template - CallContext internalGetTypedContext( - CallContext typeless); - kj::Promise internalUnimplemented(const char* actualInterfaceName, - uint64_t requestedTypeId); - kj::Promise internalUnimplemented(const char* interfaceName, - uint64_t typeId, uint16_t methodId); - kj::Promise internalUnimplemented(const char* interfaceName, const char* methodName, - uint64_t typeId, uint16_t methodId); - -private: - ClientHook* thisHook = nullptr; - friend class LocalClient; -}; - -// ======================================================================================= - -class ReaderCapabilityTable: private _::CapTableReader { - // Class which imbues Readers with the ability to read capabilities. - // - // In Cap'n Proto format, the encoding of a capability pointer is simply an integer index into - // an external table. Since these pointers fundamentally point outside the message, a - // MessageReader by default has no idea what they point at, and therefore reading capabilities - // from such a reader will throw exceptions. - // - // In order to be able to read capabilities, you must first attach a capability table, using - // this class. By "imbuing" a Reader, you get a new Reader which will interpret capability - // pointers by treating them as indexes into the ReaderCapabilityTable. - // - // Note that when using Cap'n Proto's RPC system, this is handled automatically. - -public: - explicit ReaderCapabilityTable(kj::Array>> table); - KJ_DISALLOW_COPY(ReaderCapabilityTable); - - template - T imbue(T reader); - // Return a reader equivalent to `reader` except that when reading capability-valued fields, - // the capabilities are looked up in this table. - -private: - kj::Array>> table; - - kj::Maybe> extractCap(uint index) override; -}; - -class BuilderCapabilityTable: private _::CapTableBuilder { - // Class which imbues Builders with the ability to read and write capabilities. - // - // This is much like ReaderCapabilityTable, except for builders. The table starts out empty, - // but capabilities can be added to it over time. - -public: - BuilderCapabilityTable(); - KJ_DISALLOW_COPY(BuilderCapabilityTable); - - inline kj::ArrayPtr>> getTable() { return table; } - - template - T imbue(T builder); - // Return a builder equivalent to `builder` except that when reading capability-valued fields, - // the capabilities are looked up in this table. - -private: - kj::Vector>> table; - - kj::Maybe> extractCap(uint index) override; - uint injectCap(kj::Own&& cap) override; - void dropCap(uint index) override; -}; - -// ======================================================================================= - -namespace _ { // private - -class CapabilityServerSetBase { -public: - Capability::Client addInternal(kj::Own&& server, void* ptr); - kj::Promise getLocalServerInternal(Capability::Client& client); -}; - -} // namespace _ (private) - -template -class CapabilityServerSet: private _::CapabilityServerSetBase { - // Allows a server to recognize its own capabilities when passed back to it, and obtain the - // underlying Server objects associated with them. - // - // All objects in the set must have the same interface type T. The objects may implement various - // interfaces derived from T (and in fact T can be `capnp::Capability` to accept all objects), - // but note that if you compile with RTTI disabled then you will not be able to down-cast through - // virtual inheritance, and all inheritance between server interfaces is virtual. So, with RTTI - // disabled, you will likely need to set T to be the most-derived Cap'n Proto interface type, - // and you server class will need to be directly derived from that, so that you can use - // static_cast (or kj::downcast) to cast to it after calling getLocalServer(). (If you compile - // with RTTI, then you can freely dynamic_cast and ignore this issue!) - -public: - CapabilityServerSet() = default; - KJ_DISALLOW_COPY(CapabilityServerSet); - - typename T::Client add(kj::Own&& server); - // Create a new capability Client for the given Server and also add this server to the set. - - kj::Promise> getLocalServer(typename T::Client& client); - // Given a Client pointing to a server previously passed to add(), return the corresponding - // Server. This returns a promise because if the input client is itself a promise, this must - // wait for it to resolve. Keep in mind that the server will be deleted when all clients are - // gone, so the caller should make sure to keep the client alive (hence why this method only - // accepts an lvalue input). -}; - -// ======================================================================================= -// Hook interfaces which must be implemented by the RPC system. Applications never call these -// directly; the RPC system implements them and the types defined earlier in this file wrap them. - -class RequestHook { - // Hook interface implemented by RPC system representing a request being built. - -public: - virtual RemotePromise send() = 0; - // Send the call and return a promise for the result. - - virtual const void* getBrand() = 0; - // Returns a void* that identifies who made this request. This can be used by an RPC adapter to - // discover when tail call is going to be sent over its own connection and therefore can be - // optimized into a remote tail call. - - template - inline static kj::Own from(Request&& request) { - return kj::mv(request.hook); - } -}; - -class ResponseHook { - // Hook interface implemented by RPC system representing a response. - // - // At present this class has no methods. It exists only for garbage collection -- when the - // ResponseHook is destroyed, the results can be freed. - -public: - virtual ~ResponseHook() noexcept(false); - // Just here to make sure the type is dynamic. - - template - inline static kj::Own from(Response&& response) { - return kj::mv(response.hook); - } -}; - -// class PipelineHook is declared in any.h because it is needed there. - -class ClientHook { -public: - ClientHook(); - - virtual Request newCall( - uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint) = 0; - // Start a new call, allowing the client to allocate request/response objects as it sees fit. - // This version is used when calls are made from application code in the local process. - - struct VoidPromiseAndPipeline { - kj::Promise promise; - kj::Own pipeline; - }; - - virtual VoidPromiseAndPipeline call(uint64_t interfaceId, uint16_t methodId, - kj::Own&& context) = 0; - // Call the object, but the caller controls allocation of the request/response objects. If the - // callee insists on allocating these objects itself, it must make a copy. This version is used - // when calls come in over the network via an RPC system. Note that even if the returned - // `Promise` is discarded, the call may continue executing if any pipelined calls are - // waiting for it. - // - // Since the caller of this method chooses the CallContext implementation, it is the caller's - // responsibility to ensure that the returned promise is not canceled unless allowed via - // the context's `allowCancellation()`. - // - // The call must not begin synchronously; the callee must arrange for the call to begin in a - // later turn of the event loop. Otherwise, application code may call back and affect the - // callee's state in an unexpected way. - - virtual kj::Maybe getResolved() = 0; - // If this ClientHook is a promise that has already resolved, returns the inner, resolved version - // of the capability. The caller may permanently replace this client with the resolved one if - // desired. Returns null if the client isn't a promise or hasn't resolved yet -- use - // `whenMoreResolved()` to distinguish between them. - - virtual kj::Maybe>> whenMoreResolved() = 0; - // If this client is a settled reference (not a promise), return nullptr. Otherwise, return a - // promise that eventually resolves to a new client that is closer to being the final, settled - // client (i.e. the value eventually returned by `getResolved()`). Calling this repeatedly - // should eventually produce a settled client. - - kj::Promise whenResolved(); - // Repeatedly calls whenMoreResolved() until it returns nullptr. - - virtual kj::Own addRef() = 0; - // Return a new reference to the same capability. - - virtual const void* getBrand() = 0; - // Returns a void* that identifies who made this client. This can be used by an RPC adapter to - // discover when a capability it needs to marshal is one that it created in the first place, and - // therefore it can transfer the capability without proxying. - - static const uint NULL_CAPABILITY_BRAND; - // Value is irrelevant; used for pointer. - - inline bool isNull() { return getBrand() == &NULL_CAPABILITY_BRAND; } - // Returns true if the capability was created as a result of assigning a Client to null or by - // reading a null pointer out of a Cap'n Proto message. - - virtual void* getLocalServer(_::CapabilityServerSetBase& capServerSet); - // If this is a local capability created through `capServerSet`, return the underlying Server. - // Otherwise, return nullptr. Default implementation (which everyone except LocalClient should - // use) always returns nullptr. - - static kj::Own from(Capability::Client client) { return kj::mv(client.hook); } -}; - -class CallContextHook { - // Hook interface implemented by RPC system to manage a call on the server side. See - // CallContext. - -public: - virtual AnyPointer::Reader getParams() = 0; - virtual void releaseParams() = 0; - virtual AnyPointer::Builder getResults(kj::Maybe sizeHint) = 0; - virtual kj::Promise tailCall(kj::Own&& request) = 0; - virtual void allowCancellation() = 0; - - virtual kj::Promise onTailCall() = 0; - // If `tailCall()` is called, resolves to the PipelineHook from the tail call. An - // implementation of `ClientHook::call()` is allowed to call this at most once. - - virtual ClientHook::VoidPromiseAndPipeline directTailCall(kj::Own&& request) = 0; - // Call this when you would otherwise call onTailCall() immediately followed by tailCall(). - // Implementations of tailCall() should typically call directTailCall() and then fulfill the - // promise fulfiller for onTailCall() with the returned pipeline. - - virtual kj::Own addRef() = 0; -}; - -kj::Own newLocalPromiseClient(kj::Promise>&& promise); -// Returns a ClientHook that queues up calls until `promise` resolves, then forwards them to -// the new client. This hook's `getResolved()` and `whenMoreResolved()` methods will reflect the -// redirection to the eventual replacement client. - -kj::Own newLocalPromisePipeline(kj::Promise>&& promise); -// Returns a PipelineHook that queues up calls until `promise` resolves, then forwards them to -// the new pipeline. - -kj::Own newBrokenCap(kj::StringPtr reason); -kj::Own newBrokenCap(kj::Exception&& reason); -// Helper function that creates a capability which simply throws exceptions when called. - -kj::Own newBrokenPipeline(kj::Exception&& reason); -// Helper function that creates a pipeline which simply throws exceptions when called. - -Request newBrokenRequest( - kj::Exception&& reason, kj::Maybe sizeHint); -// Helper function that creates a Request object that simply throws exceptions when sent. - -// ======================================================================================= -// Extend PointerHelpers for interfaces - -namespace _ { // private - -template -struct PointerHelpers { - static inline typename T::Client get(PointerReader reader) { - return typename T::Client(reader.getCapability()); - } - static inline typename T::Client get(PointerBuilder builder) { - return typename T::Client(builder.getCapability()); - } - static inline void set(PointerBuilder builder, typename T::Client&& value) { - builder.setCapability(kj::mv(value.Capability::Client::hook)); - } - static inline void set(PointerBuilder builder, typename T::Client& value) { - builder.setCapability(value.Capability::Client::hook->addRef()); - } - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } -}; - -} // namespace _ (private) - -// ======================================================================================= -// Extend List for interfaces - -template -struct List { - List() = delete; - - class Reader { - public: - typedef List Reads; - - Reader() = default; - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return reader.size() / ELEMENTS; } - inline typename T::Client operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return typename T::Client(reader.getPointerElement(index * ELEMENTS).getCapability()); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - Builder() = delete; - inline Builder(decltype(nullptr)) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return builder.size() / ELEMENTS; } - inline typename T::Client operator[](uint index) { - KJ_IREQUIRE(index < size()); - return typename T::Client(builder.getPointerElement(index * ELEMENTS).getCapability()); - } - inline void set(uint index, typename T::Client value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(index * ELEMENTS).setCapability(kj::mv(value.hook)); - } - inline void adopt(uint index, Orphan&& value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(index * ELEMENTS).adopt(kj::mv(value)); - } - inline Orphan disown(uint index) { - KJ_IREQUIRE(index < size()); - return Orphan(builder.getPointerElement(index * ELEMENTS).disown()); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initList(ElementSize::POINTER, size * ELEMENTS); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getList(ElementSize::POINTER, defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(ElementSize::POINTER, defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -// ======================================================================================= -// Inline implementation details - -template -RemotePromise Request::send() { - auto typelessPromise = hook->send(); - hook = nullptr; // prevent reuse - - // Convert the Promise to return the correct response type. - // Explicitly upcast to kj::Promise to make clear that calling .then() doesn't invalidate the - // Pipeline part of the RemotePromise. - auto typedPromise = kj::implicitCast>&>(typelessPromise) - .then([](Response&& response) -> Response { - return Response(response.getAs(), kj::mv(response.hook)); - }); - - // Wrap the typeless pipeline in a typed wrapper. - typename Results::Pipeline typedPipeline( - kj::mv(kj::implicitCast(typelessPromise))); - - return RemotePromise(kj::mv(typedPromise), kj::mv(typedPipeline)); -} - -inline Capability::Client::Client(kj::Own&& hook): hook(kj::mv(hook)) {} -template -inline Capability::Client::Client(kj::Own&& server) - : hook(makeLocalClient(kj::mv(server))) {} -template -inline Capability::Client::Client(kj::Promise&& promise) - : hook(newLocalPromiseClient(promise.then([](T&& t) { return kj::mv(t.hook); }))) {} -inline Capability::Client::Client(Client& other): hook(other.hook->addRef()) {} -inline Capability::Client& Capability::Client::operator=(Client& other) { - hook = other.hook->addRef(); - return *this; -} -template -inline typename T::Client Capability::Client::castAs() { - return typename T::Client(hook->addRef()); -} -inline kj::Promise Capability::Client::whenResolved() { - return hook->whenResolved(); -} -inline Request Capability::Client::typelessRequest( - uint64_t interfaceId, uint16_t methodId, - kj::Maybe sizeHint) { - return newCall(interfaceId, methodId, sizeHint); -} -template -inline Request Capability::Client::newCall( - uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint) { - auto typeless = hook->newCall(interfaceId, methodId, sizeHint); - return Request(typeless.template getAs(), kj::mv(typeless.hook)); -} - -template -inline CallContext::CallContext(CallContextHook& hook): hook(&hook) {} -template -inline typename Params::Reader CallContext::getParams() { - return hook->getParams().template getAs(); -} -template -inline void CallContext::releaseParams() { - hook->releaseParams(); -} -template -inline typename Results::Builder CallContext::getResults( - kj::Maybe sizeHint) { - // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 - return hook->getResults(sizeHint).template getAs(); -} -template -inline typename Results::Builder CallContext::initResults( - kj::Maybe sizeHint) { - // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 - return hook->getResults(sizeHint).template initAs(); -} -template -inline void CallContext::setResults(typename Results::Reader value) { - hook->getResults(value.totalSize()).template setAs(value); -} -template -inline void CallContext::adoptResults(Orphan&& value) { - hook->getResults(nullptr).adopt(kj::mv(value)); -} -template -inline Orphanage CallContext::getResultsOrphanage( - kj::Maybe sizeHint) { - return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); -} -template -template -inline kj::Promise CallContext::tailCall( - Request&& tailRequest) { - return hook->tailCall(kj::mv(tailRequest.hook)); -} -template -inline void CallContext::allowCancellation() { - hook->allowCancellation(); -} - -template -CallContext Capability::Server::internalGetTypedContext( - CallContext typeless) { - return CallContext(*typeless.hook); -} - -Capability::Client Capability::Server::thisCap() { - return Client(thisHook->addRef()); -} - -template -T ReaderCapabilityTable::imbue(T reader) { - return T(_::PointerHelpers>::getInternalReader(reader).imbue(this)); -} - -template -T BuilderCapabilityTable::imbue(T builder) { - return T(_::PointerHelpers>::getInternalBuilder(kj::mv(builder)).imbue(this)); -} - -template -typename T::Client CapabilityServerSet::add(kj::Own&& server) { - void* ptr = reinterpret_cast(server.get()); - // Clang insists that `castAs` is a template-dependent member and therefore we need the - // `template` keyword here, but AFAICT this is wrong: addImpl() is not a template. - return addInternal(kj::mv(server), ptr).template castAs(); -} - -template -kj::Promise> CapabilityServerSet::getLocalServer( - typename T::Client& client) { - return getLocalServerInternal(client) - .then([](void* server) -> kj::Maybe { - if (server == nullptr) { - return nullptr; - } else { - return *reinterpret_cast(server); - } - }); -} - -template -struct Orphanage::GetInnerReader { - static inline kj::Own apply(typename T::Client t) { - return ClientHook::from(kj::mv(t)); - } -}; - -} // namespace capnp - -#endif // CAPNP_CAPABILITY_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. + +#ifndef CAPNP_CAPABILITY_H_ +#define CAPNP_CAPABILITY_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#if CAPNP_LITE +#error "RPC APIs, including this header, are not available in lite mode." +#endif + +#include +#include +#include "raw-schema.h" +#include "any.h" +#include "pointer-helpers.h" + +namespace capnp { + +template +class Response; + +template +class RemotePromise: public kj::Promise>, public T::Pipeline { + // A Promise which supports pipelined calls. T is typically a struct type. T must declare + // an inner "mix-in" type "Pipeline" which implements pipelining; RemotePromise simply + // multiply-inherits that type along with Promise>. T::Pipeline must be movable, + // but does not need to be copyable (i.e. just like Promise). + // + // The promise is for an owned pointer so that the RPC system can allocate the MessageReader + // itself. + +public: + inline RemotePromise(kj::Promise>&& promise, typename T::Pipeline&& pipeline) + : kj::Promise>(kj::mv(promise)), + T::Pipeline(kj::mv(pipeline)) {} + inline RemotePromise(decltype(nullptr)) + : kj::Promise>(nullptr), + T::Pipeline(nullptr) {} + KJ_DISALLOW_COPY(RemotePromise); + RemotePromise(RemotePromise&& other) = default; + RemotePromise& operator=(RemotePromise&& other) = default; +}; + +class LocalClient; +namespace _ { // private +extern const RawSchema NULL_INTERFACE_SCHEMA; // defined in schema.c++ +class CapabilityServerSetBase; +} // namespace _ (private) + +struct Capability { + // A capability without type-safe methods. Typed capability clients wrap `Client` and typed + // capability servers subclass `Server` to dispatch to the regular, typed methods. + + class Client; + class Server; + + struct _capnpPrivate { + struct IsInterface; + static constexpr uint64_t typeId = 0x3; + static constexpr Kind kind = Kind::INTERFACE; + static constexpr _::RawSchema const* schema = &_::NULL_INTERFACE_SCHEMA; + + static const _::RawBrandedSchema* brand() { + return &_::NULL_INTERFACE_SCHEMA.defaultBrand; + } + }; +}; + +// ======================================================================================= +// Capability clients + +class RequestHook; +class ResponseHook; +class PipelineHook; +class ClientHook; + +template +class Request: public Params::Builder { + // A call that hasn't been sent yet. This class extends a Builder for the call's "Params" + // structure with a method send() that actually sends it. + // + // Given a Cap'n Proto method `foo(a :A, b :B): C`, the generated client interface will have + // a method `Request fooRequest()` (as well as a convenience method + // `RemotePromise foo(A::Reader a, B::Reader b)`). + +public: + inline Request(typename Params::Builder builder, kj::Own&& hook) + : Params::Builder(builder), hook(kj::mv(hook)) {} + inline Request(decltype(nullptr)): Params::Builder(nullptr) {} + + RemotePromise send() KJ_WARN_UNUSED_RESULT; + // Send the call and return a promise for the results. + +private: + kj::Own hook; + + friend class Capability::Client; + friend struct DynamicCapability; + template + friend class CallContext; + friend class RequestHook; +}; + +template +class Response: public Results::Reader { + // A completed call. This class extends a Reader for the call's answer structure. The Response + // is move-only -- once it goes out-of-scope, the underlying message will be freed. + +public: + inline Response(typename Results::Reader reader, kj::Own&& hook) + : Results::Reader(reader), hook(kj::mv(hook)) {} + +private: + kj::Own hook; + + template + friend class Request; + friend class ResponseHook; +}; + +class Capability::Client { + // Base type for capability clients. + +public: + typedef Capability Reads; + typedef Capability Calls; + + Client(decltype(nullptr)); + // If you need to declare a Client before you have anything to assign to it (perhaps because + // the assignment is going to occur in an if/else scope), you can start by initializing it to + // `nullptr`. The resulting client is not meant to be called and throws exceptions from all + // methods. + + template ()>> + Client(kj::Own&& server); + // Make a client capability that wraps the given server capability. The server's methods will + // only be executed in the given EventLoop, regardless of what thread calls the client's methods. + + template ()>> + Client(kj::Promise&& promise); + // Make a client from a promise for a future client. The resulting client queues calls until the + // promise resolves. + + Client(kj::Exception&& exception); + // Make a broken client that throws the given exception from all calls. + + Client(Client& other); + Client& operator=(Client& other); + // Copies by reference counting. Warning: This refcounting is not thread-safe. All copies of + // the client must remain in one thread. + + Client(Client&&) = default; + Client& operator=(Client&&) = default; + // Move constructor avoids reference counting. + + explicit Client(kj::Own&& hook); + // For use by the RPC implementation: Wrap a ClientHook. + + template + typename T::Client castAs(); + // Reinterpret the capability as implementing the given interface. Note that no error will occur + // here if the capability does not actually implement this interface, but later method calls will + // fail. It's up to the application to decide how indicate that additional interfaces are + // supported. + // + // TODO(perf): GCC 4.8 / Clang 3.3: rvalue-qualified version for better performance. + + template + typename T::Client castAs(InterfaceSchema schema); + // Dynamic version. `T` must be `DynamicCapability`, and you must `#include `. + + kj::Promise whenResolved(); + // If the capability is actually only a promise, the returned promise resolves once the + // capability itself has resolved to its final destination (or propagates the exception if + // the capability promise is rejected). This is mainly useful for error-checking in the case + // where no calls are being made. There is no reason to wait for this before making calls; if + // the capability does not resolve, the call results will propagate the error. + + Request typelessRequest( + uint64_t interfaceId, uint16_t methodId, + kj::Maybe sizeHint); + // Make a request without knowing the types of the params or results. You specify the type ID + // and method number manually. + + // TODO(someday): method(s) for Join + +protected: + Client() = default; + + template + Request newCall(uint64_t interfaceId, uint16_t methodId, + kj::Maybe sizeHint); + +private: + kj::Own hook; + + static kj::Own makeLocalClient(kj::Own&& server); + + template + friend struct _::PointerHelpers; + friend struct DynamicCapability; + friend class Orphanage; + friend struct DynamicStruct; + friend struct DynamicList; + template + friend struct List; + friend class _::CapabilityServerSetBase; + friend class ClientHook; +}; + +// ======================================================================================= +// Capability servers + +class CallContextHook; + +template +class CallContext: public kj::DisallowConstCopy { + // Wrapper around CallContextHook with a specific return type. + // + // Methods of this class may only be called from within the server's event loop, not from other + // threads. + // + // The CallContext becomes invalid as soon as the call reports completion. + +public: + explicit CallContext(CallContextHook& hook); + + typename Params::Reader getParams(); + // Get the params payload. + + void releaseParams(); + // Release the params payload. getParams() will throw an exception after this is called. + // Releasing the params may allow the RPC system to free up buffer space to handle other + // requests. Long-running asynchronous methods should try to call this as early as is + // convenient. + + typename Results::Builder getResults(kj::Maybe sizeHint = nullptr); + typename Results::Builder initResults(kj::Maybe sizeHint = nullptr); + void setResults(typename Results::Reader value); + void adoptResults(Orphan&& value); + Orphanage getResultsOrphanage(kj::Maybe sizeHint = nullptr); + // Manipulate the results payload. The "Return" message (part of the RPC protocol) will + // typically be allocated the first time one of these is called. Some RPC systems may + // allocate these messages in a limited space (such as a shared memory segment), therefore the + // application should delay calling these as long as is convenient to do so (but don't delay + // if doing so would require extra copies later). + // + // `sizeHint` indicates a guess at the message size. This will usually be used to decide how + // much space to allocate for the first message segment (don't worry: only space that is actually + // used will be sent on the wire). If omitted, the system decides. The message root pointer + // should not be included in the size. So, if you are simply going to copy some existing message + // directly into the results, just call `.totalSize()` and pass that in. + + template + kj::Promise tailCall(Request&& tailRequest); + // Resolve the call by making a tail call. `tailRequest` is a request that has been filled in + // but not yet sent. The context will send the call, then fill in the results with the result + // of the call. If tailCall() is used, {get,init,set,adopt}Results (above) *must not* be called. + // + // The RPC implementation may be able to optimize a tail call to another machine such that the + // results never actually pass through this machine. Even if no such optimization is possible, + // `tailCall()` may allow pipelined calls to be forwarded optimistically to the new call site. + // + // In general, this should be the last thing a method implementation calls, and the promise + // returned from `tailCall()` should then be returned by the method implementation. + + void allowCancellation(); + // Indicate that it is OK for the RPC system to discard its Promise for this call's result if + // the caller cancels the call, thereby transitively canceling any asynchronous operations the + // call implementation was performing. This is not done by default because it could represent a + // security risk: applications must be carefully written to ensure that they do not end up in + // a bad state if an operation is canceled at an arbitrary point. However, for long-running + // method calls that hold significant resources, prompt cancellation is often useful. + // + // Keep in mind that asynchronous cancellation cannot occur while the method is synchronously + // executing on a local thread. The method must perform an asynchronous operation or call + // `EventLoop::current().evalLater()` to yield control. + // + // Note: You might think that we should offer `onCancel()` and/or `isCanceled()` methods that + // provide notification when the caller cancels the request without forcefully killing off the + // promise chain. Unfortunately, this composes poorly with promise forking: the canceled + // path may be just one branch of a fork of the result promise. The other branches still want + // the call to continue. Promise forking is used within the Cap'n Proto implementation -- in + // particular each pipelined call forks the result promise. So, if a caller made a pipelined + // call and then dropped the original object, the call should not be canceled, but it would be + // excessively complicated for the framework to avoid notififying of cancellation as long as + // pipelined calls still exist. + +private: + CallContextHook* hook; + + friend class Capability::Server; + friend struct DynamicCapability; +}; + +class Capability::Server { + // Objects implementing a Cap'n Proto interface must subclass this. Typically, such objects + // will instead subclass a typed Server interface which will take care of implementing + // dispatchCall(). + +public: + typedef Capability Serves; + + virtual kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, + CallContext context) = 0; + // Call the given method. `params` is the input struct, and should be released as soon as it + // is no longer needed. `context` may be used to allocate the output struct and deal with + // cancellation. + + // TODO(someday): Method which can optionally be overridden to implement Join when the object is + // a proxy. + +protected: + inline Capability::Client thisCap(); + // Get a capability pointing to this object, much like the `this` keyword. + // + // The effect of this method is undefined if: + // - No capability client has been created pointing to this object. (This is always the case in + // the server's constructor.) + // - The capability client pointing at this object has been destroyed. (This is always the case + // in the server's destructor.) + // - Multiple capability clients have been created around the same server (possible if the server + // is refcounted, which is not recommended since the client itself provides refcounting). + + template + CallContext internalGetTypedContext( + CallContext typeless); + kj::Promise internalUnimplemented(const char* actualInterfaceName, + uint64_t requestedTypeId); + kj::Promise internalUnimplemented(const char* interfaceName, + uint64_t typeId, uint16_t methodId); + kj::Promise internalUnimplemented(const char* interfaceName, const char* methodName, + uint64_t typeId, uint16_t methodId); + +private: + ClientHook* thisHook = nullptr; + friend class LocalClient; +}; + +// ======================================================================================= + +class ReaderCapabilityTable: private _::CapTableReader { + // Class which imbues Readers with the ability to read capabilities. + // + // In Cap'n Proto format, the encoding of a capability pointer is simply an integer index into + // an external table. Since these pointers fundamentally point outside the message, a + // MessageReader by default has no idea what they point at, and therefore reading capabilities + // from such a reader will throw exceptions. + // + // In order to be able to read capabilities, you must first attach a capability table, using + // this class. By "imbuing" a Reader, you get a new Reader which will interpret capability + // pointers by treating them as indexes into the ReaderCapabilityTable. + // + // Note that when using Cap'n Proto's RPC system, this is handled automatically. + +public: + explicit ReaderCapabilityTable(kj::Array>> table); + KJ_DISALLOW_COPY(ReaderCapabilityTable); + + template + T imbue(T reader); + // Return a reader equivalent to `reader` except that when reading capability-valued fields, + // the capabilities are looked up in this table. + +private: + kj::Array>> table; + + kj::Maybe> extractCap(uint index) override; +}; + +class BuilderCapabilityTable: private _::CapTableBuilder { + // Class which imbues Builders with the ability to read and write capabilities. + // + // This is much like ReaderCapabilityTable, except for builders. The table starts out empty, + // but capabilities can be added to it over time. + +public: + BuilderCapabilityTable(); + KJ_DISALLOW_COPY(BuilderCapabilityTable); + + inline kj::ArrayPtr>> getTable() { return table; } + + template + T imbue(T builder); + // Return a builder equivalent to `builder` except that when reading capability-valued fields, + // the capabilities are looked up in this table. + +private: + kj::Vector>> table; + + kj::Maybe> extractCap(uint index) override; + uint injectCap(kj::Own&& cap) override; + void dropCap(uint index) override; +}; + +// ======================================================================================= + +namespace _ { // private + +class CapabilityServerSetBase { +public: + Capability::Client addInternal(kj::Own&& server, void* ptr); + kj::Promise getLocalServerInternal(Capability::Client& client); +}; + +} // namespace _ (private) + +template +class CapabilityServerSet: private _::CapabilityServerSetBase { + // Allows a server to recognize its own capabilities when passed back to it, and obtain the + // underlying Server objects associated with them. + // + // All objects in the set must have the same interface type T. The objects may implement various + // interfaces derived from T (and in fact T can be `capnp::Capability` to accept all objects), + // but note that if you compile with RTTI disabled then you will not be able to down-cast through + // virtual inheritance, and all inheritance between server interfaces is virtual. So, with RTTI + // disabled, you will likely need to set T to be the most-derived Cap'n Proto interface type, + // and you server class will need to be directly derived from that, so that you can use + // static_cast (or kj::downcast) to cast to it after calling getLocalServer(). (If you compile + // with RTTI, then you can freely dynamic_cast and ignore this issue!) + +public: + CapabilityServerSet() = default; + KJ_DISALLOW_COPY(CapabilityServerSet); + + typename T::Client add(kj::Own&& server); + // Create a new capability Client for the given Server and also add this server to the set. + + kj::Promise> getLocalServer(typename T::Client& client); + // Given a Client pointing to a server previously passed to add(), return the corresponding + // Server. This returns a promise because if the input client is itself a promise, this must + // wait for it to resolve. Keep in mind that the server will be deleted when all clients are + // gone, so the caller should make sure to keep the client alive (hence why this method only + // accepts an lvalue input). +}; + +// ======================================================================================= +// Hook interfaces which must be implemented by the RPC system. Applications never call these +// directly; the RPC system implements them and the types defined earlier in this file wrap them. + +class RequestHook { + // Hook interface implemented by RPC system representing a request being built. + +public: + virtual RemotePromise send() = 0; + // Send the call and return a promise for the result. + + virtual const void* getBrand() = 0; + // Returns a void* that identifies who made this request. This can be used by an RPC adapter to + // discover when tail call is going to be sent over its own connection and therefore can be + // optimized into a remote tail call. + + template + inline static kj::Own from(Request&& request) { + return kj::mv(request.hook); + } +}; + +class ResponseHook { + // Hook interface implemented by RPC system representing a response. + // + // At present this class has no methods. It exists only for garbage collection -- when the + // ResponseHook is destroyed, the results can be freed. + +public: + virtual ~ResponseHook() noexcept(false); + // Just here to make sure the type is dynamic. + + template + inline static kj::Own from(Response&& response) { + return kj::mv(response.hook); + } +}; + +// class PipelineHook is declared in any.h because it is needed there. + +class ClientHook { +public: + ClientHook(); + + virtual Request newCall( + uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint) = 0; + // Start a new call, allowing the client to allocate request/response objects as it sees fit. + // This version is used when calls are made from application code in the local process. + + struct VoidPromiseAndPipeline { + kj::Promise promise; + kj::Own pipeline; + }; + + virtual VoidPromiseAndPipeline call(uint64_t interfaceId, uint16_t methodId, + kj::Own&& context) = 0; + // Call the object, but the caller controls allocation of the request/response objects. If the + // callee insists on allocating these objects itself, it must make a copy. This version is used + // when calls come in over the network via an RPC system. Note that even if the returned + // `Promise` is discarded, the call may continue executing if any pipelined calls are + // waiting for it. + // + // Since the caller of this method chooses the CallContext implementation, it is the caller's + // responsibility to ensure that the returned promise is not canceled unless allowed via + // the context's `allowCancellation()`. + // + // The call must not begin synchronously; the callee must arrange for the call to begin in a + // later turn of the event loop. Otherwise, application code may call back and affect the + // callee's state in an unexpected way. + + virtual kj::Maybe getResolved() = 0; + // If this ClientHook is a promise that has already resolved, returns the inner, resolved version + // of the capability. The caller may permanently replace this client with the resolved one if + // desired. Returns null if the client isn't a promise or hasn't resolved yet -- use + // `whenMoreResolved()` to distinguish between them. + + virtual kj::Maybe>> whenMoreResolved() = 0; + // If this client is a settled reference (not a promise), return nullptr. Otherwise, return a + // promise that eventually resolves to a new client that is closer to being the final, settled + // client (i.e. the value eventually returned by `getResolved()`). Calling this repeatedly + // should eventually produce a settled client. + + kj::Promise whenResolved(); + // Repeatedly calls whenMoreResolved() until it returns nullptr. + + virtual kj::Own addRef() = 0; + // Return a new reference to the same capability. + + virtual const void* getBrand() = 0; + // Returns a void* that identifies who made this client. This can be used by an RPC adapter to + // discover when a capability it needs to marshal is one that it created in the first place, and + // therefore it can transfer the capability without proxying. + + static const uint NULL_CAPABILITY_BRAND; + // Value is irrelevant; used for pointer. + + inline bool isNull() { return getBrand() == &NULL_CAPABILITY_BRAND; } + // Returns true if the capability was created as a result of assigning a Client to null or by + // reading a null pointer out of a Cap'n Proto message. + + virtual void* getLocalServer(_::CapabilityServerSetBase& capServerSet); + // If this is a local capability created through `capServerSet`, return the underlying Server. + // Otherwise, return nullptr. Default implementation (which everyone except LocalClient should + // use) always returns nullptr. + + static kj::Own from(Capability::Client client) { return kj::mv(client.hook); } +}; + +class CallContextHook { + // Hook interface implemented by RPC system to manage a call on the server side. See + // CallContext. + +public: + virtual AnyPointer::Reader getParams() = 0; + virtual void releaseParams() = 0; + virtual AnyPointer::Builder getResults(kj::Maybe sizeHint) = 0; + virtual kj::Promise tailCall(kj::Own&& request) = 0; + virtual void allowCancellation() = 0; + + virtual kj::Promise onTailCall() = 0; + // If `tailCall()` is called, resolves to the PipelineHook from the tail call. An + // implementation of `ClientHook::call()` is allowed to call this at most once. + + virtual ClientHook::VoidPromiseAndPipeline directTailCall(kj::Own&& request) = 0; + // Call this when you would otherwise call onTailCall() immediately followed by tailCall(). + // Implementations of tailCall() should typically call directTailCall() and then fulfill the + // promise fulfiller for onTailCall() with the returned pipeline. + + virtual kj::Own addRef() = 0; +}; + +kj::Own newLocalPromiseClient(kj::Promise>&& promise); +// Returns a ClientHook that queues up calls until `promise` resolves, then forwards them to +// the new client. This hook's `getResolved()` and `whenMoreResolved()` methods will reflect the +// redirection to the eventual replacement client. + +kj::Own newLocalPromisePipeline(kj::Promise>&& promise); +// Returns a PipelineHook that queues up calls until `promise` resolves, then forwards them to +// the new pipeline. + +kj::Own newBrokenCap(kj::StringPtr reason); +kj::Own newBrokenCap(kj::Exception&& reason); +// Helper function that creates a capability which simply throws exceptions when called. + +kj::Own newBrokenPipeline(kj::Exception&& reason); +// Helper function that creates a pipeline which simply throws exceptions when called. + +Request newBrokenRequest( + kj::Exception&& reason, kj::Maybe sizeHint); +// Helper function that creates a Request object that simply throws exceptions when sent. + +// ======================================================================================= +// Extend PointerHelpers for interfaces + +namespace _ { // private + +template +struct PointerHelpers { + static inline typename T::Client get(PointerReader reader) { + return typename T::Client(reader.getCapability()); + } + static inline typename T::Client get(PointerBuilder builder) { + return typename T::Client(builder.getCapability()); + } + static inline void set(PointerBuilder builder, typename T::Client&& value) { + builder.setCapability(kj::mv(value.Capability::Client::hook)); + } + static inline void set(PointerBuilder builder, typename T::Client& value) { + builder.setCapability(value.Capability::Client::hook->addRef()); + } + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } +}; + +} // namespace _ (private) + +// ======================================================================================= +// Extend List for interfaces + +template +struct List { + List() = delete; + + class Reader { + public: + typedef List Reads; + + Reader() = default; + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline typename T::Client operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename T::Client(reader.getPointerElement( + bounded(index) * ELEMENTS).getCapability()); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline typename T::Client operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename T::Client(builder.getPointerElement( + bounded(index) * ELEMENTS).getCapability()); + } + inline void set(uint index, typename T::Client value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).setCapability(kj::mv(value.hook)); + } + inline void adopt(uint index, Orphan&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value)); + } + inline Orphan disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +// ======================================================================================= +// Inline implementation details + +template +RemotePromise Request::send() { + auto typelessPromise = hook->send(); + hook = nullptr; // prevent reuse + + // Convert the Promise to return the correct response type. + // Explicitly upcast to kj::Promise to make clear that calling .then() doesn't invalidate the + // Pipeline part of the RemotePromise. + auto typedPromise = kj::implicitCast>&>(typelessPromise) + .then([](Response&& response) -> Response { + return Response(response.getAs(), kj::mv(response.hook)); + }); + + // Wrap the typeless pipeline in a typed wrapper. + typename Results::Pipeline typedPipeline( + kj::mv(kj::implicitCast(typelessPromise))); + + return RemotePromise(kj::mv(typedPromise), kj::mv(typedPipeline)); +} + +inline Capability::Client::Client(kj::Own&& hook): hook(kj::mv(hook)) {} +template +inline Capability::Client::Client(kj::Own&& server) + : hook(makeLocalClient(kj::mv(server))) {} +template +inline Capability::Client::Client(kj::Promise&& promise) + : hook(newLocalPromiseClient(promise.then([](T&& t) { return kj::mv(t.hook); }))) {} +inline Capability::Client::Client(Client& other): hook(other.hook->addRef()) {} +inline Capability::Client& Capability::Client::operator=(Client& other) { + hook = other.hook->addRef(); + return *this; +} +template +inline typename T::Client Capability::Client::castAs() { + return typename T::Client(hook->addRef()); +} +inline kj::Promise Capability::Client::whenResolved() { + return hook->whenResolved(); +} +inline Request Capability::Client::typelessRequest( + uint64_t interfaceId, uint16_t methodId, + kj::Maybe sizeHint) { + return newCall(interfaceId, methodId, sizeHint); +} +template +inline Request Capability::Client::newCall( + uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint) { + auto typeless = hook->newCall(interfaceId, methodId, sizeHint); + return Request(typeless.template getAs(), kj::mv(typeless.hook)); +} + +template +inline CallContext::CallContext(CallContextHook& hook): hook(&hook) {} +template +inline typename Params::Reader CallContext::getParams() { + return hook->getParams().template getAs(); +} +template +inline void CallContext::releaseParams() { + hook->releaseParams(); +} +template +inline typename Results::Builder CallContext::getResults( + kj::Maybe sizeHint) { + // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 + return hook->getResults(sizeHint).template getAs(); +} +template +inline typename Results::Builder CallContext::initResults( + kj::Maybe sizeHint) { + // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 + return hook->getResults(sizeHint).template initAs(); +} +template +inline void CallContext::setResults(typename Results::Reader value) { + hook->getResults(value.totalSize()).template setAs(value); +} +template +inline void CallContext::adoptResults(Orphan&& value) { + hook->getResults(nullptr).adopt(kj::mv(value)); +} +template +inline Orphanage CallContext::getResultsOrphanage( + kj::Maybe sizeHint) { + return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); +} +template +template +inline kj::Promise CallContext::tailCall( + Request&& tailRequest) { + return hook->tailCall(kj::mv(tailRequest.hook)); +} +template +inline void CallContext::allowCancellation() { + hook->allowCancellation(); +} + +template +CallContext Capability::Server::internalGetTypedContext( + CallContext typeless) { + return CallContext(*typeless.hook); +} + +Capability::Client Capability::Server::thisCap() { + return Client(thisHook->addRef()); +} + +template +T ReaderCapabilityTable::imbue(T reader) { + return T(_::PointerHelpers>::getInternalReader(reader).imbue(this)); +} + +template +T BuilderCapabilityTable::imbue(T builder) { + return T(_::PointerHelpers>::getInternalBuilder(kj::mv(builder)).imbue(this)); +} + +template +typename T::Client CapabilityServerSet::add(kj::Own&& server) { + void* ptr = reinterpret_cast(server.get()); + // Clang insists that `castAs` is a template-dependent member and therefore we need the + // `template` keyword here, but AFAICT this is wrong: addImpl() is not a template. + return addInternal(kj::mv(server), ptr).template castAs(); +} + +template +kj::Promise> CapabilityServerSet::getLocalServer( + typename T::Client& client) { + return getLocalServerInternal(client) + .then([](void* server) -> kj::Maybe { + if (server == nullptr) { + return nullptr; + } else { + return *reinterpret_cast(server); + } + }); +} + +template +struct Orphanage::GetInnerReader { + static inline kj::Own apply(typename T::Client t) { + return ClientHook::from(kj::mv(t)); + } +}; + +} // namespace capnp + +#endif // CAPNP_CAPABILITY_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/common.h --- a/win32-mingw/include/capnp/common.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/common.h Tue May 23 09:16:54 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 -#include -#include -#include - -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 -struct EnumInfo; - -} // namespace schemas - -namespace _ { // private - -template struct Kind_; - -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::BLOB; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::BLOB; }; - -template struct Kind_> { - static constexpr Kind kind = Kind::STRUCT; -}; -template struct Kind_> { - static constexpr Kind kind = Kind::INTERFACE; -}; -template struct Kind_::IsEnum>> { - static constexpr Kind kind = Kind::ENUM; -}; - -} // namespace _ (private) - -template ::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_::kind -// Avoid constexpr methods in lite mode (MSVC is bad at constexpr). - -#else // CAPNP_LITE - -#define CAPNP_KIND(T) ::capnp::kind() -// Use this macro rather than kind() in any code which must work in lite mode. - -template ()> -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 -struct List; - -#if _MSC_VER - -template -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 struct ListElementType_; -template struct ListElementType_> { typedef T Type; }; -template using ListElementType = typename ListElementType_::Type; - -namespace _ { // private -template struct Kind_> { - static constexpr Kind kind = Kind::LIST; -}; -} // namespace _ (private) - -template struct ReaderFor_ { typedef typename T::Reader Type; }; -template struct ReaderFor_ { typedef T Type; }; -template struct ReaderFor_ { typedef T Type; }; -template struct ReaderFor_ { typedef typename T::Client Type; }; -template using ReaderFor = typename ReaderFor_::Type; -// The type returned by List::Reader::operator[]. - -template struct BuilderFor_ { typedef typename T::Builder Type; }; -template struct BuilderFor_ { typedef T Type; }; -template struct BuilderFor_ { typedef T Type; }; -template struct BuilderFor_ { typedef typename T::Client Type; }; -template using BuilderFor = typename BuilderFor_::Type; -// The type returned by List::Builder::operator[]. - -template struct PipelineFor_ { typedef typename T::Pipeline Type;}; -template struct PipelineFor_ { typedef typename T::Client Type; }; -template using PipelineFor = typename PipelineFor_::Type; - -template struct TypeIfEnum_; -template struct TypeIfEnum_ { typedef T Type; }; - -template -using TypeIfEnum = typename TypeIfEnum_>::Type; - -template -using FromReader = typename kj::Decay::Reads; -// FromReader = MyType (for any Cap'n Proto type). - -template -using FromBuilder = typename kj::Decay::Builds; -// FromBuilder = MyType (for any Cap'n Proto type). - -template -using FromPipeline = typename kj::Decay::Pipelines; -// FromBuilder = MyType (for any Cap'n Proto type). - -template -using FromClient = typename kj::Decay::Calls; -// FromReader = MyType (for any Cap'n Proto interface type). - -template -using FromServer = typename kj::Decay::Serves; -// FromBuilder = MyType (for any Cap'n Proto interface type). - -template -struct FromAny_; - -template -struct FromAny_>> { - using Type = FromReader; -}; - -template -struct FromAny_>> { - using Type = FromBuilder; -}; - -template -struct FromAny_>> { - using Type = FromPipeline; -}; - -// Note that T::Client is covered by FromReader - -template -struct FromAny_, kj::VoidSfinae>> { - using Type = FromServer; -}; - -template -struct FromAny_::kind == Kind::PRIMITIVE || _::Kind_::kind == Kind::ENUM>> { - // TODO(msvc): Ideally the EnableIf condition would be `style() == Style::PRIMITIVE`, but MSVC - // cannot yet use style() in this constexpr context. - - using Type = kj::Decay; -}; - -template -using FromAny = typename FromAny_::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 -// uint32_t -> uint32_t - -namespace _ { // private - -template -struct PointerHelpers; - -#if _MSC_VER - -template -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 BitCount; -typedef kj::Quantity BitCount8; -typedef kj::Quantity BitCount16; -typedef kj::Quantity BitCount32; -typedef kj::Quantity BitCount64; - -typedef kj::Quantity ByteCount; -typedef kj::Quantity ByteCount8; -typedef kj::Quantity ByteCount16; -typedef kj::Quantity ByteCount32; -typedef kj::Quantity ByteCount64; - -typedef kj::Quantity WordCount; -typedef kj::Quantity WordCount8; -typedef kj::Quantity WordCount16; -typedef kj::Quantity WordCount32; -typedef kj::Quantity WordCount64; - -typedef kj::Quantity ElementCount; -typedef kj::Quantity ElementCount8; -typedef kj::Quantity ElementCount16; -typedef kj::Quantity ElementCount32; -typedef kj::Quantity ElementCount64; - -typedef kj::Quantity WirePointerCount; -typedef kj::Quantity WirePointerCount8; -typedef kj::Quantity WirePointerCount16; -typedef kj::Quantity WirePointerCount32; -typedef kj::Quantity WirePointerCount64; - -template -inline constexpr U* operator+(U* ptr, kj::Quantity offset) { - return ptr + offset / kj::unit>(); -} -template -inline constexpr const U* operator+(const U* ptr, kj::Quantity offset) { - return ptr + offset / kj::unit>(); -} -template -inline constexpr U* operator+=(U*& ptr, kj::Quantity offset) { - return ptr = ptr + offset / kj::unit>(); -} -template -inline constexpr const U* operator+=(const U*& ptr, kj::Quantity offset) { - return ptr = ptr + offset / kj::unit>(); -} - -template -inline constexpr U* operator-(U* ptr, kj::Quantity offset) { - return ptr - offset / kj::unit>(); -} -template -inline constexpr const U* operator-(const U* ptr, kj::Quantity offset) { - return ptr - offset / kj::unit>(); -} -template -inline constexpr U* operator-=(U*& ptr, kj::Quantity offset) { - return ptr = ptr - offset / kj::unit>(); -} -template -inline constexpr const U* operator-=(const U*& ptr, kj::Quantity offset) { - return ptr = ptr - offset / kj::unit>(); -} - -#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(); -constexpr ByteCount BYTES = kj::unit(); -constexpr WordCount WORDS = kj::unit(); -constexpr ElementCount ELEMENTS = kj::unit(); -constexpr WirePointerCount POINTERS = kj::unit(); - -// 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 -inline KJ_CONSTEXPR() decltype(BYTES / ELEMENTS) bytesPerElement() { - return sizeof(T) * BYTES / ELEMENTS; -} - -template -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 +#include +#include + +#if CAPNP_DEBUG_TYPES +#include +#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 +struct EnumInfo; + +} // namespace schemas + +namespace _ { // private + +template struct Kind_; + +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::BLOB; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::BLOB; }; + +template struct Kind_> { + static constexpr Kind kind = Kind::STRUCT; +}; +template struct Kind_> { + static constexpr Kind kind = Kind::INTERFACE; +}; +template struct Kind_::IsEnum>> { + static constexpr Kind kind = Kind::ENUM; +}; + +} // namespace _ (private) + +template ::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_::kind +// Avoid constexpr methods in lite mode (MSVC is bad at constexpr). + +#else // CAPNP_LITE + +#define CAPNP_KIND(T) ::capnp::kind() +// Use this macro rather than kind() in any code which must work in lite mode. + +template ()> +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 +struct List; + +#if _MSC_VER + +template +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 struct ListElementType_; +template struct ListElementType_> { typedef T Type; }; +template using ListElementType = typename ListElementType_::Type; + +namespace _ { // private +template struct Kind_> { + static constexpr Kind kind = Kind::LIST; +}; +} // namespace _ (private) + +template struct ReaderFor_ { typedef typename T::Reader Type; }; +template struct ReaderFor_ { typedef T Type; }; +template struct ReaderFor_ { typedef T Type; }; +template struct ReaderFor_ { typedef typename T::Client Type; }; +template using ReaderFor = typename ReaderFor_::Type; +// The type returned by List::Reader::operator[]. + +template struct BuilderFor_ { typedef typename T::Builder Type; }; +template struct BuilderFor_ { typedef T Type; }; +template struct BuilderFor_ { typedef T Type; }; +template struct BuilderFor_ { typedef typename T::Client Type; }; +template using BuilderFor = typename BuilderFor_::Type; +// The type returned by List::Builder::operator[]. + +template struct PipelineFor_ { typedef typename T::Pipeline Type;}; +template struct PipelineFor_ { typedef typename T::Client Type; }; +template using PipelineFor = typename PipelineFor_::Type; + +template struct TypeIfEnum_; +template struct TypeIfEnum_ { typedef T Type; }; + +template +using TypeIfEnum = typename TypeIfEnum_>::Type; + +template +using FromReader = typename kj::Decay::Reads; +// FromReader = MyType (for any Cap'n Proto type). + +template +using FromBuilder = typename kj::Decay::Builds; +// FromBuilder = MyType (for any Cap'n Proto type). + +template +using FromPipeline = typename kj::Decay::Pipelines; +// FromBuilder = MyType (for any Cap'n Proto type). + +template +using FromClient = typename kj::Decay::Calls; +// FromReader = MyType (for any Cap'n Proto interface type). + +template +using FromServer = typename kj::Decay::Serves; +// FromBuilder = MyType (for any Cap'n Proto interface type). + +template +struct FromAny_; + +template +struct FromAny_>> { + using Type = FromReader; +}; + +template +struct FromAny_>> { + using Type = FromBuilder; +}; + +template +struct FromAny_>> { + using Type = FromPipeline; +}; + +// Note that T::Client is covered by FromReader + +template +struct FromAny_, kj::VoidSfinae>> { + using Type = FromServer; +}; + +template +struct FromAny_::kind == Kind::PRIMITIVE || _::Kind_::kind == Kind::ENUM>> { + // TODO(msvc): Ideally the EnableIf condition would be `style() == Style::PRIMITIVE`, but MSVC + // cannot yet use style() in this constexpr context. + + using Type = kj::Decay; +}; + +template +using FromAny = typename FromAny_::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 +// uint32_t -> uint32_t + +namespace _ { // private + +template +struct PointerHelpers; + +#if _MSC_VER + +template +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 +using BitCountN = kj::Quantity(), T>, _::BitLabel>; +template +using ByteCountN = kj::Quantity(), T>, byte>; +template +using WordCountN = kj::Quantity(), T>, word>; +template +using ElementCountN = kj::Quantity(), T>, _::ElementLabel>; +template +using WirePointerCountN = kj::Quantity(), 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 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 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 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 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 WirePointerCount; + +template +using BitsPerElementN = decltype(BitCountN() / ElementCountN()); +template +using BytesPerElementN = decltype(ByteCountN() / ElementCountN()); +template +using WordsPerElementN = decltype(WordCountN() / ElementCountN()); +template +using PointersPerElementN = decltype(WirePointerCountN() / ElementCountN()); + +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 +inline constexpr U* operator+(U* ptr, kj::Quantity offset) { + return ptr + unbound(offset / kj::unit>()); +} +template +inline constexpr const U* operator+(const U* ptr, kj::Quantity offset) { + return ptr + unbound(offset / kj::unit>()); +} +template +inline constexpr U* operator+=(U*& ptr, kj::Quantity offset) { + return ptr = ptr + unbound(offset / kj::unit>()); +} +template +inline constexpr const U* operator+=(const U*& ptr, kj::Quantity offset) { + return ptr = ptr + unbound(offset / kj::unit>()); +} + +template +inline constexpr U* operator-(U* ptr, kj::Quantity offset) { + return ptr - unbound(offset / kj::unit>()); +} +template +inline constexpr const U* operator-(const U* ptr, kj::Quantity offset) { + return ptr - unbound(offset / kj::unit>()); +} +template +inline constexpr U* operator-=(U*& ptr, kj::Quantity offset) { + return ptr = ptr - unbound(offset / kj::unit>()); +} +template +inline constexpr const U* operator-=(const U*& ptr, kj::Quantity offset) { + return ptr = ptr - unbound(offset / kj::unit>()); +} + +constexpr auto BITS = kj::unit>(); +constexpr auto BYTES = kj::unit>(); +constexpr auto WORDS = kj::unit>(); +constexpr auto ELEMENTS = kj::unit>(); +constexpr auto POINTERS = kj::unit>(); + +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 SegmentWordCount; +typedef ElementCountN ListElementCount; +typedef WordCountN StructDataWordCount; +typedef WirePointerCountN StructPointerCount; +typedef ByteCountN BlobSize; + +constexpr auto MAX_SEGMENT_WORDS = + bounded()>() * WORDS; +constexpr auto MAX_LIST_ELEMENTS = + bounded()>() * ELEMENTS; +constexpr auto MAX_STUCT_DATA_WORDS = + bounded()>() * WORDS; +constexpr auto MAX_STRUCT_POINTER_COUNT = + bounded()>() * POINTERS; + +using StructDataBitCount = decltype(WordCountN() * 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() - 1; +typedef kj::Quantity, byte> TextSize; +// Not including NUL terminator. + +template +inline KJ_CONSTEXPR() decltype(bounded() * BYTES / ELEMENTS) bytesPerElement() { + return bounded() * BYTES / ELEMENTS; +} + +template +inline KJ_CONSTEXPR() decltype(bounded() * BITS / ELEMENTS) bitsPerElement() { + return bounded() * BITS / ELEMENTS; +} + +template +inline constexpr kj::Quantity, T> +intervalLength(const T* a, const T* b, kj::Quantity, T>) { + return kj::assumeMax(b - a) * kj::unit, T>>(); +} + +template +inline constexpr kj::ArrayPtr arrayPtr(const U* ptr, kj::Quantity size) { + return kj::ArrayPtr(ptr, unbound(size / kj::unit>())); +} +template +inline constexpr kj::ArrayPtr arrayPtr(U* ptr, kj::Quantity size) { + return kj::ArrayPtr(ptr, unbound(size / kj::unit>())); +} + +#else + +template +using BitCountN = T; +template +using ByteCountN = T; +template +using WordCountN = T; +template +using ElementCountN = T; +template +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 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 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 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 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 WirePointerCount; + +template +using BitsPerElementN = decltype(BitCountN() / ElementCountN()); +template +using BytesPerElementN = decltype(ByteCountN() / ElementCountN()); +template +using WordsPerElementN = decltype(WordCountN() / ElementCountN()); +template +using PointersPerElementN = decltype(WirePointerCountN() / ElementCountN()); + +using kj::ThrowOverflow; +// YYY + +template inline constexpr uint bounded() { return i; } +template inline constexpr T bounded(T i) { return i; } +template inline constexpr T unbound(T i) { return i; } + +template inline constexpr T unboundAs(U i) { return i; } + +template inline constexpr uint unboundMax(T i) { return i; } +template inline constexpr uint unboundMaxBits(T i) { return i; } + +template +inline T assertMax(T value, ErrorFunc&& func) { + if (KJ_UNLIKELY(value > newMax)) func(); + return value; +} + +template +inline T assertMax(uint newMax, T value, ErrorFunc&& func) { + if (KJ_UNLIKELY(value > newMax)) func(); + return value; +} + +template +inline T assertMaxBits(T value, ErrorFunc&& func = ErrorFunc()) { + if (KJ_UNLIKELY(value > kj::maxValueForBits())) func(); + return value; +} + +template +inline T assertMaxBits(uint bits, T value, ErrorFunc&& func = ErrorFunc()) { + if (KJ_UNLIKELY(value > (1ull << bits) - 1)) func(); + return value; +} + +template inline constexpr T upgradeBound(U i) { return i; } + +template inline constexpr T assumeBits(T i) { return i; } +template inline constexpr T assumeMax(T i) { return i; } + +template +inline auto subtractChecked(T a, U b, ErrorFunc&& errorFunc = ErrorFunc()) + -> decltype(a - b) { + if (b > a) errorFunc(); + return a - b; +} + +template +inline auto trySubtract(T a, U b) -> kj::Maybe { + 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 SegmentWordCount; +typedef ElementCountN ListElementCount; +typedef WordCountN StructDataWordCount; +typedef WirePointerCountN StructPointerCount; +typedef ByteCountN BlobSize; +// YYY + +constexpr auto MAX_SEGMENT_WORDS = kj::maxValueForBits(); +constexpr auto MAX_LIST_ELEMENTS = kj::maxValueForBits(); +constexpr auto MAX_STUCT_DATA_WORDS = kj::maxValueForBits(); +constexpr auto MAX_STRUCT_POINTER_COUNT = kj::maxValueForBits(); + +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() - 1; +typedef uint TextSize; + +template +inline KJ_CONSTEXPR() size_t bytesPerElement() { return sizeof(T); } + +template +inline KJ_CONSTEXPR() size_t bitsPerElement() { return sizeof(T) * 8; } + +template +inline constexpr ptrdiff_t intervalLength(const T* a, const T* b, uint) { + return b - a; +} + +template +inline constexpr kj::ArrayPtr arrayPtr(const U* ptr, T size) { + return kj::arrayPtr(ptr, size); +} +template +inline constexpr kj::ArrayPtr arrayPtr(U* ptr, T size) { + return kj::arrayPtr(ptr, size); +} + +#endif + +} // namespace capnp + +#endif // CAPNP_COMMON_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/dynamic.h --- a/win32-mingw/include/capnp/dynamic.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/dynamic.h Tue May 23 09:16:54 2017 +0100 @@ -1,1593 +1,1643 @@ -// 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 defines classes that can be used to manipulate messages based on schemas that are not -// known until runtime. This is also useful for writing generic code that uses schemas to handle -// arbitrary types in a generic way. -// -// Each of the classes defined here has a to() template method which converts an instance back to a -// native type. This method will throw an exception if the requested type does not match the -// schema. To convert native types to dynamic, use DynamicFactory. -// -// As always, underlying data is validated lazily, so you have to actually traverse the whole -// message if you want to validate all content. - -#ifndef CAPNP_DYNAMIC_H_ -#define CAPNP_DYNAMIC_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "schema.h" -#include "layout.h" -#include "message.h" -#include "any.h" -#include "capability.h" - -namespace capnp { - -class MessageReader; -class MessageBuilder; - -struct DynamicValue { - DynamicValue() = delete; - - enum Type { - UNKNOWN, - // Means that the value has unknown type and content because it comes from a newer version of - // the schema, or from a newer version of Cap'n Proto that has new features that this version - // doesn't understand. - - VOID, - BOOL, - INT, - UINT, - FLOAT, - TEXT, - DATA, - LIST, - ENUM, - STRUCT, - CAPABILITY, - ANY_POINTER - }; - - class Reader; - class Builder; - class Pipeline; -}; -class DynamicEnum; -struct DynamicStruct { - DynamicStruct() = delete; - class Reader; - class Builder; - class Pipeline; -}; -struct DynamicList { - DynamicList() = delete; - class Reader; - class Builder; -}; -struct DynamicCapability { - DynamicCapability() = delete; - class Client; - class Server; -}; -template <> class Orphan; - -template struct DynamicTypeFor_; -template <> struct DynamicTypeFor_ { typedef DynamicEnum Type; }; -template <> struct DynamicTypeFor_ { typedef DynamicStruct Type; }; -template <> struct DynamicTypeFor_ { typedef DynamicList Type; }; -template <> struct DynamicTypeFor_ { typedef DynamicCapability Type; }; - -template -using DynamicTypeFor = typename DynamicTypeFor_()>::Type; - -template -ReaderFor>> toDynamic(T&& value); -template -BuilderFor>> toDynamic(T&& value); -template -DynamicTypeFor> toDynamic(T&& value); -template -typename DynamicTypeFor>::Client toDynamic(kj::Own&& value); - -namespace _ { // private - -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; - -} // namespace _ (private) - -template <> inline constexpr Style style() { return Style::POINTER; } -template <> inline constexpr Style style() { return Style::PRIMITIVE; } -template <> inline constexpr Style style() { return Style::STRUCT; } -template <> inline constexpr Style style() { return Style::POINTER; } -template <> inline constexpr Style style() { return Style::CAPABILITY; } - -// ------------------------------------------------------------------- - -class DynamicEnum { -public: - DynamicEnum() = default; - inline DynamicEnum(EnumSchema::Enumerant enumerant) - : schema(enumerant.getContainingEnum()), value(enumerant.getOrdinal()) {} - inline DynamicEnum(EnumSchema schema, uint16_t value) - : schema(schema), value(value) {} - - template () == Kind::ENUM>> - inline DynamicEnum(T&& value): DynamicEnum(toDynamic(value)) {} - - template - inline T as() const { return static_cast(asImpl(typeId())); } - // Cast to a native enum type. - - inline EnumSchema getSchema() const { return schema; } - - kj::Maybe getEnumerant() const; - // Get which enumerant this enum value represents. Returns nullptr if the numeric value does not - // correspond to any enumerant in the schema -- this can happen if the data was built using a - // newer schema that has more values defined. - - inline uint16_t getRaw() const { return value; } - // Returns the raw underlying enum value. - -private: - EnumSchema schema; - uint16_t value; - - uint16_t asImpl(uint64_t requestedTypeId) const; - - friend struct DynamicStruct; - friend struct DynamicList; - friend struct DynamicValue; - template - friend DynamicTypeFor> toDynamic(T&& value); -}; - -// ------------------------------------------------------------------- - -class DynamicStruct::Reader { -public: - typedef DynamicStruct Reads; - - Reader() = default; - - template >() == Kind::STRUCT>> - inline Reader(T&& value): Reader(toDynamic(value)) {} - - inline MessageSize totalSize() const { return reader.totalSize().asPublic(); } - - template - typename T::Reader as() const; - // Convert the dynamic struct to its compiled-in type. - - inline StructSchema getSchema() const { return schema; } - - DynamicValue::Reader get(StructSchema::Field field) const; - // Read the given field value. - - bool has(StructSchema::Field field) const; - // Tests whether the given field is set to its default value. For pointer values, this does - // not actually traverse the value comparing it with the default, but simply returns true if the - // pointer is non-null. For members of unions, has() returns false if the union member is not - // active, but does not necessarily return true if the member is active (depends on the field's - // value). - - kj::Maybe which() const; - // If the struct contains an (unnamed) union, and the currently-active field within that union - // is known, this returns that field. Otherwise, it returns null. In other words, this returns - // null if there is no union present _or_ if the union's discriminant is set to an unrecognized - // value. This could happen in particular when receiving a message from a sender who has a - // newer version of the protocol and is using a field of the union that you don't know about yet. - - DynamicValue::Reader get(kj::StringPtr name) const; - bool has(kj::StringPtr name) const; - // Shortcuts to access fields by name. These throw exceptions if no such field exists. - -private: - StructSchema schema; - _::StructReader reader; - - inline Reader(StructSchema schema, _::StructReader reader) - : schema(schema), reader(reader) {} - - bool isSetInUnion(StructSchema::Field field) const; - void verifySetInUnion(StructSchema::Field field) const; - static DynamicValue::Reader getImpl(_::StructReader reader, StructSchema::Field field); - - template - friend struct _::PointerHelpers; - friend class DynamicStruct::Builder; - friend struct DynamicList; - friend class MessageReader; - friend class MessageBuilder; - template - friend struct ::capnp::ToDynamic_; - friend kj::StringTree _::structString( - _::StructReader reader, const _::RawBrandedSchema& schema); - friend class Orphanage; - friend class Orphan; - friend class Orphan; - friend class Orphan; -}; - -class DynamicStruct::Builder { -public: - typedef DynamicStruct Builds; - - Builder() = default; - inline Builder(decltype(nullptr)) {} - - template >() == Kind::STRUCT>> - inline Builder(T&& value): Builder(toDynamic(value)) {} - - inline MessageSize totalSize() const { return asReader().totalSize(); } - - template - typename T::Builder as(); - // Cast to a particular struct type. - - inline StructSchema getSchema() const { return schema; } - - DynamicValue::Builder get(StructSchema::Field field); - // Read the given field value. - - inline bool has(StructSchema::Field field) { return asReader().has(field); } - // Tests whether the given field is set to its default value. For pointer values, this does - // not actually traverse the value comparing it with the default, but simply returns true if the - // pointer is non-null. For members of unions, has() returns whether the field is currently - // active and the union as a whole is non-default -- so, the only time has() will return false - // for an active union field is if it is the default active field and it has its default value. - - kj::Maybe which(); - // If the struct contains an (unnamed) union, and the currently-active field within that union - // is known, this returns that field. Otherwise, it returns null. In other words, this returns - // null if there is no union present _or_ if the union's discriminant is set to an unrecognized - // value. This could happen in particular when receiving a message from a sender who has a - // newer version of the protocol and is using a field of the union that you don't know about yet. - - void set(StructSchema::Field field, const DynamicValue::Reader& value); - // Set the given field value. - - DynamicValue::Builder init(StructSchema::Field field); - DynamicValue::Builder init(StructSchema::Field field, uint size); - // Init a struct, list, or blob field. - - void adopt(StructSchema::Field field, Orphan&& orphan); - Orphan disown(StructSchema::Field field); - // Adopt/disown. This works even for non-pointer fields: adopt() becomes equivalent to set() - // and disown() becomes like get() followed by clear(). - - void clear(StructSchema::Field field); - // Clear a field, setting it to its default value. For pointer fields, this actually makes the - // field null. - - DynamicValue::Builder get(kj::StringPtr name); - bool has(kj::StringPtr name); - void set(kj::StringPtr name, const DynamicValue::Reader& value); - void set(kj::StringPtr name, std::initializer_list value); - DynamicValue::Builder init(kj::StringPtr name); - DynamicValue::Builder init(kj::StringPtr name, uint size); - void adopt(kj::StringPtr name, Orphan&& orphan); - Orphan disown(kj::StringPtr name); - void clear(kj::StringPtr name); - // Shortcuts to access fields by name. These throw exceptions if no such field exists. - - Reader asReader() const; - -private: - StructSchema schema; - _::StructBuilder builder; - - inline Builder(StructSchema schema, _::StructBuilder builder) - : schema(schema), builder(builder) {} - - bool isSetInUnion(StructSchema::Field field); - void verifySetInUnion(StructSchema::Field field); - void setInUnion(StructSchema::Field field); - - template - friend struct _::PointerHelpers; - friend struct DynamicList; - friend class MessageReader; - friend class MessageBuilder; - template - friend struct ::capnp::ToDynamic_; - friend class Orphanage; - friend class Orphan; - friend class Orphan; - friend class Orphan; -}; - -class DynamicStruct::Pipeline { -public: - typedef DynamicStruct Pipelines; - - inline Pipeline(decltype(nullptr)): typeless(nullptr) {} - - template - typename T::Pipeline releaseAs(); - // Convert the dynamic pipeline to its compiled-in type. - - inline StructSchema getSchema() { return schema; } - - DynamicValue::Pipeline get(StructSchema::Field field); - // Read the given field value. - - DynamicValue::Pipeline get(kj::StringPtr name); - // Get by string name. - -private: - StructSchema schema; - AnyPointer::Pipeline typeless; - - inline explicit Pipeline(StructSchema schema, AnyPointer::Pipeline&& typeless) - : schema(schema), typeless(kj::mv(typeless)) {} - - friend class Request; -}; - -// ------------------------------------------------------------------- - -class DynamicList::Reader { -public: - typedef DynamicList Reads; - - inline Reader(): reader(ElementSize::VOID) {} - - template >() == Kind::LIST>> - inline Reader(T&& value): Reader(toDynamic(value)) {} - - template - typename T::Reader as() const; - // Try to convert to any List, Data, or Text. Throws an exception if the underlying data - // can't possibly represent the requested type. - - inline ListSchema getSchema() const { return schema; } - - inline uint size() const { return reader.size() / ELEMENTS; } - DynamicValue::Reader operator[](uint index) const; - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - ListSchema schema; - _::ListReader reader; - - Reader(ListSchema schema, _::ListReader reader): schema(schema), reader(reader) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicStruct; - friend class DynamicList::Builder; - template - friend struct ::capnp::ToDynamic_; - friend class Orphanage; - friend class Orphan; - friend class Orphan; - friend class Orphan; -}; - -class DynamicList::Builder { -public: - typedef DynamicList Builds; - - inline Builder(): builder(ElementSize::VOID) {} - inline Builder(decltype(nullptr)): builder(ElementSize::VOID) {} - - template >() == Kind::LIST>> - inline Builder(T&& value): Builder(toDynamic(value)) {} - - template - typename T::Builder as(); - // Try to convert to any List, Data, or Text. Throws an exception if the underlying data - // can't possibly represent the requested type. - - inline ListSchema getSchema() const { return schema; } - - inline uint size() const { return builder.size() / ELEMENTS; } - DynamicValue::Builder operator[](uint index); - void set(uint index, const DynamicValue::Reader& value); - DynamicValue::Builder init(uint index, uint size); - void adopt(uint index, Orphan&& orphan); - Orphan disown(uint index); - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - void copyFrom(std::initializer_list value); - - Reader asReader() const; - -private: - ListSchema schema; - _::ListBuilder builder; - - Builder(ListSchema schema, _::ListBuilder builder): schema(schema), builder(builder) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicStruct; - template - friend struct ::capnp::ToDynamic_; - friend class Orphanage; - template - friend struct _::OrphanGetImpl; - friend class Orphan; - friend class Orphan; - friend class Orphan; -}; - -// ------------------------------------------------------------------- - -class DynamicCapability::Client: public Capability::Client { -public: - typedef DynamicCapability Calls; - typedef DynamicCapability Reads; - - Client() = default; - - template >() == Kind::INTERFACE>> - inline Client(T&& client); - - template ()>> - inline Client(kj::Own&& server); - - template () == Kind::INTERFACE>> - typename T::Client as(); - template () == Kind::INTERFACE>> - typename T::Client releaseAs(); - // Convert to any client type. - - Client upcast(InterfaceSchema requestedSchema); - // Upcast to a superclass. Throws an exception if `schema` is not a superclass. - - inline InterfaceSchema getSchema() { return schema; } - - Request newRequest( - InterfaceSchema::Method method, kj::Maybe sizeHint = nullptr); - Request newRequest( - kj::StringPtr methodName, kj::Maybe sizeHint = nullptr); - -private: - InterfaceSchema schema; - - Client(InterfaceSchema schema, kj::Own&& hook) - : Capability::Client(kj::mv(hook)), schema(schema) {} - - template - inline Client(InterfaceSchema schema, kj::Own&& server); - - friend struct Capability; - friend struct DynamicStruct; - friend struct DynamicList; - friend struct DynamicValue; - friend class Orphan; - friend class Orphan; - friend class Orphan; - template - friend struct _::PointerHelpers; -}; - -class DynamicCapability::Server: public Capability::Server { -public: - typedef DynamicCapability Serves; - - Server(InterfaceSchema schema): schema(schema) {} - - virtual kj::Promise call(InterfaceSchema::Method method, - CallContext context) = 0; - - kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, - CallContext context) override final; - - inline InterfaceSchema getSchema() const { return schema; } - -private: - InterfaceSchema schema; -}; - -template <> -class Request: public DynamicStruct::Builder { - // Specialization of `Request` for DynamicStruct. - -public: - inline Request(DynamicStruct::Builder builder, kj::Own&& hook, - StructSchema resultSchema) - : DynamicStruct::Builder(builder), hook(kj::mv(hook)), resultSchema(resultSchema) {} - - RemotePromise send(); - // Send the call and return a promise for the results. - -private: - kj::Own hook; - StructSchema resultSchema; - - friend class Capability::Client; - friend struct DynamicCapability; - template - friend class CallContext; - friend class RequestHook; -}; - -template <> -class CallContext: public kj::DisallowConstCopy { - // Wrapper around CallContextHook with a specific return type. - // - // Methods of this class may only be called from within the server's event loop, not from other - // threads. - -public: - explicit CallContext(CallContextHook& hook, StructSchema paramType, StructSchema resultType); - - DynamicStruct::Reader getParams(); - void releaseParams(); - DynamicStruct::Builder getResults(kj::Maybe sizeHint = nullptr); - DynamicStruct::Builder initResults(kj::Maybe sizeHint = nullptr); - void setResults(DynamicStruct::Reader value); - void adoptResults(Orphan&& value); - Orphanage getResultsOrphanage(kj::Maybe sizeHint = nullptr); - template - kj::Promise tailCall(Request&& tailRequest); - void allowCancellation(); - -private: - CallContextHook* hook; - StructSchema paramType; - StructSchema resultType; - - friend class DynamicCapability::Server; -}; - -// ------------------------------------------------------------------- - -// Make sure ReaderFor and BuilderFor work for DynamicEnum, DynamicStruct, and -// DynamicList, so that we can define DynamicValue::as(). - -template <> struct ReaderFor_ { typedef DynamicEnum Type; }; -template <> struct BuilderFor_ { typedef DynamicEnum Type; }; -template <> struct ReaderFor_ { typedef DynamicStruct::Reader Type; }; -template <> struct BuilderFor_ { typedef DynamicStruct::Builder Type; }; -template <> struct ReaderFor_ { typedef DynamicList::Reader Type; }; -template <> struct BuilderFor_ { typedef DynamicList::Builder Type; }; -template <> struct ReaderFor_ { typedef DynamicCapability::Client Type; }; -template <> struct BuilderFor_ { typedef DynamicCapability::Client Type; }; -template <> struct PipelineFor_ { typedef DynamicCapability::Client Type; }; - -class DynamicValue::Reader { -public: - typedef DynamicValue Reads; - - inline Reader(decltype(nullptr) n = nullptr); // UNKNOWN - inline Reader(Void value); - inline Reader(bool value); - inline Reader(char value); - inline Reader(signed char value); - inline Reader(short value); - inline Reader(int value); - inline Reader(long value); - inline Reader(long long value); - inline Reader(unsigned char value); - inline Reader(unsigned short value); - inline Reader(unsigned int value); - inline Reader(unsigned long value); - inline Reader(unsigned long long value); - inline Reader(float value); - inline Reader(double value); - inline Reader(const char* value); // Text - inline Reader(const Text::Reader& value); - inline Reader(const Data::Reader& value); - inline Reader(const DynamicList::Reader& value); - inline Reader(DynamicEnum value); - inline Reader(const DynamicStruct::Reader& value); - inline Reader(const AnyPointer::Reader& value); - inline Reader(DynamicCapability::Client& value); - inline Reader(DynamicCapability::Client&& value); - template ()>> - inline Reader(kj::Own&& value); - Reader(ConstSchema constant); - - template ()))> - inline Reader(T&& value): Reader(toDynamic(kj::mv(value))) {} - - Reader(const Reader& other); - Reader(Reader&& other) noexcept; - ~Reader() noexcept(false); - Reader& operator=(const Reader& other); - Reader& operator=(Reader&& other); - // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not - // trivially copyable. - - template - inline ReaderFor as() const { return AsImpl::apply(*this); } - // Use to interpret the value as some Cap'n Proto type. Allowed types are: - // - Void, bool, [u]int{8,16,32,64}_t, float, double, any enum: Returns the raw value. - // - Text, Data, AnyPointer, any struct type: Returns the corresponding Reader. - // - List for any T listed above: Returns List::Reader. - // - DynamicEnum: Returns the corresponding type. - // - DynamicStruct, DynamicList: Returns the corresponding Reader. - // - Any capability type, including DynamicCapability: Returns the corresponding Client. - // (TODO(perf): On GCC 4.8 / Clang 3.3, provide rvalue-qualified version that avoids - // refcounting.) - // - // DynamicValue allows various implicit conversions, mostly just to make the interface friendlier. - // - Any integer can be converted to any other integer type so long as the actual value is within - // the new type's range. - // - Floating-point types can be converted to integers as long as no information would be lost - // in the conversion. - // - Integers can be converted to floating points. This may lose information, but won't throw. - // - Float32/Float64 can be converted between each other. Converting Float64 -> Float32 may lose - // information, but won't throw. - // - Text can be converted to an enum, if the Text matches one of the enumerant names (but not - // vice-versa). - // - Capabilities can be upcast (cast to a supertype), but not downcast. - // - // Any other conversion attempt will throw an exception. - - inline Type getType() const { return type; } - // Get the type of this value. - -private: - Type type; - - union { - Void voidValue; - bool boolValue; - int64_t intValue; - uint64_t uintValue; - double floatValue; - Text::Reader textValue; - Data::Reader dataValue; - DynamicList::Reader listValue; - DynamicEnum enumValue; - DynamicStruct::Reader structValue; - AnyPointer::Reader anyPointerValue; - - mutable DynamicCapability::Client capabilityValue; - // Declared mutable because `Client`s normally cannot be const. - - // Warning: Copy/move constructors assume all these types are trivially copyable except - // Capability. - }; - - template ()> struct AsImpl; - // Implementation backing the as() method. Needs to be a struct to allow partial - // specialization. Has a method apply() which does the work. - - friend class Orphanage; // to speed up newOrphanCopy(DynamicValue::Reader) -}; - -class DynamicValue::Builder { -public: - typedef DynamicValue Builds; - - inline Builder(decltype(nullptr) n = nullptr); // UNKNOWN - inline Builder(Void value); - inline Builder(bool value); - inline Builder(char value); - inline Builder(signed char value); - inline Builder(short value); - inline Builder(int value); - inline Builder(long value); - inline Builder(long long value); - inline Builder(unsigned char value); - inline Builder(unsigned short value); - inline Builder(unsigned int value); - inline Builder(unsigned long value); - inline Builder(unsigned long long value); - inline Builder(float value); - inline Builder(double value); - inline Builder(Text::Builder value); - inline Builder(Data::Builder value); - inline Builder(DynamicList::Builder value); - inline Builder(DynamicEnum value); - inline Builder(DynamicStruct::Builder value); - inline Builder(AnyPointer::Builder value); - inline Builder(DynamicCapability::Client& value); - inline Builder(DynamicCapability::Client&& value); - - template ()))> - inline Builder(T value): Builder(toDynamic(value)) {} - - Builder(Builder& other); - Builder(Builder&& other) noexcept; - ~Builder() noexcept(false); - Builder& operator=(Builder& other); - Builder& operator=(Builder&& other); - // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not - // trivially copyable. - - template - inline BuilderFor as() { return AsImpl::apply(*this); } - // See DynamicValue::Reader::as(). - - inline Type getType() { return type; } - // Get the type of this value. - - Reader asReader() const; - -private: - Type type; - - union { - Void voidValue; - bool boolValue; - int64_t intValue; - uint64_t uintValue; - double floatValue; - Text::Builder textValue; - Data::Builder dataValue; - DynamicList::Builder listValue; - DynamicEnum enumValue; - DynamicStruct::Builder structValue; - AnyPointer::Builder anyPointerValue; - - mutable DynamicCapability::Client capabilityValue; - // Declared mutable because `Client`s normally cannot be const. - }; - - template ()> struct AsImpl; - // Implementation backing the as() method. Needs to be a struct to allow partial - // specialization. Has a method apply() which does the work. - - friend class Orphan; -}; - -class DynamicValue::Pipeline { -public: - typedef DynamicValue Pipelines; - - inline Pipeline(decltype(nullptr) n = nullptr); - inline Pipeline(DynamicStruct::Pipeline&& value); - inline Pipeline(DynamicCapability::Client&& value); - - Pipeline(Pipeline&& other) noexcept; - Pipeline& operator=(Pipeline&& other); - ~Pipeline() noexcept(false); - - template - inline PipelineFor releaseAs() { return AsImpl::apply(*this); } - - inline Type getType() { return type; } - // Get the type of this value. - -private: - Type type; - union { - DynamicStruct::Pipeline structValue; - DynamicCapability::Client capabilityValue; - }; - - template ()> struct AsImpl; - // Implementation backing the releaseAs() method. Needs to be a struct to allow partial - // specialization. Has a method apply() which does the work. -}; - -kj::StringTree KJ_STRINGIFY(const DynamicValue::Reader& value); -kj::StringTree KJ_STRINGIFY(const DynamicValue::Builder& value); -kj::StringTree KJ_STRINGIFY(DynamicEnum value); -kj::StringTree KJ_STRINGIFY(const DynamicStruct::Reader& value); -kj::StringTree KJ_STRINGIFY(const DynamicStruct::Builder& value); -kj::StringTree KJ_STRINGIFY(const DynamicList::Reader& value); -kj::StringTree KJ_STRINGIFY(const DynamicList::Builder& value); - -// ------------------------------------------------------------------- -// Orphan <-> Dynamic glue - -template <> -class Orphan { -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - Orphan& operator=(Orphan&&) = default; - - template () == Kind::STRUCT>> - inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} - - DynamicStruct::Builder get(); - DynamicStruct::Reader getReader() const; - - template - Orphan releaseAs(); - // Like DynamicStruct::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, - // the original Orphan is no longer valid after this call; ownership is - // transferred to the returned Orphan. - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - -private: - StructSchema schema; - _::OrphanBuilder builder; - - inline Orphan(StructSchema schema, _::OrphanBuilder&& builder) - : schema(schema), builder(kj::mv(builder)) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicList; - friend class Orphanage; - friend class Orphan; - friend class Orphan; - friend class MessageBuilder; -}; - -template <> -class Orphan { -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - Orphan& operator=(Orphan&&) = default; - - template () == Kind::LIST>> - inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} - - DynamicList::Builder get(); - DynamicList::Reader getReader() const; - - template - Orphan releaseAs(); - // Like DynamicList::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, - // the original Orphan is no longer valid after this call; ownership is - // transferred to the returned Orphan. - - // TODO(someday): Support truncate(). - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - -private: - ListSchema schema; - _::OrphanBuilder builder; - - inline Orphan(ListSchema schema, _::OrphanBuilder&& builder) - : schema(schema), builder(kj::mv(builder)) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicList; - friend class Orphanage; - friend class Orphan; - friend class Orphan; -}; - -template <> -class Orphan { -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - Orphan& operator=(Orphan&&) = default; - - template () == Kind::INTERFACE>> - inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} - - DynamicCapability::Client get(); - DynamicCapability::Client getReader() const; - - template - Orphan releaseAs(); - // Like DynamicCapability::Client::as(), but coerces the Orphan type. Since Orphans are move-only, - // the original Orphan is no longer valid after this call; ownership is - // transferred to the returned Orphan. - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - -private: - InterfaceSchema schema; - _::OrphanBuilder builder; - - inline Orphan(InterfaceSchema schema, _::OrphanBuilder&& builder) - : schema(schema), builder(kj::mv(builder)) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicList; - friend class Orphanage; - friend class Orphan; - friend class Orphan; -}; - -template <> -class Orphan { -public: - inline Orphan(decltype(nullptr) n = nullptr): type(DynamicValue::UNKNOWN) {} - inline Orphan(Void value); - inline Orphan(bool value); - inline Orphan(char value); - inline Orphan(signed char value); - inline Orphan(short value); - inline Orphan(int value); - inline Orphan(long value); - inline Orphan(long long value); - inline Orphan(unsigned char value); - inline Orphan(unsigned short value); - inline Orphan(unsigned int value); - inline Orphan(unsigned long value); - inline Orphan(unsigned long long value); - inline Orphan(float value); - inline Orphan(double value); - inline Orphan(DynamicEnum value); - Orphan(Orphan&&) = default; - template - Orphan(Orphan&&); - Orphan(Orphan&&); - Orphan(void*) = delete; // So Orphan(bool) doesn't accept pointers. - KJ_DISALLOW_COPY(Orphan); - - Orphan& operator=(Orphan&&) = default; - - inline DynamicValue::Type getType() { return type; } - - DynamicValue::Builder get(); - DynamicValue::Reader getReader() const; - - template - Orphan releaseAs(); - // Like DynamicValue::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, - // the original Orphan is no longer valid after this call; ownership is - // transferred to the returned Orphan. - -private: - DynamicValue::Type type; - union { - Void voidValue; - bool boolValue; - int64_t intValue; - uint64_t uintValue; - double floatValue; - DynamicEnum enumValue; - StructSchema structSchema; - ListSchema listSchema; - InterfaceSchema interfaceSchema; - }; - - _::OrphanBuilder builder; - // Only used if `type` is a pointer type. - - Orphan(DynamicValue::Builder value, _::OrphanBuilder&& builder); - Orphan(DynamicValue::Type type, _::OrphanBuilder&& builder) - : type(type), builder(kj::mv(builder)) {} - Orphan(StructSchema structSchema, _::OrphanBuilder&& builder) - : type(DynamicValue::STRUCT), structSchema(structSchema), builder(kj::mv(builder)) {} - Orphan(ListSchema listSchema, _::OrphanBuilder&& builder) - : type(DynamicValue::LIST), listSchema(listSchema), builder(kj::mv(builder)) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicStruct; - friend struct DynamicList; - friend struct AnyPointer; - friend class Orphanage; -}; - -template -inline Orphan::Orphan(Orphan&& other) - : Orphan(other.get(), kj::mv(other.builder)) {} - -inline Orphan::Orphan(Orphan&& other) - : type(DynamicValue::ANY_POINTER), builder(kj::mv(other.builder)) {} - -template -Orphan Orphan::releaseAs() { - get().as(); // type check - return Orphan(kj::mv(builder)); -} - -template -Orphan Orphan::releaseAs() { - get().as(); // type check - return Orphan(kj::mv(builder)); -} - -template -Orphan Orphan::releaseAs() { - get().as(); // type check - return Orphan(kj::mv(builder)); -} - -template -Orphan Orphan::releaseAs() { - get().as(); // type check - type = DynamicValue::UNKNOWN; - return Orphan(kj::mv(builder)); -} - -template <> -Orphan Orphan::releaseAs(); -template <> -Orphan Orphan::releaseAs(); -template <> -Orphan Orphan::releaseAs(); -template <> -Orphan Orphan::releaseAs(); - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::StructBuilder apply(DynamicStruct::Builder& t) { - return t.builder; - } -}; - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::ListBuilder apply(DynamicList::Builder& t) { - return t.builder; - } -}; - -template <> -inline Orphan Orphanage::newOrphanCopy( - DynamicStruct::Reader copyFrom) const { - return Orphan( - copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); -} - -template <> -inline Orphan Orphanage::newOrphanCopy( - DynamicList::Reader copyFrom) const { - return Orphan(copyFrom.getSchema(), - _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); -} - -template <> -inline Orphan Orphanage::newOrphanCopy( - DynamicCapability::Client copyFrom) const { - return Orphan( - copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.hook->addRef())); -} - -template <> -Orphan Orphanage::newOrphanCopy( - DynamicValue::Reader copyFrom) const; - -namespace _ { // private - -template <> -struct PointerHelpers { - // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for - // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we - // don't want people to accidentally be able to provide their own default value. - static DynamicStruct::Reader getDynamic(PointerReader reader, StructSchema schema); - static DynamicStruct::Builder getDynamic(PointerBuilder builder, StructSchema schema); - static void set(PointerBuilder builder, const DynamicStruct::Reader& value); - static DynamicStruct::Builder init(PointerBuilder builder, StructSchema schema); - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder, StructSchema schema) { - return Orphan(schema, builder.disown()); - } -}; - -template <> -struct PointerHelpers { - // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for - // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we - // don't want people to accidentally be able to provide their own default value. - static DynamicList::Reader getDynamic(PointerReader reader, ListSchema schema); - static DynamicList::Builder getDynamic(PointerBuilder builder, ListSchema schema); - static void set(PointerBuilder builder, const DynamicList::Reader& value); - static DynamicList::Builder init(PointerBuilder builder, ListSchema schema, uint size); - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder, ListSchema schema) { - return Orphan(schema, builder.disown()); - } -}; - -template <> -struct PointerHelpers { - // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for - // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we - // don't want people to accidentally be able to provide their own default value. - static DynamicCapability::Client getDynamic(PointerReader reader, InterfaceSchema schema); - static DynamicCapability::Client getDynamic(PointerBuilder builder, InterfaceSchema schema); - static void set(PointerBuilder builder, DynamicCapability::Client& value); - static void set(PointerBuilder builder, DynamicCapability::Client&& value); - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder, InterfaceSchema schema) { - return Orphan(schema, builder.disown()); - } -}; - -} // namespace _ (private) - -template -inline ReaderFor AnyPointer::Reader::getAs(StructSchema schema) const { - return _::PointerHelpers::getDynamic(reader, schema); -} -template -inline ReaderFor AnyPointer::Reader::getAs(ListSchema schema) const { - return _::PointerHelpers::getDynamic(reader, schema); -} -template -inline ReaderFor AnyPointer::Reader::getAs(InterfaceSchema schema) const { - return _::PointerHelpers::getDynamic(reader, schema); -} -template -inline BuilderFor AnyPointer::Builder::getAs(StructSchema schema) { - return _::PointerHelpers::getDynamic(builder, schema); -} -template -inline BuilderFor AnyPointer::Builder::getAs(ListSchema schema) { - return _::PointerHelpers::getDynamic(builder, schema); -} -template -inline BuilderFor AnyPointer::Builder::getAs(InterfaceSchema schema) { - return _::PointerHelpers::getDynamic(builder, schema); -} -template -inline BuilderFor AnyPointer::Builder::initAs(StructSchema schema) { - return _::PointerHelpers::init(builder, schema); -} -template -inline BuilderFor AnyPointer::Builder::initAs(ListSchema schema, uint elementCount) { - return _::PointerHelpers::init(builder, schema, elementCount); -} -template <> -inline void AnyPointer::Builder::setAs(DynamicStruct::Reader value) { - return _::PointerHelpers::set(builder, value); -} -template <> -inline void AnyPointer::Builder::setAs(DynamicList::Reader value) { - return _::PointerHelpers::set(builder, value); -} -template <> -inline void AnyPointer::Builder::setAs(DynamicCapability::Client value) { - return _::PointerHelpers::set(builder, kj::mv(value)); -} -template <> -void AnyPointer::Builder::adopt(Orphan&& orphan); -template -inline Orphan AnyPointer::Builder::disownAs(StructSchema schema) { - return _::PointerHelpers::disown(builder, schema); -} -template -inline Orphan AnyPointer::Builder::disownAs(ListSchema schema) { - return _::PointerHelpers::disown(builder, schema); -} -template -inline Orphan AnyPointer::Builder::disownAs(InterfaceSchema schema) { - return _::PointerHelpers::disown(builder, schema); -} - -template <> -DynamicStruct::Builder Orphan::getAs(StructSchema schema); -template <> -DynamicList::Builder Orphan::getAs(ListSchema schema); -template <> -DynamicCapability::Client Orphan::getAs(InterfaceSchema schema); -template <> -DynamicStruct::Reader Orphan::getAsReader(StructSchema schema) const; -template <> -DynamicList::Reader Orphan::getAsReader(ListSchema schema) const; -template <> -DynamicCapability::Client Orphan::getAsReader( - InterfaceSchema schema) const; -template <> -Orphan Orphan::releaseAs(StructSchema schema); -template <> -Orphan Orphan::releaseAs(ListSchema schema); -template <> -Orphan Orphan::releaseAs( - InterfaceSchema schema); - -// ======================================================================================= -// Inline implementation details. - -template -struct ToDynamic_ { - static inline DynamicStruct::Reader apply(const typename T::Reader& value) { - return DynamicStruct::Reader(Schema::from(), value._reader); - } - static inline DynamicStruct::Builder apply(typename T::Builder& value) { - return DynamicStruct::Builder(Schema::from(), value._builder); - } -}; - -template -struct ToDynamic_ { - static inline DynamicList::Reader apply(const typename T::Reader& value) { - return DynamicList::Reader(Schema::from(), value.reader); - } - static inline DynamicList::Builder apply(typename T::Builder& value) { - return DynamicList::Builder(Schema::from(), value.builder); - } -}; - -template -struct ToDynamic_ { - static inline DynamicCapability::Client apply(typename T::Client value) { - return DynamicCapability::Client(kj::mv(value)); - } - static inline DynamicCapability::Client apply(typename T::Client&& value) { - return DynamicCapability::Client(kj::mv(value)); - } -}; - -template -ReaderFor>> toDynamic(T&& value) { - return ToDynamic_>::apply(value); -} -template -BuilderFor>> toDynamic(T&& value) { - return ToDynamic_>::apply(value); -} -template -DynamicTypeFor> toDynamic(T&& value) { - return DynamicEnum(Schema::from>(), static_cast(value)); -} -template -typename DynamicTypeFor>::Client toDynamic(kj::Own&& value) { - return typename FromServer::Client(kj::mv(value)); -} - -inline DynamicValue::Reader::Reader(std::nullptr_t n): type(UNKNOWN) {} -inline DynamicValue::Builder::Builder(std::nullptr_t n): type(UNKNOWN) {} - -#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ -inline DynamicValue::Reader::Reader(cppType value) \ - : type(typeTag), fieldName##Value(value) {} \ -inline DynamicValue::Builder::Builder(cppType value) \ - : type(typeTag), fieldName##Value(value) {} \ -inline Orphan::Orphan(cppType value) \ - : type(DynamicValue::typeTag), fieldName##Value(value) {} - -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Void, VOID, void); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(bool, BOOL, bool); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(char, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(signed char, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(short, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(int, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long long, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned char, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned short, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned int, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long long, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(float, FLOAT, float); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(double, FLOAT, float); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicEnum, ENUM, enum); -#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR - -#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ -inline DynamicValue::Reader::Reader(const cppType::Reader& value) \ - : type(typeTag), fieldName##Value(value) {} \ -inline DynamicValue::Builder::Builder(cppType::Builder value) \ - : type(typeTag), fieldName##Value(value) {} - -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Text, TEXT, text); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Data, DATA, data); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicList, LIST, list); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicStruct, STRUCT, struct); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(AnyPointer, ANY_POINTER, anyPointer); - -#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR - -inline DynamicValue::Reader::Reader(DynamicCapability::Client& value) - : type(CAPABILITY), capabilityValue(value) {} -inline DynamicValue::Reader::Reader(DynamicCapability::Client&& value) - : type(CAPABILITY), capabilityValue(kj::mv(value)) {} -template -inline DynamicValue::Reader::Reader(kj::Own&& value) - : type(CAPABILITY), capabilityValue(kj::mv(value)) {} -inline DynamicValue::Builder::Builder(DynamicCapability::Client& value) - : type(CAPABILITY), capabilityValue(value) {} -inline DynamicValue::Builder::Builder(DynamicCapability::Client&& value) - : type(CAPABILITY), capabilityValue(kj::mv(value)) {} - -inline DynamicValue::Reader::Reader(const char* value): Reader(Text::Reader(value)) {} - -#define CAPNP_DECLARE_TYPE(discrim, typeName) \ -template <> \ -struct DynamicValue::Reader::AsImpl { \ - static ReaderFor apply(const Reader& reader); \ -}; \ -template <> \ -struct DynamicValue::Builder::AsImpl { \ - static BuilderFor apply(Builder& builder); \ -}; - -//CAPNP_DECLARE_TYPE(VOID, Void) -CAPNP_DECLARE_TYPE(BOOL, bool) -CAPNP_DECLARE_TYPE(INT8, int8_t) -CAPNP_DECLARE_TYPE(INT16, int16_t) -CAPNP_DECLARE_TYPE(INT32, int32_t) -CAPNP_DECLARE_TYPE(INT64, int64_t) -CAPNP_DECLARE_TYPE(UINT8, uint8_t) -CAPNP_DECLARE_TYPE(UINT16, uint16_t) -CAPNP_DECLARE_TYPE(UINT32, uint32_t) -CAPNP_DECLARE_TYPE(UINT64, uint64_t) -CAPNP_DECLARE_TYPE(FLOAT32, float) -CAPNP_DECLARE_TYPE(FLOAT64, double) - -CAPNP_DECLARE_TYPE(TEXT, Text) -CAPNP_DECLARE_TYPE(DATA, Data) -CAPNP_DECLARE_TYPE(LIST, DynamicList) -CAPNP_DECLARE_TYPE(STRUCT, DynamicStruct) -CAPNP_DECLARE_TYPE(INTERFACE, DynamicCapability) -CAPNP_DECLARE_TYPE(ENUM, DynamicEnum) -CAPNP_DECLARE_TYPE(ANY_POINTER, AnyPointer) -#undef CAPNP_DECLARE_TYPE - -// CAPNP_DECLARE_TYPE(Void) causes gcc 4.7 to segfault. If I do it manually and remove the -// ReaderFor<> and BuilderFor<> wrappers, it works. -template <> -struct DynamicValue::Reader::AsImpl { - static Void apply(const Reader& reader); -}; -template <> -struct DynamicValue::Builder::AsImpl { - static Void apply(Builder& builder); -}; - -template -struct DynamicValue::Reader::AsImpl { - static T apply(const Reader& reader) { - return reader.as().as(); - } -}; -template -struct DynamicValue::Builder::AsImpl { - static T apply(Builder& builder) { - return builder.as().as(); - } -}; - -template -struct DynamicValue::Reader::AsImpl { - static typename T::Reader apply(const Reader& reader) { - return reader.as().as(); - } -}; -template -struct DynamicValue::Builder::AsImpl { - static typename T::Builder apply(Builder& builder) { - return builder.as().as(); - } -}; - -template -struct DynamicValue::Reader::AsImpl { - static typename T::Reader apply(const Reader& reader) { - return reader.as().as(); - } -}; -template -struct DynamicValue::Builder::AsImpl { - static typename T::Builder apply(Builder& builder) { - return builder.as().as(); - } -}; - -template -struct DynamicValue::Reader::AsImpl { - static typename T::Client apply(const Reader& reader) { - return reader.as().as(); - } -}; -template -struct DynamicValue::Builder::AsImpl { - static typename T::Client apply(Builder& builder) { - return builder.as().as(); - } -}; - -inline DynamicValue::Pipeline::Pipeline(std::nullptr_t n): type(UNKNOWN) {} -inline DynamicValue::Pipeline::Pipeline(DynamicStruct::Pipeline&& value) - : type(STRUCT), structValue(kj::mv(value)) {} -inline DynamicValue::Pipeline::Pipeline(DynamicCapability::Client&& value) - : type(CAPABILITY), capabilityValue(kj::mv(value)) {} - -template -struct DynamicValue::Pipeline::AsImpl { - static typename T::Pipeline apply(Pipeline& pipeline) { - return pipeline.releaseAs().releaseAs(); - } -}; -template -struct DynamicValue::Pipeline::AsImpl { - static typename T::Client apply(Pipeline& pipeline) { - return pipeline.releaseAs().releaseAs(); - } -}; -template <> -struct DynamicValue::Pipeline::AsImpl { - static PipelineFor apply(Pipeline& pipeline); -}; -template <> -struct DynamicValue::Pipeline::AsImpl { - static PipelineFor apply(Pipeline& pipeline); -}; - -// ------------------------------------------------------------------- - -template -typename T::Reader DynamicStruct::Reader::as() const { - static_assert(kind() == Kind::STRUCT, - "DynamicStruct::Reader::as() can only convert to struct types."); - schema.requireUsableAs(); - return typename T::Reader(reader); -} - -template -typename T::Builder DynamicStruct::Builder::as() { - static_assert(kind() == Kind::STRUCT, - "DynamicStruct::Builder::as() can only convert to struct types."); - schema.requireUsableAs(); - return typename T::Builder(builder); -} - -template <> -inline DynamicStruct::Reader DynamicStruct::Reader::as() const { - return *this; -} -template <> -inline DynamicStruct::Builder DynamicStruct::Builder::as() { - return *this; -} - -inline DynamicStruct::Reader DynamicStruct::Builder::asReader() const { - return DynamicStruct::Reader(schema, builder.asReader()); -} - -template <> -inline AnyStruct::Reader DynamicStruct::Reader::as() const { - return AnyStruct::Reader(reader); -} - -template <> -inline AnyStruct::Builder DynamicStruct::Builder::as() { - return AnyStruct::Builder(builder); -} - -template -typename T::Pipeline DynamicStruct::Pipeline::releaseAs() { - static_assert(kind() == Kind::STRUCT, - "DynamicStruct::Pipeline::releaseAs() can only convert to struct types."); - schema.requireUsableAs(); - return typename T::Pipeline(kj::mv(typeless)); -} - -// ------------------------------------------------------------------- - -template -typename T::Reader DynamicList::Reader::as() const { - static_assert(kind() == Kind::LIST, - "DynamicStruct::Reader::as() can only convert to list types."); - schema.requireUsableAs(); - return typename T::Reader(reader); -} -template -typename T::Builder DynamicList::Builder::as() { - static_assert(kind() == Kind::LIST, - "DynamicStruct::Builder::as() can only convert to list types."); - schema.requireUsableAs(); - return typename T::Builder(builder); -} - -template <> -inline DynamicList::Reader DynamicList::Reader::as() const { - return *this; -} -template <> -inline DynamicList::Builder DynamicList::Builder::as() { - return *this; -} - -// ------------------------------------------------------------------- - -template -inline DynamicCapability::Client::Client(T&& client) - : Capability::Client(kj::mv(client)), schema(Schema::from>()) {} - -template -inline DynamicCapability::Client::Client(kj::Own&& server) - : Client(server->getSchema(), kj::mv(server)) {} -template -inline DynamicCapability::Client::Client(InterfaceSchema schema, kj::Own&& server) - : Capability::Client(kj::mv(server)), schema(schema) {} - -template -typename T::Client DynamicCapability::Client::as() { - static_assert(kind() == Kind::INTERFACE, - "DynamicCapability::Client::as() can only convert to interface types."); - schema.requireUsableAs(); - return typename T::Client(hook->addRef()); -} - -template -typename T::Client DynamicCapability::Client::releaseAs() { - static_assert(kind() == Kind::INTERFACE, - "DynamicCapability::Client::as() can only convert to interface types."); - schema.requireUsableAs(); - return typename T::Client(kj::mv(hook)); -} - -inline CallContext::CallContext( - CallContextHook& hook, StructSchema paramType, StructSchema resultType) - : hook(&hook), paramType(paramType), resultType(resultType) {} -inline DynamicStruct::Reader CallContext::getParams() { - return hook->getParams().getAs(paramType); -} -inline void CallContext::releaseParams() { - hook->releaseParams(); -} -inline DynamicStruct::Builder CallContext::getResults( - kj::Maybe sizeHint) { - return hook->getResults(sizeHint).getAs(resultType); -} -inline DynamicStruct::Builder CallContext::initResults( - kj::Maybe sizeHint) { - return hook->getResults(sizeHint).initAs(resultType); -} -inline void CallContext::setResults(DynamicStruct::Reader value) { - hook->getResults(value.totalSize()).setAs(value); -} -inline void CallContext::adoptResults(Orphan&& value) { - hook->getResults(MessageSize { 0, 0 }).adopt(kj::mv(value)); -} -inline Orphanage CallContext::getResultsOrphanage( - kj::Maybe sizeHint) { - return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); -} -template -inline kj::Promise CallContext::tailCall( - Request&& tailRequest) { - return hook->tailCall(kj::mv(tailRequest.hook)); -} -inline void CallContext::allowCancellation() { - hook->allowCancellation(); -} - -template <> -inline DynamicCapability::Client Capability::Client::castAs( - InterfaceSchema schema) { - return DynamicCapability::Client(schema, hook->addRef()); -} - -// ------------------------------------------------------------------- - -template -ReaderFor ConstSchema::as() const { - return DynamicValue::Reader(*this).as(); -} - -} // namespace capnp - -#endif // CAPNP_DYNAMIC_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 defines classes that can be used to manipulate messages based on schemas that are not +// known until runtime. This is also useful for writing generic code that uses schemas to handle +// arbitrary types in a generic way. +// +// Each of the classes defined here has a to() template method which converts an instance back to a +// native type. This method will throw an exception if the requested type does not match the +// schema. To convert native types to dynamic, use DynamicFactory. +// +// As always, underlying data is validated lazily, so you have to actually traverse the whole +// message if you want to validate all content. + +#ifndef CAPNP_DYNAMIC_H_ +#define CAPNP_DYNAMIC_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "schema.h" +#include "layout.h" +#include "message.h" +#include "any.h" +#include "capability.h" + +namespace capnp { + +class MessageReader; +class MessageBuilder; + +struct DynamicValue { + DynamicValue() = delete; + + enum Type { + UNKNOWN, + // Means that the value has unknown type and content because it comes from a newer version of + // the schema, or from a newer version of Cap'n Proto that has new features that this version + // doesn't understand. + + VOID, + BOOL, + INT, + UINT, + FLOAT, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + CAPABILITY, + ANY_POINTER + }; + + class Reader; + class Builder; + class Pipeline; +}; +class DynamicEnum; +struct DynamicStruct { + DynamicStruct() = delete; + class Reader; + class Builder; + class Pipeline; +}; +struct DynamicList { + DynamicList() = delete; + class Reader; + class Builder; +}; +struct DynamicCapability { + DynamicCapability() = delete; + class Client; + class Server; +}; +template <> class Orphan; + +template struct DynamicTypeFor_; +template <> struct DynamicTypeFor_ { typedef DynamicEnum Type; }; +template <> struct DynamicTypeFor_ { typedef DynamicStruct Type; }; +template <> struct DynamicTypeFor_ { typedef DynamicList Type; }; +template <> struct DynamicTypeFor_ { typedef DynamicCapability Type; }; + +template +using DynamicTypeFor = typename DynamicTypeFor_()>::Type; + +template +ReaderFor>> toDynamic(T&& value); +template +BuilderFor>> toDynamic(T&& value); +template +DynamicTypeFor> toDynamic(T&& value); +template +typename DynamicTypeFor>::Client toDynamic(kj::Own&& value); + +namespace _ { // private + +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; + +} // namespace _ (private) + +template <> inline constexpr Style style() { return Style::POINTER; } +template <> inline constexpr Style style() { return Style::PRIMITIVE; } +template <> inline constexpr Style style() { return Style::STRUCT; } +template <> inline constexpr Style style() { return Style::POINTER; } +template <> inline constexpr Style style() { return Style::CAPABILITY; } + +// ------------------------------------------------------------------- + +class DynamicEnum { +public: + DynamicEnum() = default; + inline DynamicEnum(EnumSchema::Enumerant enumerant) + : schema(enumerant.getContainingEnum()), value(enumerant.getOrdinal()) {} + inline DynamicEnum(EnumSchema schema, uint16_t value) + : schema(schema), value(value) {} + + template () == Kind::ENUM>> + inline DynamicEnum(T&& value): DynamicEnum(toDynamic(value)) {} + + template + inline T as() const { return static_cast(asImpl(typeId())); } + // Cast to a native enum type. + + inline EnumSchema getSchema() const { return schema; } + + kj::Maybe getEnumerant() const; + // Get which enumerant this enum value represents. Returns nullptr if the numeric value does not + // correspond to any enumerant in the schema -- this can happen if the data was built using a + // newer schema that has more values defined. + + inline uint16_t getRaw() const { return value; } + // Returns the raw underlying enum value. + +private: + EnumSchema schema; + uint16_t value; + + uint16_t asImpl(uint64_t requestedTypeId) const; + + friend struct DynamicStruct; + friend struct DynamicList; + friend struct DynamicValue; + template + friend DynamicTypeFor> toDynamic(T&& value); +}; + +// ------------------------------------------------------------------- + +class DynamicStruct::Reader { +public: + typedef DynamicStruct Reads; + + Reader() = default; + + template >() == Kind::STRUCT>> + inline Reader(T&& value): Reader(toDynamic(value)) {} + + inline MessageSize totalSize() const { return reader.totalSize().asPublic(); } + + template + typename T::Reader as() const; + // Convert the dynamic struct to its compiled-in type. + + inline StructSchema getSchema() const { return schema; } + + DynamicValue::Reader get(StructSchema::Field field) const; + // Read the given field value. + + bool has(StructSchema::Field field) const; + // Tests whether the given field is set to its default value. For pointer values, this does + // not actually traverse the value comparing it with the default, but simply returns true if the + // pointer is non-null. For members of unions, has() returns false if the union member is not + // active, but does not necessarily return true if the member is active (depends on the field's + // value). + + kj::Maybe which() const; + // If the struct contains an (unnamed) union, and the currently-active field within that union + // is known, this returns that field. Otherwise, it returns null. In other words, this returns + // null if there is no union present _or_ if the union's discriminant is set to an unrecognized + // value. This could happen in particular when receiving a message from a sender who has a + // newer version of the protocol and is using a field of the union that you don't know about yet. + + DynamicValue::Reader get(kj::StringPtr name) const; + bool has(kj::StringPtr name) const; + // Shortcuts to access fields by name. These throw exceptions if no such field exists. + +private: + StructSchema schema; + _::StructReader reader; + + inline Reader(StructSchema schema, _::StructReader reader) + : schema(schema), reader(reader) {} + Reader(StructSchema schema, const _::OrphanBuilder& orphan); + + bool isSetInUnion(StructSchema::Field field) const; + void verifySetInUnion(StructSchema::Field field) const; + static DynamicValue::Reader getImpl(_::StructReader reader, StructSchema::Field field); + + template + friend struct _::PointerHelpers; + friend class DynamicStruct::Builder; + friend struct DynamicList; + friend class MessageReader; + friend class MessageBuilder; + template + friend struct ::capnp::ToDynamic_; + friend kj::StringTree _::structString( + _::StructReader reader, const _::RawBrandedSchema& schema); + friend class Orphanage; + friend class Orphan; + friend class Orphan; + friend class Orphan; +}; + +class DynamicStruct::Builder { +public: + typedef DynamicStruct Builds; + + Builder() = default; + inline Builder(decltype(nullptr)) {} + + template >() == Kind::STRUCT>> + inline Builder(T&& value): Builder(toDynamic(value)) {} + + inline MessageSize totalSize() const { return asReader().totalSize(); } + + template + typename T::Builder as(); + // Cast to a particular struct type. + + inline StructSchema getSchema() const { return schema; } + + DynamicValue::Builder get(StructSchema::Field field); + // Read the given field value. + + inline bool has(StructSchema::Field field) { return asReader().has(field); } + // Tests whether the given field is set to its default value. For pointer values, this does + // not actually traverse the value comparing it with the default, but simply returns true if the + // pointer is non-null. For members of unions, has() returns whether the field is currently + // active and the union as a whole is non-default -- so, the only time has() will return false + // for an active union field is if it is the default active field and it has its default value. + + kj::Maybe which(); + // If the struct contains an (unnamed) union, and the currently-active field within that union + // is known, this returns that field. Otherwise, it returns null. In other words, this returns + // null if there is no union present _or_ if the union's discriminant is set to an unrecognized + // value. This could happen in particular when receiving a message from a sender who has a + // newer version of the protocol and is using a field of the union that you don't know about yet. + + void set(StructSchema::Field field, const DynamicValue::Reader& value); + // Set the given field value. + + DynamicValue::Builder init(StructSchema::Field field); + DynamicValue::Builder init(StructSchema::Field field, uint size); + // Init a struct, list, or blob field. + + void adopt(StructSchema::Field field, Orphan&& orphan); + Orphan disown(StructSchema::Field field); + // Adopt/disown. This works even for non-pointer fields: adopt() becomes equivalent to set() + // and disown() becomes like get() followed by clear(). + + void clear(StructSchema::Field field); + // Clear a field, setting it to its default value. For pointer fields, this actually makes the + // field null. + + DynamicValue::Builder get(kj::StringPtr name); + bool has(kj::StringPtr name); + void set(kj::StringPtr name, const DynamicValue::Reader& value); + void set(kj::StringPtr name, std::initializer_list value); + DynamicValue::Builder init(kj::StringPtr name); + DynamicValue::Builder init(kj::StringPtr name, uint size); + void adopt(kj::StringPtr name, Orphan&& orphan); + Orphan disown(kj::StringPtr name); + void clear(kj::StringPtr name); + // Shortcuts to access fields by name. These throw exceptions if no such field exists. + + Reader asReader() const; + +private: + StructSchema schema; + _::StructBuilder builder; + + inline Builder(StructSchema schema, _::StructBuilder builder) + : schema(schema), builder(builder) {} + Builder(StructSchema schema, _::OrphanBuilder& orphan); + + bool isSetInUnion(StructSchema::Field field); + void verifySetInUnion(StructSchema::Field field); + void setInUnion(StructSchema::Field field); + + template + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class MessageReader; + friend class MessageBuilder; + template + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + friend class Orphan; + friend class Orphan; + friend class Orphan; +}; + +class DynamicStruct::Pipeline { +public: + typedef DynamicStruct Pipelines; + + inline Pipeline(decltype(nullptr)): typeless(nullptr) {} + + template + typename T::Pipeline releaseAs(); + // Convert the dynamic pipeline to its compiled-in type. + + inline StructSchema getSchema() { return schema; } + + DynamicValue::Pipeline get(StructSchema::Field field); + // Read the given field value. + + DynamicValue::Pipeline get(kj::StringPtr name); + // Get by string name. + +private: + StructSchema schema; + AnyPointer::Pipeline typeless; + + inline explicit Pipeline(StructSchema schema, AnyPointer::Pipeline&& typeless) + : schema(schema), typeless(kj::mv(typeless)) {} + + friend class Request; +}; + +// ------------------------------------------------------------------- + +class DynamicList::Reader { +public: + typedef DynamicList Reads; + + inline Reader(): reader(ElementSize::VOID) {} + + template >() == Kind::LIST>> + inline Reader(T&& value): Reader(toDynamic(value)) {} + + template + typename T::Reader as() const; + // Try to convert to any List, Data, or Text. Throws an exception if the underlying data + // can't possibly represent the requested type. + + inline ListSchema getSchema() const { return schema; } + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + DynamicValue::Reader operator[](uint index) const; + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + ListSchema schema; + _::ListReader reader; + + Reader(ListSchema schema, _::ListReader reader): schema(schema), reader(reader) {} + Reader(ListSchema schema, const _::OrphanBuilder& orphan); + + template + friend struct _::PointerHelpers; + friend struct DynamicStruct; + friend class DynamicList::Builder; + template + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + friend class Orphan; + friend class Orphan; + friend class Orphan; +}; + +class DynamicList::Builder { +public: + typedef DynamicList Builds; + + inline Builder(): builder(ElementSize::VOID) {} + inline Builder(decltype(nullptr)): builder(ElementSize::VOID) {} + + template >() == Kind::LIST>> + inline Builder(T&& value): Builder(toDynamic(value)) {} + + template + typename T::Builder as(); + // Try to convert to any List, Data, or Text. Throws an exception if the underlying data + // can't possibly represent the requested type. + + inline ListSchema getSchema() const { return schema; } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + DynamicValue::Builder operator[](uint index); + void set(uint index, const DynamicValue::Reader& value); + DynamicValue::Builder init(uint index, uint size); + void adopt(uint index, Orphan&& orphan); + Orphan disown(uint index); + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + void copyFrom(std::initializer_list value); + + Reader asReader() const; + +private: + ListSchema schema; + _::ListBuilder builder; + + Builder(ListSchema schema, _::ListBuilder builder): schema(schema), builder(builder) {} + Builder(ListSchema schema, _::OrphanBuilder& orphan); + + template + friend struct _::PointerHelpers; + friend struct DynamicStruct; + template + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + template + friend struct _::OrphanGetImpl; + friend class Orphan; + friend class Orphan; + friend class Orphan; +}; + +// ------------------------------------------------------------------- + +class DynamicCapability::Client: public Capability::Client { +public: + typedef DynamicCapability Calls; + typedef DynamicCapability Reads; + + Client() = default; + + template >() == Kind::INTERFACE>> + inline Client(T&& client); + + template ()>> + inline Client(kj::Own&& server); + + template () == Kind::INTERFACE>> + typename T::Client as(); + template () == Kind::INTERFACE>> + typename T::Client releaseAs(); + // Convert to any client type. + + Client upcast(InterfaceSchema requestedSchema); + // Upcast to a superclass. Throws an exception if `schema` is not a superclass. + + inline InterfaceSchema getSchema() { return schema; } + + Request newRequest( + InterfaceSchema::Method method, kj::Maybe sizeHint = nullptr); + Request newRequest( + kj::StringPtr methodName, kj::Maybe sizeHint = nullptr); + +private: + InterfaceSchema schema; + + Client(InterfaceSchema schema, kj::Own&& hook) + : Capability::Client(kj::mv(hook)), schema(schema) {} + + template + inline Client(InterfaceSchema schema, kj::Own&& server); + + friend struct Capability; + friend struct DynamicStruct; + friend struct DynamicList; + friend struct DynamicValue; + friend class Orphan; + friend class Orphan; + friend class Orphan; + template + friend struct _::PointerHelpers; +}; + +class DynamicCapability::Server: public Capability::Server { +public: + typedef DynamicCapability Serves; + + Server(InterfaceSchema schema): schema(schema) {} + + virtual kj::Promise call(InterfaceSchema::Method method, + CallContext context) = 0; + + kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, + CallContext context) override final; + + inline InterfaceSchema getSchema() const { return schema; } + +private: + InterfaceSchema schema; +}; + +template <> +class Request: public DynamicStruct::Builder { + // Specialization of `Request` for DynamicStruct. + +public: + inline Request(DynamicStruct::Builder builder, kj::Own&& hook, + StructSchema resultSchema) + : DynamicStruct::Builder(builder), hook(kj::mv(hook)), resultSchema(resultSchema) {} + + RemotePromise send(); + // Send the call and return a promise for the results. + +private: + kj::Own hook; + StructSchema resultSchema; + + friend class Capability::Client; + friend struct DynamicCapability; + template + friend class CallContext; + friend class RequestHook; +}; + +template <> +class CallContext: public kj::DisallowConstCopy { + // Wrapper around CallContextHook with a specific return type. + // + // Methods of this class may only be called from within the server's event loop, not from other + // threads. + +public: + explicit CallContext(CallContextHook& hook, StructSchema paramType, StructSchema resultType); + + DynamicStruct::Reader getParams(); + void releaseParams(); + DynamicStruct::Builder getResults(kj::Maybe sizeHint = nullptr); + DynamicStruct::Builder initResults(kj::Maybe sizeHint = nullptr); + void setResults(DynamicStruct::Reader value); + void adoptResults(Orphan&& value); + Orphanage getResultsOrphanage(kj::Maybe sizeHint = nullptr); + template + kj::Promise tailCall(Request&& tailRequest); + void allowCancellation(); + +private: + CallContextHook* hook; + StructSchema paramType; + StructSchema resultType; + + friend class DynamicCapability::Server; +}; + +// ------------------------------------------------------------------- + +// Make sure ReaderFor and BuilderFor work for DynamicEnum, DynamicStruct, and +// DynamicList, so that we can define DynamicValue::as(). + +template <> struct ReaderFor_ { typedef DynamicEnum Type; }; +template <> struct BuilderFor_ { typedef DynamicEnum Type; }; +template <> struct ReaderFor_ { typedef DynamicStruct::Reader Type; }; +template <> struct BuilderFor_ { typedef DynamicStruct::Builder Type; }; +template <> struct ReaderFor_ { typedef DynamicList::Reader Type; }; +template <> struct BuilderFor_ { typedef DynamicList::Builder Type; }; +template <> struct ReaderFor_ { typedef DynamicCapability::Client Type; }; +template <> struct BuilderFor_ { typedef DynamicCapability::Client Type; }; +template <> struct PipelineFor_ { typedef DynamicCapability::Client Type; }; + +class DynamicValue::Reader { +public: + typedef DynamicValue Reads; + + inline Reader(decltype(nullptr) n = nullptr); // UNKNOWN + inline Reader(Void value); + inline Reader(bool value); + inline Reader(char value); + inline Reader(signed char value); + inline Reader(short value); + inline Reader(int value); + inline Reader(long value); + inline Reader(long long value); + inline Reader(unsigned char value); + inline Reader(unsigned short value); + inline Reader(unsigned int value); + inline Reader(unsigned long value); + inline Reader(unsigned long long value); + inline Reader(float value); + inline Reader(double value); + inline Reader(const char* value); // Text + inline Reader(const Text::Reader& value); + inline Reader(const Data::Reader& value); + inline Reader(const DynamicList::Reader& value); + inline Reader(DynamicEnum value); + inline Reader(const DynamicStruct::Reader& value); + inline Reader(const AnyPointer::Reader& value); + inline Reader(DynamicCapability::Client& value); + inline Reader(DynamicCapability::Client&& value); + template ()>> + inline Reader(kj::Own&& value); + Reader(ConstSchema constant); + + template ()))> + inline Reader(T&& value): Reader(toDynamic(kj::mv(value))) {} + + Reader(const Reader& other); + Reader(Reader&& other) noexcept; + ~Reader() noexcept(false); + Reader& operator=(const Reader& other); + Reader& operator=(Reader&& other); + // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not + // trivially copyable. + + template + inline ReaderFor as() const { return AsImpl::apply(*this); } + // Use to interpret the value as some Cap'n Proto type. Allowed types are: + // - Void, bool, [u]int{8,16,32,64}_t, float, double, any enum: Returns the raw value. + // - Text, Data, AnyPointer, any struct type: Returns the corresponding Reader. + // - List for any T listed above: Returns List::Reader. + // - DynamicEnum: Returns the corresponding type. + // - DynamicStruct, DynamicList: Returns the corresponding Reader. + // - Any capability type, including DynamicCapability: Returns the corresponding Client. + // - DynamicValue: Returns an identical Reader. Useful to avoid special-casing in generic code. + // (TODO(perf): On GCC 4.8 / Clang 3.3, provide rvalue-qualified version that avoids + // refcounting.) + // + // DynamicValue allows various implicit conversions, mostly just to make the interface friendlier. + // - Any integer can be converted to any other integer type so long as the actual value is within + // the new type's range. + // - Floating-point types can be converted to integers as long as no information would be lost + // in the conversion. + // - Integers can be converted to floating points. This may lose information, but won't throw. + // - Float32/Float64 can be converted between each other. Converting Float64 -> Float32 may lose + // information, but won't throw. + // - Text can be converted to an enum, if the Text matches one of the enumerant names (but not + // vice-versa). + // - Capabilities can be upcast (cast to a supertype), but not downcast. + // + // Any other conversion attempt will throw an exception. + + inline Type getType() const { return type; } + // Get the type of this value. + +private: + Type type; + + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + Text::Reader textValue; + Data::Reader dataValue; + DynamicList::Reader listValue; + DynamicEnum enumValue; + DynamicStruct::Reader structValue; + AnyPointer::Reader anyPointerValue; + + mutable DynamicCapability::Client capabilityValue; + // Declared mutable because `Client`s normally cannot be const. + + // Warning: Copy/move constructors assume all these types are trivially copyable except + // Capability. + }; + + template ()> struct AsImpl; + // Implementation backing the as() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. + + friend class Orphanage; // to speed up newOrphanCopy(DynamicValue::Reader) +}; + +class DynamicValue::Builder { +public: + typedef DynamicValue Builds; + + inline Builder(decltype(nullptr) n = nullptr); // UNKNOWN + inline Builder(Void value); + inline Builder(bool value); + inline Builder(char value); + inline Builder(signed char value); + inline Builder(short value); + inline Builder(int value); + inline Builder(long value); + inline Builder(long long value); + inline Builder(unsigned char value); + inline Builder(unsigned short value); + inline Builder(unsigned int value); + inline Builder(unsigned long value); + inline Builder(unsigned long long value); + inline Builder(float value); + inline Builder(double value); + inline Builder(Text::Builder value); + inline Builder(Data::Builder value); + inline Builder(DynamicList::Builder value); + inline Builder(DynamicEnum value); + inline Builder(DynamicStruct::Builder value); + inline Builder(AnyPointer::Builder value); + inline Builder(DynamicCapability::Client& value); + inline Builder(DynamicCapability::Client&& value); + + template ()))> + inline Builder(T value): Builder(toDynamic(value)) {} + + Builder(Builder& other); + Builder(Builder&& other) noexcept; + ~Builder() noexcept(false); + Builder& operator=(Builder& other); + Builder& operator=(Builder&& other); + // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not + // trivially copyable. + + template + inline BuilderFor as() { return AsImpl::apply(*this); } + // See DynamicValue::Reader::as(). + + inline Type getType() { return type; } + // Get the type of this value. + + Reader asReader() const; + +private: + Type type; + + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + Text::Builder textValue; + Data::Builder dataValue; + DynamicList::Builder listValue; + DynamicEnum enumValue; + DynamicStruct::Builder structValue; + AnyPointer::Builder anyPointerValue; + + mutable DynamicCapability::Client capabilityValue; + // Declared mutable because `Client`s normally cannot be const. + }; + + template ()> struct AsImpl; + // Implementation backing the as() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. + + friend class Orphan; +}; + +class DynamicValue::Pipeline { +public: + typedef DynamicValue Pipelines; + + inline Pipeline(decltype(nullptr) n = nullptr); + inline Pipeline(DynamicStruct::Pipeline&& value); + inline Pipeline(DynamicCapability::Client&& value); + + Pipeline(Pipeline&& other) noexcept; + Pipeline& operator=(Pipeline&& other); + ~Pipeline() noexcept(false); + + template + inline PipelineFor releaseAs() { return AsImpl::apply(*this); } + + inline Type getType() { return type; } + // Get the type of this value. + +private: + Type type; + union { + DynamicStruct::Pipeline structValue; + DynamicCapability::Client capabilityValue; + }; + + template ()> struct AsImpl; + // Implementation backing the releaseAs() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. +}; + +kj::StringTree KJ_STRINGIFY(const DynamicValue::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicValue::Builder& value); +kj::StringTree KJ_STRINGIFY(DynamicEnum value); +kj::StringTree KJ_STRINGIFY(const DynamicStruct::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicStruct::Builder& value); +kj::StringTree KJ_STRINGIFY(const DynamicList::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicList::Builder& value); + +// ------------------------------------------------------------------- +// Orphan <-> Dynamic glue + +template <> +class Orphan { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template () == Kind::STRUCT>> + inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} + + DynamicStruct::Builder get(); + DynamicStruct::Reader getReader() const; + + template + Orphan releaseAs(); + // Like DynamicStruct::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan is no longer valid after this call; ownership is + // transferred to the returned Orphan. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + StructSchema schema; + _::OrphanBuilder builder; + + inline Orphan(StructSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan; + friend class Orphan; + friend class MessageBuilder; +}; + +template <> +class Orphan { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template () == Kind::LIST>> + inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} + + DynamicList::Builder get(); + DynamicList::Reader getReader() const; + + template + Orphan releaseAs(); + // Like DynamicList::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan is no longer valid after this call; ownership is + // transferred to the returned Orphan. + + // TODO(someday): Support truncate(). + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + ListSchema schema; + _::OrphanBuilder builder; + + inline Orphan(ListSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan; + friend class Orphan; +}; + +template <> +class Orphan { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template () == Kind::INTERFACE>> + inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} + + DynamicCapability::Client get(); + DynamicCapability::Client getReader() const; + + template + Orphan releaseAs(); + // Like DynamicCapability::Client::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan is no longer valid after this call; ownership is + // transferred to the returned Orphan. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + InterfaceSchema schema; + _::OrphanBuilder builder; + + inline Orphan(InterfaceSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan; + friend class Orphan; +}; + +template <> +class Orphan { +public: + inline Orphan(decltype(nullptr) n = nullptr): type(DynamicValue::UNKNOWN) {} + inline Orphan(Void value); + inline Orphan(bool value); + inline Orphan(char value); + inline Orphan(signed char value); + inline Orphan(short value); + inline Orphan(int value); + inline Orphan(long value); + inline Orphan(long long value); + inline Orphan(unsigned char value); + inline Orphan(unsigned short value); + inline Orphan(unsigned int value); + inline Orphan(unsigned long value); + inline Orphan(unsigned long long value); + inline Orphan(float value); + inline Orphan(double value); + inline Orphan(DynamicEnum value); + Orphan(Orphan&&) = default; + template + Orphan(Orphan&&); + Orphan(Orphan&&); + Orphan(void*) = delete; // So Orphan(bool) doesn't accept pointers. + KJ_DISALLOW_COPY(Orphan); + + Orphan& operator=(Orphan&&) = default; + + inline DynamicValue::Type getType() { return type; } + + DynamicValue::Builder get(); + DynamicValue::Reader getReader() const; + + template + Orphan releaseAs(); + // Like DynamicValue::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan is no longer valid after this call; ownership is + // transferred to the returned Orphan. + +private: + DynamicValue::Type type; + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + DynamicEnum enumValue; + StructSchema structSchema; + ListSchema listSchema; + InterfaceSchema interfaceSchema; + }; + + _::OrphanBuilder builder; + // Only used if `type` is a pointer type. + + Orphan(DynamicValue::Builder value, _::OrphanBuilder&& builder); + Orphan(DynamicValue::Type type, _::OrphanBuilder&& builder) + : type(type), builder(kj::mv(builder)) {} + Orphan(StructSchema structSchema, _::OrphanBuilder&& builder) + : type(DynamicValue::STRUCT), structSchema(structSchema), builder(kj::mv(builder)) {} + Orphan(ListSchema listSchema, _::OrphanBuilder&& builder) + : type(DynamicValue::LIST), listSchema(listSchema), builder(kj::mv(builder)) {} + + template + friend struct _::PointerHelpers; + friend struct DynamicStruct; + friend struct DynamicList; + friend struct AnyPointer; + friend class Orphanage; +}; + +template +inline Orphan::Orphan(Orphan&& other) + : Orphan(other.get(), kj::mv(other.builder)) {} + +inline Orphan::Orphan(Orphan&& other) + : type(DynamicValue::ANY_POINTER), builder(kj::mv(other.builder)) {} + +template +Orphan Orphan::releaseAs() { + get().as(); // type check + return Orphan(kj::mv(builder)); +} + +template +Orphan Orphan::releaseAs() { + get().as(); // type check + return Orphan(kj::mv(builder)); +} + +template +Orphan Orphan::releaseAs() { + get().as(); // type check + return Orphan(kj::mv(builder)); +} + +template +Orphan Orphan::releaseAs() { + get().as(); // type check + type = DynamicValue::UNKNOWN; + return Orphan(kj::mv(builder)); +} + +template <> +Orphan Orphan::releaseAs(); +template <> +Orphan Orphan::releaseAs(); +template <> +Orphan Orphan::releaseAs(); +template <> +Orphan Orphan::releaseAs(); + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::StructBuilder apply(DynamicStruct::Builder& t) { + return t.builder; + } +}; + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::ListBuilder apply(DynamicList::Builder& t) { + return t.builder; + } +}; + +template <> +inline Orphan Orphanage::newOrphanCopy( + DynamicStruct::Reader copyFrom) const { + return Orphan( + copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); +} + +template <> +inline Orphan Orphanage::newOrphanCopy( + DynamicList::Reader copyFrom) const { + return Orphan(copyFrom.getSchema(), + _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); +} + +template <> +inline Orphan Orphanage::newOrphanCopy( + DynamicCapability::Client copyFrom) const { + return Orphan( + copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.hook->addRef())); +} + +template <> +Orphan Orphanage::newOrphanCopy( + DynamicValue::Reader copyFrom) const; + +namespace _ { // private + +template <> +struct PointerHelpers { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicStruct::Reader getDynamic(PointerReader reader, StructSchema schema); + static DynamicStruct::Builder getDynamic(PointerBuilder builder, StructSchema schema); + static void set(PointerBuilder builder, const DynamicStruct::Reader& value); + static DynamicStruct::Builder init(PointerBuilder builder, StructSchema schema); + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder, StructSchema schema) { + return Orphan(schema, builder.disown()); + } +}; + +template <> +struct PointerHelpers { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicList::Reader getDynamic(PointerReader reader, ListSchema schema); + static DynamicList::Builder getDynamic(PointerBuilder builder, ListSchema schema); + static void set(PointerBuilder builder, const DynamicList::Reader& value); + static DynamicList::Builder init(PointerBuilder builder, ListSchema schema, uint size); + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder, ListSchema schema) { + return Orphan(schema, builder.disown()); + } +}; + +template <> +struct PointerHelpers { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicCapability::Client getDynamic(PointerReader reader, InterfaceSchema schema); + static DynamicCapability::Client getDynamic(PointerBuilder builder, InterfaceSchema schema); + static void set(PointerBuilder builder, DynamicCapability::Client& value); + static void set(PointerBuilder builder, DynamicCapability::Client&& value); + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder, InterfaceSchema schema) { + return Orphan(schema, builder.disown()); + } +}; + +} // namespace _ (private) + +template +inline ReaderFor AnyPointer::Reader::getAs(StructSchema schema) const { + return _::PointerHelpers::getDynamic(reader, schema); +} +template +inline ReaderFor AnyPointer::Reader::getAs(ListSchema schema) const { + return _::PointerHelpers::getDynamic(reader, schema); +} +template +inline ReaderFor AnyPointer::Reader::getAs(InterfaceSchema schema) const { + return _::PointerHelpers::getDynamic(reader, schema); +} +template +inline BuilderFor AnyPointer::Builder::getAs(StructSchema schema) { + return _::PointerHelpers::getDynamic(builder, schema); +} +template +inline BuilderFor AnyPointer::Builder::getAs(ListSchema schema) { + return _::PointerHelpers::getDynamic(builder, schema); +} +template +inline BuilderFor AnyPointer::Builder::getAs(InterfaceSchema schema) { + return _::PointerHelpers::getDynamic(builder, schema); +} +template +inline BuilderFor AnyPointer::Builder::initAs(StructSchema schema) { + return _::PointerHelpers::init(builder, schema); +} +template +inline BuilderFor AnyPointer::Builder::initAs(ListSchema schema, uint elementCount) { + return _::PointerHelpers::init(builder, schema, elementCount); +} +template <> +inline void AnyPointer::Builder::setAs(DynamicStruct::Reader value) { + return _::PointerHelpers::set(builder, value); +} +template <> +inline void AnyPointer::Builder::setAs(DynamicList::Reader value) { + return _::PointerHelpers::set(builder, value); +} +template <> +inline void AnyPointer::Builder::setAs(DynamicCapability::Client value) { + return _::PointerHelpers::set(builder, kj::mv(value)); +} +template <> +void AnyPointer::Builder::adopt(Orphan&& orphan); +template +inline Orphan AnyPointer::Builder::disownAs(StructSchema schema) { + return _::PointerHelpers::disown(builder, schema); +} +template +inline Orphan AnyPointer::Builder::disownAs(ListSchema schema) { + return _::PointerHelpers::disown(builder, schema); +} +template +inline Orphan AnyPointer::Builder::disownAs(InterfaceSchema schema) { + return _::PointerHelpers::disown(builder, schema); +} + +// We have to declare the methods below inline because Clang and GCC disagree about how to mangle +// their symbol names. +template <> +inline DynamicStruct::Builder Orphan::getAs(StructSchema schema) { + return DynamicStruct::Builder(schema, builder); +} +template <> +inline DynamicStruct::Reader Orphan::getAsReader( + StructSchema schema) const { + return DynamicStruct::Reader(schema, builder); +} +template <> +inline Orphan Orphan::releaseAs(StructSchema schema) { + return Orphan(schema, kj::mv(builder)); +} +template <> +inline DynamicList::Builder Orphan::getAs(ListSchema schema) { + return DynamicList::Builder(schema, builder); +} +template <> +inline DynamicList::Reader Orphan::getAsReader(ListSchema schema) const { + return DynamicList::Reader(schema, builder); +} +template <> +inline Orphan Orphan::releaseAs(ListSchema schema) { + return Orphan(schema, kj::mv(builder)); +} +template <> +inline DynamicCapability::Client Orphan::getAs( + InterfaceSchema schema) { + return DynamicCapability::Client(schema, builder.asCapability()); +} +template <> +inline DynamicCapability::Client Orphan::getAsReader( + InterfaceSchema schema) const { + return DynamicCapability::Client(schema, builder.asCapability()); +} +template <> +inline Orphan Orphan::releaseAs( + InterfaceSchema schema) { + return Orphan(schema, kj::mv(builder)); +} + +// ======================================================================================= +// Inline implementation details. + +template +struct ToDynamic_ { + static inline DynamicStruct::Reader apply(const typename T::Reader& value) { + return DynamicStruct::Reader(Schema::from(), value._reader); + } + static inline DynamicStruct::Builder apply(typename T::Builder& value) { + return DynamicStruct::Builder(Schema::from(), value._builder); + } +}; + +template +struct ToDynamic_ { + static inline DynamicList::Reader apply(const typename T::Reader& value) { + return DynamicList::Reader(Schema::from(), value.reader); + } + static inline DynamicList::Builder apply(typename T::Builder& value) { + return DynamicList::Builder(Schema::from(), value.builder); + } +}; + +template +struct ToDynamic_ { + static inline DynamicCapability::Client apply(typename T::Client value) { + return DynamicCapability::Client(kj::mv(value)); + } + static inline DynamicCapability::Client apply(typename T::Client&& value) { + return DynamicCapability::Client(kj::mv(value)); + } +}; + +template +ReaderFor>> toDynamic(T&& value) { + return ToDynamic_>::apply(value); +} +template +BuilderFor>> toDynamic(T&& value) { + return ToDynamic_>::apply(value); +} +template +DynamicTypeFor> toDynamic(T&& value) { + return DynamicEnum(Schema::from>(), static_cast(value)); +} +template +typename DynamicTypeFor>::Client toDynamic(kj::Own&& value) { + return typename FromServer::Client(kj::mv(value)); +} + +inline DynamicValue::Reader::Reader(std::nullptr_t n): type(UNKNOWN) {} +inline DynamicValue::Builder::Builder(std::nullptr_t n): type(UNKNOWN) {} + +#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ +inline DynamicValue::Reader::Reader(cppType value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline DynamicValue::Builder::Builder(cppType value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline Orphan::Orphan(cppType value) \ + : type(DynamicValue::typeTag), fieldName##Value(value) {} + +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Void, VOID, void); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(bool, BOOL, bool); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(char, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(signed char, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(short, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(int, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long long, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned char, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned short, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned int, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long long, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(float, FLOAT, float); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(double, FLOAT, float); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicEnum, ENUM, enum); +#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR + +#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ +inline DynamicValue::Reader::Reader(const cppType::Reader& value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline DynamicValue::Builder::Builder(cppType::Builder value) \ + : type(typeTag), fieldName##Value(value) {} + +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Text, TEXT, text); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Data, DATA, data); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicList, LIST, list); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicStruct, STRUCT, struct); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(AnyPointer, ANY_POINTER, anyPointer); + +#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR + +inline DynamicValue::Reader::Reader(DynamicCapability::Client& value) + : type(CAPABILITY), capabilityValue(value) {} +inline DynamicValue::Reader::Reader(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} +template +inline DynamicValue::Reader::Reader(kj::Own&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} +inline DynamicValue::Builder::Builder(DynamicCapability::Client& value) + : type(CAPABILITY), capabilityValue(value) {} +inline DynamicValue::Builder::Builder(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} + +inline DynamicValue::Reader::Reader(const char* value): Reader(Text::Reader(value)) {} + +#define CAPNP_DECLARE_TYPE(discrim, typeName) \ +template <> \ +struct DynamicValue::Reader::AsImpl { \ + static ReaderFor apply(const Reader& reader); \ +}; \ +template <> \ +struct DynamicValue::Builder::AsImpl { \ + static BuilderFor apply(Builder& builder); \ +}; + +//CAPNP_DECLARE_TYPE(VOID, Void) +CAPNP_DECLARE_TYPE(BOOL, bool) +CAPNP_DECLARE_TYPE(INT8, int8_t) +CAPNP_DECLARE_TYPE(INT16, int16_t) +CAPNP_DECLARE_TYPE(INT32, int32_t) +CAPNP_DECLARE_TYPE(INT64, int64_t) +CAPNP_DECLARE_TYPE(UINT8, uint8_t) +CAPNP_DECLARE_TYPE(UINT16, uint16_t) +CAPNP_DECLARE_TYPE(UINT32, uint32_t) +CAPNP_DECLARE_TYPE(UINT64, uint64_t) +CAPNP_DECLARE_TYPE(FLOAT32, float) +CAPNP_DECLARE_TYPE(FLOAT64, double) + +CAPNP_DECLARE_TYPE(TEXT, Text) +CAPNP_DECLARE_TYPE(DATA, Data) +CAPNP_DECLARE_TYPE(LIST, DynamicList) +CAPNP_DECLARE_TYPE(STRUCT, DynamicStruct) +CAPNP_DECLARE_TYPE(INTERFACE, DynamicCapability) +CAPNP_DECLARE_TYPE(ENUM, DynamicEnum) +CAPNP_DECLARE_TYPE(ANY_POINTER, AnyPointer) +#undef CAPNP_DECLARE_TYPE + +// CAPNP_DECLARE_TYPE(Void) causes gcc 4.7 to segfault. If I do it manually and remove the +// ReaderFor<> and BuilderFor<> wrappers, it works. +template <> +struct DynamicValue::Reader::AsImpl { + static Void apply(const Reader& reader); +}; +template <> +struct DynamicValue::Builder::AsImpl { + static Void apply(Builder& builder); +}; + +template +struct DynamicValue::Reader::AsImpl { + static T apply(const Reader& reader) { + return reader.as().as(); + } +}; +template +struct DynamicValue::Builder::AsImpl { + static T apply(Builder& builder) { + return builder.as().as(); + } +}; + +template +struct DynamicValue::Reader::AsImpl { + static typename T::Reader apply(const Reader& reader) { + return reader.as().as(); + } +}; +template +struct DynamicValue::Builder::AsImpl { + static typename T::Builder apply(Builder& builder) { + return builder.as().as(); + } +}; + +template +struct DynamicValue::Reader::AsImpl { + static typename T::Reader apply(const Reader& reader) { + return reader.as().as(); + } +}; +template +struct DynamicValue::Builder::AsImpl { + static typename T::Builder apply(Builder& builder) { + return builder.as().as(); + } +}; + +template +struct DynamicValue::Reader::AsImpl { + static typename T::Client apply(const Reader& reader) { + return reader.as().as(); + } +}; +template +struct DynamicValue::Builder::AsImpl { + static typename T::Client apply(Builder& builder) { + return builder.as().as(); + } +}; + +template <> +struct DynamicValue::Reader::AsImpl { + static DynamicValue::Reader apply(const Reader& reader) { + return reader; + } +}; +template <> +struct DynamicValue::Builder::AsImpl { + static DynamicValue::Builder apply(Builder& builder) { + return builder; + } +}; + +inline DynamicValue::Pipeline::Pipeline(std::nullptr_t n): type(UNKNOWN) {} +inline DynamicValue::Pipeline::Pipeline(DynamicStruct::Pipeline&& value) + : type(STRUCT), structValue(kj::mv(value)) {} +inline DynamicValue::Pipeline::Pipeline(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} + +template +struct DynamicValue::Pipeline::AsImpl { + static typename T::Pipeline apply(Pipeline& pipeline) { + return pipeline.releaseAs().releaseAs(); + } +}; +template +struct DynamicValue::Pipeline::AsImpl { + static typename T::Client apply(Pipeline& pipeline) { + return pipeline.releaseAs().releaseAs(); + } +}; +template <> +struct DynamicValue::Pipeline::AsImpl { + static PipelineFor apply(Pipeline& pipeline); +}; +template <> +struct DynamicValue::Pipeline::AsImpl { + static PipelineFor apply(Pipeline& pipeline); +}; + +// ------------------------------------------------------------------- + +template +typename T::Reader DynamicStruct::Reader::as() const { + static_assert(kind() == Kind::STRUCT, + "DynamicStruct::Reader::as() can only convert to struct types."); + schema.requireUsableAs(); + return typename T::Reader(reader); +} + +template +typename T::Builder DynamicStruct::Builder::as() { + static_assert(kind() == Kind::STRUCT, + "DynamicStruct::Builder::as() can only convert to struct types."); + schema.requireUsableAs(); + return typename T::Builder(builder); +} + +template <> +inline DynamicStruct::Reader DynamicStruct::Reader::as() const { + return *this; +} +template <> +inline DynamicStruct::Builder DynamicStruct::Builder::as() { + return *this; +} + +inline DynamicStruct::Reader DynamicStruct::Builder::asReader() const { + return DynamicStruct::Reader(schema, builder.asReader()); +} + +template <> +inline AnyStruct::Reader DynamicStruct::Reader::as() const { + return AnyStruct::Reader(reader); +} + +template <> +inline AnyStruct::Builder DynamicStruct::Builder::as() { + return AnyStruct::Builder(builder); +} + +template +typename T::Pipeline DynamicStruct::Pipeline::releaseAs() { + static_assert(kind() == Kind::STRUCT, + "DynamicStruct::Pipeline::releaseAs() can only convert to struct types."); + schema.requireUsableAs(); + return typename T::Pipeline(kj::mv(typeless)); +} + +// ------------------------------------------------------------------- + +template +typename T::Reader DynamicList::Reader::as() const { + static_assert(kind() == Kind::LIST, + "DynamicStruct::Reader::as() can only convert to list types."); + schema.requireUsableAs(); + return typename T::Reader(reader); +} +template +typename T::Builder DynamicList::Builder::as() { + static_assert(kind() == Kind::LIST, + "DynamicStruct::Builder::as() can only convert to list types."); + schema.requireUsableAs(); + return typename T::Builder(builder); +} + +template <> +inline DynamicList::Reader DynamicList::Reader::as() const { + return *this; +} +template <> +inline DynamicList::Builder DynamicList::Builder::as() { + return *this; +} + +template <> +inline AnyList::Reader DynamicList::Reader::as() const { + return AnyList::Reader(reader); +} + +template <> +inline AnyList::Builder DynamicList::Builder::as() { + return AnyList::Builder(builder); +} + +// ------------------------------------------------------------------- + +template +inline DynamicCapability::Client::Client(T&& client) + : Capability::Client(kj::mv(client)), schema(Schema::from>()) {} + +template +inline DynamicCapability::Client::Client(kj::Own&& server) + : Client(server->getSchema(), kj::mv(server)) {} +template +inline DynamicCapability::Client::Client(InterfaceSchema schema, kj::Own&& server) + : Capability::Client(kj::mv(server)), schema(schema) {} + +template +typename T::Client DynamicCapability::Client::as() { + static_assert(kind() == Kind::INTERFACE, + "DynamicCapability::Client::as() can only convert to interface types."); + schema.requireUsableAs(); + return typename T::Client(hook->addRef()); +} + +template +typename T::Client DynamicCapability::Client::releaseAs() { + static_assert(kind() == Kind::INTERFACE, + "DynamicCapability::Client::as() can only convert to interface types."); + schema.requireUsableAs(); + return typename T::Client(kj::mv(hook)); +} + +inline CallContext::CallContext( + CallContextHook& hook, StructSchema paramType, StructSchema resultType) + : hook(&hook), paramType(paramType), resultType(resultType) {} +inline DynamicStruct::Reader CallContext::getParams() { + return hook->getParams().getAs(paramType); +} +inline void CallContext::releaseParams() { + hook->releaseParams(); +} +inline DynamicStruct::Builder CallContext::getResults( + kj::Maybe sizeHint) { + return hook->getResults(sizeHint).getAs(resultType); +} +inline DynamicStruct::Builder CallContext::initResults( + kj::Maybe sizeHint) { + return hook->getResults(sizeHint).initAs(resultType); +} +inline void CallContext::setResults(DynamicStruct::Reader value) { + hook->getResults(value.totalSize()).setAs(value); +} +inline void CallContext::adoptResults(Orphan&& value) { + hook->getResults(MessageSize { 0, 0 }).adopt(kj::mv(value)); +} +inline Orphanage CallContext::getResultsOrphanage( + kj::Maybe sizeHint) { + return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); +} +template +inline kj::Promise CallContext::tailCall( + Request&& tailRequest) { + return hook->tailCall(kj::mv(tailRequest.hook)); +} +inline void CallContext::allowCancellation() { + hook->allowCancellation(); +} + +template <> +inline DynamicCapability::Client Capability::Client::castAs( + InterfaceSchema schema) { + return DynamicCapability::Client(schema, hook->addRef()); +} + +// ------------------------------------------------------------------- + +template +ReaderFor ConstSchema::as() const { + return DynamicValue::Reader(*this).as(); +} + +} // namespace capnp + +#endif // CAPNP_DYNAMIC_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/endian.h --- a/win32-mingw/include/capnp/endian.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/endian.h Tue May 23 09:16:54 2017 +0100 @@ -1,309 +1,309 @@ -// 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. - -#ifndef CAPNP_ENDIAN_H_ -#define CAPNP_ENDIAN_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "common.h" -#include -#include // memcpy - -namespace capnp { -namespace _ { // private - -// WireValue -// -// Wraps a primitive value as it appears on the wire. Namely, values are little-endian on the -// wire, because little-endian is the most common endianness in modern CPUs. -// -// Note: In general, code that depends cares about byte ordering is bad. See: -// http://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html -// Cap'n Proto is special because it is essentially doing compiler-like things, fussing over -// allocation and layout of memory, in order to squeeze out every last drop of performance. - -#if _MSC_VER -// Assume Windows is little-endian. -// -// TODO(msvc): This is ugly. Maybe refactor later checks to be based on CAPNP_BYTE_ORDER or -// CAPNP_SWAP_BYTES or something, and define that in turn based on _MSC_VER or the GCC -// intrinsics. - -#ifndef __ORDER_BIG_ENDIAN__ -#define __ORDER_BIG_ENDIAN__ 4321 -#endif -#ifndef __ORDER_LITTLE_ENDIAN__ -#define __ORDER_LITTLE_ENDIAN__ 1234 -#endif -#ifndef __BYTE_ORDER__ -#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ -#endif -#endif - -#if CAPNP_REVERSE_ENDIAN -#define CAPNP_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ -#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ -#else -#define CAPNP_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ -#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ -#endif - -#if defined(__BYTE_ORDER__) && \ - __BYTE_ORDER__ == CAPNP_WIRE_BYTE_ORDER && \ - !CAPNP_DISABLE_ENDIAN_DETECTION -// CPU is little-endian. We can just read/write the memory directly. - -template -class DirectWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { return value; } - KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } - -private: - T value; -}; - -template -using WireValue = DirectWireValue; -// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are -// linked together, we define each implementation with a different name and define an alias to the -// one we want to use. - -#elif defined(__BYTE_ORDER__) && \ - __BYTE_ORDER__ == CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER && \ - defined(__GNUC__) && !CAPNP_DISABLE_ENDIAN_DETECTION -// Big-endian, but GCC's __builtin_bswap() is available. - -// TODO(perf): Use dedicated instructions to read little-endian data on big-endian CPUs that have -// them. - -// TODO(perf): Verify that this code optimizes reasonably. In particular, ensure that the -// compiler optimizes away the memcpy()s and keeps everything in registers. - -template -class SwappingWireValue; - -template -class SwappingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { return value; } - KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } - -private: - T value; -}; - -template -class SwappingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing - // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). - uint16_t swapped = (value << 8) | (value >> 8); - T result; - memcpy(&result, &swapped, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint16_t raw; - memcpy(&raw, &newValue, sizeof(T)); - // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing - // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). - value = (raw << 8) | (raw >> 8); - } - -private: - uint16_t value; -}; - -template -class SwappingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint32_t swapped = __builtin_bswap32(value); - T result; - memcpy(&result, &swapped, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint32_t raw; - memcpy(&raw, &newValue, sizeof(T)); - value = __builtin_bswap32(raw); - } - -private: - uint32_t value; -}; - -template -class SwappingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint64_t swapped = __builtin_bswap64(value); - T result; - memcpy(&result, &swapped, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint64_t raw; - memcpy(&raw, &newValue, sizeof(T)); - value = __builtin_bswap64(raw); - } - -private: - uint64_t value; -}; - -template -using WireValue = SwappingWireValue; -// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are -// linked together, we define each implementation with a different name and define an alias to the -// one we want to use. - -#else -// Unknown endianness. Fall back to bit shifts. - -#if !CAPNP_DISABLE_ENDIAN_DETECTION -#if _MSC_VER -#pragma message("Couldn't detect endianness of your platform. Using unoptimized fallback implementation.") -#pragma message("Consider changing this code to detect your platform and send us a patch!") -#else -#warning "Couldn't detect endianness of your platform. Using unoptimized fallback implementation." -#warning "Consider changing this code to detect your platform and send us a patch!" -#endif -#endif // !CAPNP_DISABLE_ENDIAN_DETECTION - -template -class ShiftingWireValue; - -template -class ShiftingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { return value; } - KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } - -private: - T value; -}; - -template -class ShiftingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint16_t raw = (static_cast(bytes[0]) ) | - (static_cast(bytes[1]) << 8); - T result; - memcpy(&result, &raw, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint16_t raw; - memcpy(&raw, &newValue, sizeof(T)); - bytes[0] = raw; - bytes[1] = raw >> 8; - } - -private: - union { - byte bytes[2]; - uint16_t align; - }; -}; - -template -class ShiftingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint32_t raw = (static_cast(bytes[0]) ) | - (static_cast(bytes[1]) << 8) | - (static_cast(bytes[2]) << 16) | - (static_cast(bytes[3]) << 24); - T result; - memcpy(&result, &raw, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint32_t raw; - memcpy(&raw, &newValue, sizeof(T)); - bytes[0] = raw; - bytes[1] = raw >> 8; - bytes[2] = raw >> 16; - bytes[3] = raw >> 24; - } - -private: - union { - byte bytes[4]; - uint32_t align; - }; -}; - -template -class ShiftingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint64_t raw = (static_cast(bytes[0]) ) | - (static_cast(bytes[1]) << 8) | - (static_cast(bytes[2]) << 16) | - (static_cast(bytes[3]) << 24) | - (static_cast(bytes[4]) << 32) | - (static_cast(bytes[5]) << 40) | - (static_cast(bytes[6]) << 48) | - (static_cast(bytes[7]) << 56); - T result; - memcpy(&result, &raw, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint64_t raw; - memcpy(&raw, &newValue, sizeof(T)); - bytes[0] = raw; - bytes[1] = raw >> 8; - bytes[2] = raw >> 16; - bytes[3] = raw >> 24; - bytes[4] = raw >> 32; - bytes[5] = raw >> 40; - bytes[6] = raw >> 48; - bytes[7] = raw >> 56; - } - -private: - union { - byte bytes[8]; - uint64_t align; - }; -}; - -template -using WireValue = ShiftingWireValue; -// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are -// linked together, we define each implementation with a different name and define an alias to the -// one we want to use. - -#endif - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_ENDIAN_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. + +#ifndef CAPNP_ENDIAN_H_ +#define CAPNP_ENDIAN_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "common.h" +#include +#include // memcpy + +namespace capnp { +namespace _ { // private + +// WireValue +// +// Wraps a primitive value as it appears on the wire. Namely, values are little-endian on the +// wire, because little-endian is the most common endianness in modern CPUs. +// +// Note: In general, code that depends cares about byte ordering is bad. See: +// http://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +// Cap'n Proto is special because it is essentially doing compiler-like things, fussing over +// allocation and layout of memory, in order to squeeze out every last drop of performance. + +#if _MSC_VER +// Assume Windows is little-endian. +// +// TODO(msvc): This is ugly. Maybe refactor later checks to be based on CAPNP_BYTE_ORDER or +// CAPNP_SWAP_BYTES or something, and define that in turn based on _MSC_VER or the GCC +// intrinsics. + +#ifndef __ORDER_BIG_ENDIAN__ +#define __ORDER_BIG_ENDIAN__ 4321 +#endif +#ifndef __ORDER_LITTLE_ENDIAN__ +#define __ORDER_LITTLE_ENDIAN__ 1234 +#endif +#ifndef __BYTE_ORDER__ +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#endif +#endif + +#if CAPNP_REVERSE_ENDIAN +#define CAPNP_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ +#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ +#else +#define CAPNP_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ +#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ +#endif + +#if defined(__BYTE_ORDER__) && \ + __BYTE_ORDER__ == CAPNP_WIRE_BYTE_ORDER && \ + !CAPNP_DISABLE_ENDIAN_DETECTION +// CPU is little-endian. We can just read/write the memory directly. + +template +class DirectWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template +using WireValue = DirectWireValue; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#elif defined(__BYTE_ORDER__) && \ + __BYTE_ORDER__ == CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER && \ + defined(__GNUC__) && !CAPNP_DISABLE_ENDIAN_DETECTION +// Big-endian, but GCC's __builtin_bswap() is available. + +// TODO(perf): Use dedicated instructions to read little-endian data on big-endian CPUs that have +// them. + +// TODO(perf): Verify that this code optimizes reasonably. In particular, ensure that the +// compiler optimizes away the memcpy()s and keeps everything in registers. + +template +class SwappingWireValue; + +template +class SwappingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template +class SwappingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing + // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). + uint16_t swapped = (value << 8) | (value >> 8); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint16_t raw; + memcpy(&raw, &newValue, sizeof(T)); + // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing + // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). + value = (raw << 8) | (raw >> 8); + } + +private: + uint16_t value; +}; + +template +class SwappingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint32_t swapped = __builtin_bswap32(value); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint32_t raw; + memcpy(&raw, &newValue, sizeof(T)); + value = __builtin_bswap32(raw); + } + +private: + uint32_t value; +}; + +template +class SwappingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint64_t swapped = __builtin_bswap64(value); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint64_t raw; + memcpy(&raw, &newValue, sizeof(T)); + value = __builtin_bswap64(raw); + } + +private: + uint64_t value; +}; + +template +using WireValue = SwappingWireValue; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#else +// Unknown endianness. Fall back to bit shifts. + +#if !CAPNP_DISABLE_ENDIAN_DETECTION +#if _MSC_VER +#pragma message("Couldn't detect endianness of your platform. Using unoptimized fallback implementation.") +#pragma message("Consider changing this code to detect your platform and send us a patch!") +#else +#warning "Couldn't detect endianness of your platform. Using unoptimized fallback implementation." +#warning "Consider changing this code to detect your platform and send us a patch!" +#endif +#endif // !CAPNP_DISABLE_ENDIAN_DETECTION + +template +class ShiftingWireValue; + +template +class ShiftingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template +class ShiftingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint16_t raw = (static_cast(bytes[0]) ) | + (static_cast(bytes[1]) << 8); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint16_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + } + +private: + union { + byte bytes[2]; + uint16_t align; + }; +}; + +template +class ShiftingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint32_t raw = (static_cast(bytes[0]) ) | + (static_cast(bytes[1]) << 8) | + (static_cast(bytes[2]) << 16) | + (static_cast(bytes[3]) << 24); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint32_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + bytes[2] = raw >> 16; + bytes[3] = raw >> 24; + } + +private: + union { + byte bytes[4]; + uint32_t align; + }; +}; + +template +class ShiftingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint64_t raw = (static_cast(bytes[0]) ) | + (static_cast(bytes[1]) << 8) | + (static_cast(bytes[2]) << 16) | + (static_cast(bytes[3]) << 24) | + (static_cast(bytes[4]) << 32) | + (static_cast(bytes[5]) << 40) | + (static_cast(bytes[6]) << 48) | + (static_cast(bytes[7]) << 56); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint64_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + bytes[2] = raw >> 16; + bytes[3] = raw >> 24; + bytes[4] = raw >> 32; + bytes[5] = raw >> 40; + bytes[6] = raw >> 48; + bytes[7] = raw >> 56; + } + +private: + union { + byte bytes[8]; + uint64_t align; + }; +}; + +template +using WireValue = ShiftingWireValue; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#endif + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_ENDIAN_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/ez-rpc.h --- a/win32-mingw/include/capnp/ez-rpc.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/ez-rpc.h Tue May 23 09:16:54 2017 +0100 @@ -1,254 +1,254 @@ -// 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. - -#ifndef CAPNP_EZ_RPC_H_ -#define CAPNP_EZ_RPC_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "rpc.h" -#include "message.h" - -struct sockaddr; - -namespace kj { class AsyncIoProvider; class LowLevelAsyncIoProvider; } - -namespace capnp { - -class EzRpcContext; - -class EzRpcClient { - // Super-simple interface for setting up a Cap'n Proto RPC client. Example: - // - // # Cap'n Proto schema - // interface Adder { - // add @0 (left :Int32, right :Int32) -> (value :Int32); - // } - // - // // C++ client - // int main() { - // capnp::EzRpcClient client("localhost:3456"); - // Adder::Client adder = client.getMain(); - // auto request = adder.addRequest(); - // request.setLeft(12); - // request.setRight(34); - // auto response = request.send().wait(client.getWaitScope()); - // assert(response.getValue() == 46); - // return 0; - // } - // - // // C++ server - // class AdderImpl final: public Adder::Server { - // public: - // kj::Promise add(AddContext context) override { - // auto params = context.getParams(); - // context.getResults().setValue(params.getLeft() + params.getRight()); - // return kj::READY_NOW; - // } - // }; - // - // int main() { - // capnp::EzRpcServer server(kj::heap(), "*:3456"); - // kj::NEVER_DONE.wait(server.getWaitScope()); - // } - // - // This interface is easy, but it hides a lot of useful features available from the lower-level - // classes: - // - The server can only export a small set of public, singleton capabilities under well-known - // string names. This is fine for transient services where no state needs to be kept between - // connections, but hides the power of Cap'n Proto when it comes to long-lived resources. - // - EzRpcClient/EzRpcServer automatically set up a `kj::EventLoop` and make it current for the - // thread. Only one `kj::EventLoop` can exist per thread, so you cannot use these interfaces - // if you wish to set up your own event loop. (However, you can safely create multiple - // EzRpcClient / EzRpcServer objects in a single thread; they will make sure to make no more - // than one EventLoop.) - // - These classes only support simple two-party connections, not multilateral VatNetworks. - // - These classes only support communication over a raw, unencrypted socket. If you want to - // build on an abstract stream (perhaps one which supports encryption), you must use the - // lower-level interfaces. - // - // Some of these restrictions will probably be lifted in future versions, but some things will - // always require using the low-level interfaces directly. If you are interested in working - // at a lower level, start by looking at these interfaces: - // - `kj::setupAsyncIo()` in `kj/async-io.h`. - // - `RpcSystem` in `capnp/rpc.h`. - // - `TwoPartyVatNetwork` in `capnp/rpc-twoparty.h`. - -public: - explicit EzRpcClient(kj::StringPtr serverAddress, uint defaultPort = 0, - ReaderOptions readerOpts = ReaderOptions()); - // Construct a new EzRpcClient and connect to the given address. The connection is formed in - // the background -- if it fails, calls to capabilities returned by importCap() will fail with an - // appropriate exception. - // - // `defaultPort` is the IP port number to use if `serverAddress` does not include it explicitly. - // If unspecified, the port is required in `serverAddress`. - // - // The address is parsed by `kj::Network` in `kj/async-io.h`. See that interface for more info - // on the address format, but basically it's what you'd expect. - // - // `readerOpts` is the ReaderOptions structure used to read each incoming message on the - // connection. Setting this may be necessary if you need to receive very large individual - // messages or messages. However, it is recommended that you instead think about how to change - // your protocol to send large data blobs in multiple small chunks -- this is much better for - // both security and performance. See `ReaderOptions` in `message.h` for more details. - - EzRpcClient(const struct sockaddr* serverAddress, uint addrSize, - ReaderOptions readerOpts = ReaderOptions()); - // Like the above constructor, but connects to an already-resolved socket address. Any address - // format supported by `kj::Network` in `kj/async-io.h` is accepted. - - explicit EzRpcClient(int socketFd, ReaderOptions readerOpts = ReaderOptions()); - // Create a client on top of an already-connected socket. - // `readerOpts` acts as in the first constructor. - - ~EzRpcClient() noexcept(false); - - template - typename Type::Client getMain(); - Capability::Client getMain(); - // Get the server's main (aka "bootstrap") interface. - - template - typename Type::Client importCap(kj::StringPtr name) - KJ_DEPRECATED("Change your server to export a main interface, then use getMain() instead."); - Capability::Client importCap(kj::StringPtr name) - KJ_DEPRECATED("Change your server to export a main interface, then use getMain() instead."); - // ** DEPRECATED ** - // - // Ask the sever for the capability with the given name. You may specify a type to automatically - // down-cast to that type. It is up to you to specify the correct expected type. - // - // Named interfaces are deprecated. The new preferred usage pattern is for the server to export - // a "main" interface which itself has methods for getting any other interfaces. - - kj::WaitScope& getWaitScope(); - // Get the `WaitScope` for the client's `EventLoop`, which allows you to synchronously wait on - // promises. - - kj::AsyncIoProvider& getIoProvider(); - // Get the underlying AsyncIoProvider set up by the RPC system. This is useful if you want - // to do some non-RPC I/O in asynchronous fashion. - - kj::LowLevelAsyncIoProvider& getLowLevelIoProvider(); - // Get the underlying LowLevelAsyncIoProvider set up by the RPC system. This is useful if you - // want to do some non-RPC I/O in asynchronous fashion. - -private: - struct Impl; - kj::Own impl; -}; - -class EzRpcServer { - // The server counterpart to `EzRpcClient`. See `EzRpcClient` for an example. - -public: - explicit EzRpcServer(Capability::Client mainInterface, kj::StringPtr bindAddress, - uint defaultPort = 0, ReaderOptions readerOpts = ReaderOptions()); - // Construct a new `EzRpcServer` that binds to the given address. An address of "*" means to - // bind to all local addresses. - // - // `defaultPort` is the IP port number to use if `serverAddress` does not include it explicitly. - // If unspecified, a port is chosen automatically, and you must call getPort() to find out what - // it is. - // - // The address is parsed by `kj::Network` in `kj/async-io.h`. See that interface for more info - // on the address format, but basically it's what you'd expect. - // - // The server might not begin listening immediately, especially if `bindAddress` needs to be - // resolved. If you need to wait until the server is definitely up, wait on the promise returned - // by `getPort()`. - // - // `readerOpts` is the ReaderOptions structure used to read each incoming message on the - // connection. Setting this may be necessary if you need to receive very large individual - // messages or messages. However, it is recommended that you instead think about how to change - // your protocol to send large data blobs in multiple small chunks -- this is much better for - // both security and performance. See `ReaderOptions` in `message.h` for more details. - - EzRpcServer(Capability::Client mainInterface, struct sockaddr* bindAddress, uint addrSize, - ReaderOptions readerOpts = ReaderOptions()); - // Like the above constructor, but binds to an already-resolved socket address. Any address - // format supported by `kj::Network` in `kj/async-io.h` is accepted. - - EzRpcServer(Capability::Client mainInterface, int socketFd, uint port, - ReaderOptions readerOpts = ReaderOptions()); - // Create a server on top of an already-listening socket (i.e. one on which accept() may be - // called). `port` is returned by `getPort()` -- it serves no other purpose. - // `readerOpts` acts as in the other two above constructors. - - explicit EzRpcServer(kj::StringPtr bindAddress, uint defaultPort = 0, - ReaderOptions readerOpts = ReaderOptions()) - KJ_DEPRECATED("Please specify a main interface for your server."); - EzRpcServer(struct sockaddr* bindAddress, uint addrSize, - ReaderOptions readerOpts = ReaderOptions()) - KJ_DEPRECATED("Please specify a main interface for your server."); - EzRpcServer(int socketFd, uint port, ReaderOptions readerOpts = ReaderOptions()) - KJ_DEPRECATED("Please specify a main interface for your server."); - - ~EzRpcServer() noexcept(false); - - void exportCap(kj::StringPtr name, Capability::Client cap); - // Export a capability publicly under the given name, so that clients can import it. - // - // Keep in mind that you can implicitly convert `kj::Own&&` to - // `Capability::Client`, so it's typical to pass something like - // `kj::heap()` as the second parameter. - - kj::Promise getPort(); - // Get the IP port number on which this server is listening. This promise won't resolve until - // the server is actually listening. If the address was not an IP address (e.g. it was a Unix - // domain socket) then getPort() resolves to zero. - - kj::WaitScope& getWaitScope(); - // Get the `WaitScope` for the client's `EventLoop`, which allows you to synchronously wait on - // promises. - - kj::AsyncIoProvider& getIoProvider(); - // Get the underlying AsyncIoProvider set up by the RPC system. This is useful if you want - // to do some non-RPC I/O in asynchronous fashion. - - kj::LowLevelAsyncIoProvider& getLowLevelIoProvider(); - // Get the underlying LowLevelAsyncIoProvider set up by the RPC system. This is useful if you - // want to do some non-RPC I/O in asynchronous fashion. - -private: - struct Impl; - kj::Own impl; -}; - -// ======================================================================================= -// inline implementation details - -template -inline typename Type::Client EzRpcClient::getMain() { - return getMain().castAs(); -} - -template -inline typename Type::Client EzRpcClient::importCap(kj::StringPtr name) { - return importCap(name).castAs(); -} - -} // namespace capnp - -#endif // CAPNP_EZ_RPC_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. + +#ifndef CAPNP_EZ_RPC_H_ +#define CAPNP_EZ_RPC_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "rpc.h" +#include "message.h" + +struct sockaddr; + +namespace kj { class AsyncIoProvider; class LowLevelAsyncIoProvider; } + +namespace capnp { + +class EzRpcContext; + +class EzRpcClient { + // Super-simple interface for setting up a Cap'n Proto RPC client. Example: + // + // # Cap'n Proto schema + // interface Adder { + // add @0 (left :Int32, right :Int32) -> (value :Int32); + // } + // + // // C++ client + // int main() { + // capnp::EzRpcClient client("localhost:3456"); + // Adder::Client adder = client.getMain(); + // auto request = adder.addRequest(); + // request.setLeft(12); + // request.setRight(34); + // auto response = request.send().wait(client.getWaitScope()); + // assert(response.getValue() == 46); + // return 0; + // } + // + // // C++ server + // class AdderImpl final: public Adder::Server { + // public: + // kj::Promise add(AddContext context) override { + // auto params = context.getParams(); + // context.getResults().setValue(params.getLeft() + params.getRight()); + // return kj::READY_NOW; + // } + // }; + // + // int main() { + // capnp::EzRpcServer server(kj::heap(), "*:3456"); + // kj::NEVER_DONE.wait(server.getWaitScope()); + // } + // + // This interface is easy, but it hides a lot of useful features available from the lower-level + // classes: + // - The server can only export a small set of public, singleton capabilities under well-known + // string names. This is fine for transient services where no state needs to be kept between + // connections, but hides the power of Cap'n Proto when it comes to long-lived resources. + // - EzRpcClient/EzRpcServer automatically set up a `kj::EventLoop` and make it current for the + // thread. Only one `kj::EventLoop` can exist per thread, so you cannot use these interfaces + // if you wish to set up your own event loop. (However, you can safely create multiple + // EzRpcClient / EzRpcServer objects in a single thread; they will make sure to make no more + // than one EventLoop.) + // - These classes only support simple two-party connections, not multilateral VatNetworks. + // - These classes only support communication over a raw, unencrypted socket. If you want to + // build on an abstract stream (perhaps one which supports encryption), you must use the + // lower-level interfaces. + // + // Some of these restrictions will probably be lifted in future versions, but some things will + // always require using the low-level interfaces directly. If you are interested in working + // at a lower level, start by looking at these interfaces: + // - `kj::setupAsyncIo()` in `kj/async-io.h`. + // - `RpcSystem` in `capnp/rpc.h`. + // - `TwoPartyVatNetwork` in `capnp/rpc-twoparty.h`. + +public: + explicit EzRpcClient(kj::StringPtr serverAddress, uint defaultPort = 0, + ReaderOptions readerOpts = ReaderOptions()); + // Construct a new EzRpcClient and connect to the given address. The connection is formed in + // the background -- if it fails, calls to capabilities returned by importCap() will fail with an + // appropriate exception. + // + // `defaultPort` is the IP port number to use if `serverAddress` does not include it explicitly. + // If unspecified, the port is required in `serverAddress`. + // + // The address is parsed by `kj::Network` in `kj/async-io.h`. See that interface for more info + // on the address format, but basically it's what you'd expect. + // + // `readerOpts` is the ReaderOptions structure used to read each incoming message on the + // connection. Setting this may be necessary if you need to receive very large individual + // messages or messages. However, it is recommended that you instead think about how to change + // your protocol to send large data blobs in multiple small chunks -- this is much better for + // both security and performance. See `ReaderOptions` in `message.h` for more details. + + EzRpcClient(const struct sockaddr* serverAddress, uint addrSize, + ReaderOptions readerOpts = ReaderOptions()); + // Like the above constructor, but connects to an already-resolved socket address. Any address + // format supported by `kj::Network` in `kj/async-io.h` is accepted. + + explicit EzRpcClient(int socketFd, ReaderOptions readerOpts = ReaderOptions()); + // Create a client on top of an already-connected socket. + // `readerOpts` acts as in the first constructor. + + ~EzRpcClient() noexcept(false); + + template + typename Type::Client getMain(); + Capability::Client getMain(); + // Get the server's main (aka "bootstrap") interface. + + template + typename Type::Client importCap(kj::StringPtr name) + KJ_DEPRECATED("Change your server to export a main interface, then use getMain() instead."); + Capability::Client importCap(kj::StringPtr name) + KJ_DEPRECATED("Change your server to export a main interface, then use getMain() instead."); + // ** DEPRECATED ** + // + // Ask the sever for the capability with the given name. You may specify a type to automatically + // down-cast to that type. It is up to you to specify the correct expected type. + // + // Named interfaces are deprecated. The new preferred usage pattern is for the server to export + // a "main" interface which itself has methods for getting any other interfaces. + + kj::WaitScope& getWaitScope(); + // Get the `WaitScope` for the client's `EventLoop`, which allows you to synchronously wait on + // promises. + + kj::AsyncIoProvider& getIoProvider(); + // Get the underlying AsyncIoProvider set up by the RPC system. This is useful if you want + // to do some non-RPC I/O in asynchronous fashion. + + kj::LowLevelAsyncIoProvider& getLowLevelIoProvider(); + // Get the underlying LowLevelAsyncIoProvider set up by the RPC system. This is useful if you + // want to do some non-RPC I/O in asynchronous fashion. + +private: + struct Impl; + kj::Own impl; +}; + +class EzRpcServer { + // The server counterpart to `EzRpcClient`. See `EzRpcClient` for an example. + +public: + explicit EzRpcServer(Capability::Client mainInterface, kj::StringPtr bindAddress, + uint defaultPort = 0, ReaderOptions readerOpts = ReaderOptions()); + // Construct a new `EzRpcServer` that binds to the given address. An address of "*" means to + // bind to all local addresses. + // + // `defaultPort` is the IP port number to use if `serverAddress` does not include it explicitly. + // If unspecified, a port is chosen automatically, and you must call getPort() to find out what + // it is. + // + // The address is parsed by `kj::Network` in `kj/async-io.h`. See that interface for more info + // on the address format, but basically it's what you'd expect. + // + // The server might not begin listening immediately, especially if `bindAddress` needs to be + // resolved. If you need to wait until the server is definitely up, wait on the promise returned + // by `getPort()`. + // + // `readerOpts` is the ReaderOptions structure used to read each incoming message on the + // connection. Setting this may be necessary if you need to receive very large individual + // messages or messages. However, it is recommended that you instead think about how to change + // your protocol to send large data blobs in multiple small chunks -- this is much better for + // both security and performance. See `ReaderOptions` in `message.h` for more details. + + EzRpcServer(Capability::Client mainInterface, struct sockaddr* bindAddress, uint addrSize, + ReaderOptions readerOpts = ReaderOptions()); + // Like the above constructor, but binds to an already-resolved socket address. Any address + // format supported by `kj::Network` in `kj/async-io.h` is accepted. + + EzRpcServer(Capability::Client mainInterface, int socketFd, uint port, + ReaderOptions readerOpts = ReaderOptions()); + // Create a server on top of an already-listening socket (i.e. one on which accept() may be + // called). `port` is returned by `getPort()` -- it serves no other purpose. + // `readerOpts` acts as in the other two above constructors. + + explicit EzRpcServer(kj::StringPtr bindAddress, uint defaultPort = 0, + ReaderOptions readerOpts = ReaderOptions()) + KJ_DEPRECATED("Please specify a main interface for your server."); + EzRpcServer(struct sockaddr* bindAddress, uint addrSize, + ReaderOptions readerOpts = ReaderOptions()) + KJ_DEPRECATED("Please specify a main interface for your server."); + EzRpcServer(int socketFd, uint port, ReaderOptions readerOpts = ReaderOptions()) + KJ_DEPRECATED("Please specify a main interface for your server."); + + ~EzRpcServer() noexcept(false); + + void exportCap(kj::StringPtr name, Capability::Client cap); + // Export a capability publicly under the given name, so that clients can import it. + // + // Keep in mind that you can implicitly convert `kj::Own&&` to + // `Capability::Client`, so it's typical to pass something like + // `kj::heap()` as the second parameter. + + kj::Promise getPort(); + // Get the IP port number on which this server is listening. This promise won't resolve until + // the server is actually listening. If the address was not an IP address (e.g. it was a Unix + // domain socket) then getPort() resolves to zero. + + kj::WaitScope& getWaitScope(); + // Get the `WaitScope` for the client's `EventLoop`, which allows you to synchronously wait on + // promises. + + kj::AsyncIoProvider& getIoProvider(); + // Get the underlying AsyncIoProvider set up by the RPC system. This is useful if you want + // to do some non-RPC I/O in asynchronous fashion. + + kj::LowLevelAsyncIoProvider& getLowLevelIoProvider(); + // Get the underlying LowLevelAsyncIoProvider set up by the RPC system. This is useful if you + // want to do some non-RPC I/O in asynchronous fashion. + +private: + struct Impl; + kj::Own impl; +}; + +// ======================================================================================= +// inline implementation details + +template +inline typename Type::Client EzRpcClient::getMain() { + return getMain().castAs(); +} + +template +inline typename Type::Client EzRpcClient::importCap(kj::StringPtr name) { + return importCap(name).castAs(); +} + +} // namespace capnp + +#endif // CAPNP_EZ_RPC_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/generated-header-support.h --- a/win32-mingw/include/capnp/generated-header-support.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/generated-header-support.h Tue May 23 09:16:54 2017 +0100 @@ -1,585 +1,407 @@ -// 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 is included form all generated headers. - -#ifndef CAPNP_GENERATED_HEADER_SUPPORT_H_ -#define CAPNP_GENERATED_HEADER_SUPPORT_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" -#include "list.h" -#include "orphan.h" -#include "pointer-helpers.h" -#include "any.h" -#include -#include - -namespace capnp { - -class MessageBuilder; // So that it can be declared a friend. - -template -struct ToDynamic_; // Defined in dynamic.h, needs to be declared as everyone's friend. - -struct DynamicStruct; // So that it can be declared a friend. - -struct Capability; // To declare brandBindingFor() - -namespace _ { // private - -#if !CAPNP_LITE - -struct RawSchema; - -struct RawBrandedSchema { - // Represents a combination of a schema and bindings for its generic parameters. - // - // Note that while we generate one `RawSchema` per type, we generate a `RawBrandedSchema` for - // every _instance_ of a generic type -- or, at least, every instance that is actually used. For - // generated-code types, we use template magic to initialize these. - - const RawSchema* generic; - // Generic type which we're branding. - - struct Binding { - uint8_t which; // Numeric value of one of schema::Type::Which. - - bool isImplicitParameter; - // For AnyPointer, true if it's an implicit method parameter. - - uint16_t listDepth; // Number of times to wrap the base type in List(). - - uint16_t paramIndex; - // For AnyPointer. If it's a type parameter (scopeId is non-zero) or it's an implicit parameter - // (isImplicitParameter is true), then this is the parameter index. Otherwise this is a numeric - // value of one of schema::Type::AnyPointer::Unconstrained::Which. - - union { - const RawBrandedSchema* schema; // for struct, enum, interface - uint64_t scopeId; // for AnyPointer, if it's a type parameter - }; - - Binding() = default; - inline constexpr Binding(uint8_t which, uint16_t listDepth, const RawBrandedSchema* schema) - : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(0), - schema(schema) {} - inline constexpr Binding(uint8_t which, uint16_t listDepth, - uint64_t scopeId, uint16_t paramIndex) - : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(paramIndex), - scopeId(scopeId) {} - inline constexpr Binding(uint8_t which, uint16_t listDepth, uint16_t implicitParamIndex) - : which(which), isImplicitParameter(true), listDepth(listDepth), - paramIndex(implicitParamIndex), scopeId(0) {} - }; - - struct Scope { - uint64_t typeId; - // Type ID whose parameters are being bound. - - const Binding* bindings; - uint bindingCount; - // Bindings for those parameters. - - bool isUnbound; - // This scope is unbound, in the sense of SchemaLoader::getUnbound(). - }; - - const Scope* scopes; - // Array of enclosing scopes for which generic variables have been bound, sorted by type ID. - - struct Dependency { - uint location; - const RawBrandedSchema* schema; - }; - - const Dependency* dependencies; - // Map of branded schemas for dependencies of this type, given our brand. Only dependencies that - // are branded are included in this map; if a dependency is missing, use its `defaultBrand`. - - uint32_t scopeCount; - uint32_t dependencyCount; - - enum class DepKind { - // Component of a Dependency::location. Specifies what sort of dependency this is. - - INVALID, - // Mostly defined to ensure that zero is not a valid location. - - FIELD, - // Binding needed for a field's type. The index is the field index (NOT ordinal!). - - METHOD_PARAMS, - // Bindings needed for a method's params type. The index is the method number. - - METHOD_RESULTS, - // Bindings needed for a method's results type. The index is the method ordinal. - - SUPERCLASS, - // Bindings needed for a superclass type. The index is the superclass's index in the - // "extends" list. - - CONST_TYPE - // Bindings needed for the type of a constant. The index is zero. - }; - - static inline uint makeDepLocation(DepKind kind, uint index) { - // Make a number representing the location of a particular dependency within its parent - // schema. - - return (static_cast(kind) << 24) | index; - } - - class Initializer { - public: - virtual void init(const RawBrandedSchema* generic) const = 0; - }; - - const Initializer* lazyInitializer; - // Lazy initializer, invoked by ensureInitialized(). - - inline void ensureInitialized() const { - // Lazy initialization support. Invoke to ensure that initialization has taken place. This - // is required in particular when traversing the dependency list. RawSchemas for compiled-in - // types are always initialized; only dynamically-loaded schemas may be lazy. - - const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); - if (i != nullptr) i->init(this); - } - - inline bool isUnbound() const; - // Checks if this schema is the result of calling SchemaLoader::getUnbound(), in which case - // binding lookups need to be handled specially. -}; - -struct RawSchema { - // The generated code defines a constant RawSchema for every compiled declaration. - // - // This is an internal structure which could change in the future. - - uint64_t id; - - const word* encodedNode; - // Encoded SchemaNode, readable via readMessageUnchecked(encodedNode). - - uint32_t encodedSize; - // Size of encodedNode, in words. - - const RawSchema* const* dependencies; - // Pointers to other types on which this one depends, sorted by ID. The schemas in this table - // may be uninitialized -- you must call ensureInitialized() on the one you wish to use before - // using it. - // - // TODO(someday): Make this a hashtable. - - const uint16_t* membersByName; - // Indexes of members sorted by name. Used to implement name lookup. - // TODO(someday): Make this a hashtable. - - uint32_t dependencyCount; - uint32_t memberCount; - // Sizes of above tables. - - const uint16_t* membersByDiscriminant; - // List of all member indexes ordered by discriminant value. Those which don't have a - // discriminant value are listed at the end, in order by ordinal. - - const RawSchema* canCastTo; - // Points to the RawSchema of a compiled-in type to which it is safe to cast any DynamicValue - // with this schema. This is null for all compiled-in types; it is only set by SchemaLoader on - // dynamically-loaded types. - - class Initializer { - public: - virtual void init(const RawSchema* schema) const = 0; - }; - - const Initializer* lazyInitializer; - // Lazy initializer, invoked by ensureInitialized(). - - inline void ensureInitialized() const { - // Lazy initialization support. Invoke to ensure that initialization has taken place. This - // is required in particular when traversing the dependency list. RawSchemas for compiled-in - // types are always initialized; only dynamically-loaded schemas may be lazy. - - const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); - if (i != nullptr) i->init(this); - } - - RawBrandedSchema defaultBrand; - // Specifies the brand to use for this schema if no generic parameters have been bound to - // anything. Generally, in the default brand, all generic parameters are treated as if they were - // bound to `AnyPointer`. -}; - -inline bool RawBrandedSchema::isUnbound() const { - // The unbound schema is the only one that has no scopes but is not the default schema. - return scopeCount == 0 && this != &generic->defaultBrand; -} - -template -inline const RawSchema& rawSchema() { - return *CapnpPrivate::schema; -} -template ::typeId> -inline const RawSchema& rawSchema() { - return *schemas::EnumInfo::schema; -} - -template -inline const RawBrandedSchema& rawBrandedSchema() { - return *CapnpPrivate::brand; -} -template ::typeId> -inline const RawBrandedSchema& rawBrandedSchema() { - return schemas::EnumInfo::schema->defaultBrand; -} - -template -struct ChooseBrand; -// If all of `Params` are `AnyPointer`, return the type's default brand. Otherwise, return a -// specific brand instance. TypeTag is the _capnpPrivate struct for the type in question. - -template -struct ChooseBrand { - // All params were AnyPointer. No specific brand needed. - static constexpr _::RawBrandedSchema const* brand = &TypeTag::schema->defaultBrand; -}; - -template -struct ChooseBrand: public ChooseBrand {}; -// The first parameter is AnyPointer, so recurse to check the rest. - -template -struct ChooseBrand { - // At least one parameter is not AnyPointer, so use the specificBrand constant. - static constexpr _::RawBrandedSchema const* brand = &TypeTag::specificBrand; -}; - -template ()> -struct BrandBindingFor_; - -#define HANDLE_TYPE(Type, which) \ - template <> \ - struct BrandBindingFor_ { \ - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { \ - return { which, listDepth, nullptr }; \ - } \ - } -HANDLE_TYPE(Void, 0); -HANDLE_TYPE(bool, 1); -HANDLE_TYPE(int8_t, 2); -HANDLE_TYPE(int16_t, 3); -HANDLE_TYPE(int32_t, 4); -HANDLE_TYPE(int64_t, 5); -HANDLE_TYPE(uint8_t, 6); -HANDLE_TYPE(uint16_t, 7); -HANDLE_TYPE(uint32_t, 8); -HANDLE_TYPE(uint64_t, 9); -HANDLE_TYPE(float, 10); -HANDLE_TYPE(double, 11); -#undef HANDLE_TYPE - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 12, listDepth, nullptr }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 13, listDepth, nullptr }; - } -}; - -template -struct BrandBindingFor_, Kind::LIST> { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return BrandBindingFor_::get(listDepth + 1); - } -}; - -template -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 15, listDepth, nullptr }; - } -}; - -template -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 16, listDepth, T::_capnpPrivate::brand }; - } -}; - -template -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 17, listDepth, T::_capnpPrivate::brand }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 18, listDepth, 0, 0 }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 18, listDepth, 0, 1 }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 18, listDepth, 0, 2 }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 18, listDepth, 0, 3 }; - } -}; - -template -constexpr RawBrandedSchema::Binding brandBindingFor() { - return BrandBindingFor_::get(0); -} - -kj::StringTree structString(StructReader reader, const RawBrandedSchema& schema); -kj::String enumString(uint16_t value, const RawBrandedSchema& schema); -// Declared here so that we can declare inline stringify methods on generated types. -// Defined in stringify.c++, which depends on dynamic.c++, which is allowed not to be linked in. - -template -inline kj::StringTree structString(StructReader reader) { - return structString(reader, rawBrandedSchema()); -} -template -inline kj::String enumString(T value) { - return enumString(static_cast(value), rawBrandedSchema()); -} - -#endif // !CAPNP_LITE - -// TODO(cleanup): Unify ConstStruct and ConstList. -template -class ConstStruct { -public: - ConstStruct() = delete; - KJ_DISALLOW_COPY(ConstStruct); - inline explicit constexpr ConstStruct(const word* ptr): ptr(ptr) {} - - inline typename T::Reader get() const { - return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs(); - } - - inline operator typename T::Reader() const { return get(); } - inline typename T::Reader operator*() const { return get(); } - inline TemporaryPointer operator->() const { return get(); } - -private: - const word* ptr; -}; - -template -class ConstList { -public: - ConstList() = delete; - KJ_DISALLOW_COPY(ConstList); - inline explicit constexpr ConstList(const word* ptr): ptr(ptr) {} - - inline typename List::Reader get() const { - return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs>(); - } - - inline operator typename List::Reader() const { return get(); } - inline typename List::Reader operator*() const { return get(); } - inline TemporaryPointer::Reader> operator->() const { return get(); } - -private: - const word* ptr; -}; - -template -class ConstText { -public: - ConstText() = delete; - KJ_DISALLOW_COPY(ConstText); - inline explicit constexpr ConstText(const word* ptr): ptr(ptr) {} - - inline Text::Reader get() const { - return Text::Reader(reinterpret_cast(ptr), size); - } - - inline operator Text::Reader() const { return get(); } - inline Text::Reader operator*() const { return get(); } - inline TemporaryPointer operator->() const { return get(); } - - inline kj::StringPtr toString() const { - return get(); - } - -private: - const word* ptr; -}; - -template -inline kj::StringPtr KJ_STRINGIFY(const ConstText& s) { - return s.get(); -} - -template -class ConstData { -public: - ConstData() = delete; - KJ_DISALLOW_COPY(ConstData); - inline explicit constexpr ConstData(const word* ptr): ptr(ptr) {} - - inline Data::Reader get() const { - return Data::Reader(reinterpret_cast(ptr), size); - } - - inline operator Data::Reader() const { return get(); } - inline Data::Reader operator*() const { return get(); } - inline TemporaryPointer operator->() const { return get(); } - -private: - const word* ptr; -}; - -template -inline auto KJ_STRINGIFY(const ConstData& s) -> decltype(kj::toCharSequence(s.get())) { - return kj::toCharSequence(s.get()); -} - -} // namespace _ (private) - -template -inline constexpr uint64_t typeId() { return CapnpPrivate::typeId; } -template ::typeId> -inline constexpr uint64_t typeId() { return id; } -// typeId() returns the type ID as defined in the schema. Works with structs, enums, and -// interfaces. - -template -inline constexpr uint sizeInWords() { - // Return the size, in words, of a Struct type, if allocated free-standing (not in a list). - // May be useful for pre-computing space needed in order to precisely allocate messages. - - return (WordCount32(_::structSize().data) + - _::structSize().pointers * WORDS_PER_POINTER) / WORDS; -} - -} // namespace capnp - -#if _MSC_VER -// MSVC doesn't understand floating-point constexpr yet. -// -// TODO(msvc): Remove this hack when MSVC is fixed. -#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) -#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) = value -#else -#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) = value -#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) -#endif - -#if CAPNP_LITE - -#define CAPNP_DECLARE_SCHEMA(id) \ - extern ::capnp::word const* const bp_##id - -#define CAPNP_DECLARE_ENUM(type, id) \ - inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ - return ::kj::str(static_cast(value)); \ - } \ - template <> struct EnumInfo { \ - struct IsEnum; \ - static constexpr uint64_t typeId = 0x##id; \ - static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ - } - -#if _MSC_VER -// TODO(msvc): MSVC dosen't expect constexprs to have definitions. -#define CAPNP_DEFINE_ENUM(type, id) -#else -#define CAPNP_DEFINE_ENUM(type, id) \ - constexpr uint64_t EnumInfo::typeId -#endif - -#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ - struct IsStruct; \ - static constexpr uint64_t typeId = 0x##id; \ - static constexpr uint16_t dataWordSize = dataWordSize_; \ - static constexpr uint16_t pointerCount = pointerCount_; \ - static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } - -#else // CAPNP_LITE - -#define CAPNP_DECLARE_SCHEMA(id) \ - extern ::capnp::word const* const bp_##id; \ - extern const ::capnp::_::RawSchema s_##id - -#define CAPNP_DECLARE_ENUM(type, id) \ - inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ - return ::capnp::_::enumString(value); \ - } \ - template <> struct EnumInfo { \ - struct IsEnum; \ - static constexpr uint64_t typeId = 0x##id; \ - static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ - static constexpr ::capnp::_::RawSchema const* schema = &s_##id; \ - } -#define CAPNP_DEFINE_ENUM(type, id) \ - constexpr uint64_t EnumInfo::typeId; \ - constexpr ::capnp::_::RawSchema const* EnumInfo::schema - -#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ - struct IsStruct; \ - static constexpr uint64_t typeId = 0x##id; \ - static constexpr ::capnp::Kind kind = ::capnp::Kind::STRUCT; \ - static constexpr uint16_t dataWordSize = dataWordSize_; \ - static constexpr uint16_t pointerCount = pointerCount_; \ - static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ - static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; - -#define CAPNP_DECLARE_INTERFACE_HEADER(id) \ - struct IsInterface; \ - static constexpr uint64_t typeId = 0x##id; \ - static constexpr ::capnp::Kind kind = ::capnp::Kind::INTERFACE; \ - static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ - static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; - -#endif // CAPNP_LITE, else - -#endif // CAPNP_GENERATED_HEADER_SUPPORT_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 is included from all generated headers. + +#ifndef CAPNP_GENERATED_HEADER_SUPPORT_H_ +#define CAPNP_GENERATED_HEADER_SUPPORT_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "raw-schema.h" +#include "layout.h" +#include "list.h" +#include "orphan.h" +#include "pointer-helpers.h" +#include "any.h" +#include +#include + +namespace capnp { + +class MessageBuilder; // So that it can be declared a friend. + +template +struct ToDynamic_; // Defined in dynamic.h, needs to be declared as everyone's friend. + +struct DynamicStruct; // So that it can be declared a friend. + +struct Capability; // To declare brandBindingFor() + +namespace _ { // private + +#if !CAPNP_LITE + +template +inline const RawSchema& rawSchema() { + return *CapnpPrivate::schema; +} +template ::typeId> +inline const RawSchema& rawSchema() { + return *schemas::EnumInfo::schema; +} + +template +inline const RawBrandedSchema& rawBrandedSchema() { + return *CapnpPrivate::brand(); +} +template ::typeId> +inline const RawBrandedSchema& rawBrandedSchema() { + return schemas::EnumInfo::schema->defaultBrand; +} + +template +struct ChooseBrand; +// If all of `Params` are `AnyPointer`, return the type's default brand. Otherwise, return a +// specific brand instance. TypeTag is the _capnpPrivate struct for the type in question. + +template +struct ChooseBrand { + // All params were AnyPointer. No specific brand needed. + static constexpr _::RawBrandedSchema const* brand() { return &TypeTag::schema->defaultBrand; } +}; + +template +struct ChooseBrand: public ChooseBrand {}; +// The first parameter is AnyPointer, so recurse to check the rest. + +template +struct ChooseBrand { + // At least one parameter is not AnyPointer, so use the specificBrand constant. + static constexpr _::RawBrandedSchema const* brand() { return &TypeTag::specificBrand; } +}; + +template ()> +struct BrandBindingFor_; + +#define HANDLE_TYPE(Type, which) \ + template <> \ + struct BrandBindingFor_ { \ + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { \ + return { which, listDepth, nullptr }; \ + } \ + } +HANDLE_TYPE(Void, 0); +HANDLE_TYPE(bool, 1); +HANDLE_TYPE(int8_t, 2); +HANDLE_TYPE(int16_t, 3); +HANDLE_TYPE(int32_t, 4); +HANDLE_TYPE(int64_t, 5); +HANDLE_TYPE(uint8_t, 6); +HANDLE_TYPE(uint16_t, 7); +HANDLE_TYPE(uint32_t, 8); +HANDLE_TYPE(uint64_t, 9); +HANDLE_TYPE(float, 10); +HANDLE_TYPE(double, 11); +#undef HANDLE_TYPE + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 12, listDepth, nullptr }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 13, listDepth, nullptr }; + } +}; + +template +struct BrandBindingFor_, Kind::LIST> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return BrandBindingFor_::get(listDepth + 1); + } +}; + +template +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 15, listDepth, nullptr }; + } +}; + +template +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 16, listDepth, T::_capnpPrivate::brand() }; + } +}; + +template +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 17, listDepth, T::_capnpPrivate::brand() }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 0 }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 1 }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 2 }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 3 }; + } +}; + +template +constexpr RawBrandedSchema::Binding brandBindingFor() { + return BrandBindingFor_::get(0); +} + +kj::StringTree structString(StructReader reader, const RawBrandedSchema& schema); +kj::String enumString(uint16_t value, const RawBrandedSchema& schema); +// Declared here so that we can declare inline stringify methods on generated types. +// Defined in stringify.c++, which depends on dynamic.c++, which is allowed not to be linked in. + +template +inline kj::StringTree structString(StructReader reader) { + return structString(reader, rawBrandedSchema()); +} +template +inline kj::String enumString(T value) { + return enumString(static_cast(value), rawBrandedSchema()); +} + +#endif // !CAPNP_LITE + +// TODO(cleanup): Unify ConstStruct and ConstList. +template +class ConstStruct { +public: + ConstStruct() = delete; + KJ_DISALLOW_COPY(ConstStruct); + inline explicit constexpr ConstStruct(const word* ptr): ptr(ptr) {} + + inline typename T::Reader get() const { + return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs(); + } + + inline operator typename T::Reader() const { return get(); } + inline typename T::Reader operator*() const { return get(); } + inline TemporaryPointer operator->() const { return get(); } + +private: + const word* ptr; +}; + +template +class ConstList { +public: + ConstList() = delete; + KJ_DISALLOW_COPY(ConstList); + inline explicit constexpr ConstList(const word* ptr): ptr(ptr) {} + + inline typename List::Reader get() const { + return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs>(); + } + + inline operator typename List::Reader() const { return get(); } + inline typename List::Reader operator*() const { return get(); } + inline TemporaryPointer::Reader> operator->() const { return get(); } + +private: + const word* ptr; +}; + +template +class ConstText { +public: + ConstText() = delete; + KJ_DISALLOW_COPY(ConstText); + inline explicit constexpr ConstText(const word* ptr): ptr(ptr) {} + + inline Text::Reader get() const { + return Text::Reader(reinterpret_cast(ptr), size); + } + + inline operator Text::Reader() const { return get(); } + inline Text::Reader operator*() const { return get(); } + inline TemporaryPointer operator->() const { return get(); } + + inline kj::StringPtr toString() const { + return get(); + } + +private: + const word* ptr; +}; + +template +inline kj::StringPtr KJ_STRINGIFY(const ConstText& s) { + return s.get(); +} + +template +class ConstData { +public: + ConstData() = delete; + KJ_DISALLOW_COPY(ConstData); + inline explicit constexpr ConstData(const word* ptr): ptr(ptr) {} + + inline Data::Reader get() const { + return Data::Reader(reinterpret_cast(ptr), size); + } + + inline operator Data::Reader() const { return get(); } + inline Data::Reader operator*() const { return get(); } + inline TemporaryPointer operator->() const { return get(); } + +private: + const word* ptr; +}; + +template +inline auto KJ_STRINGIFY(const ConstData& s) -> decltype(kj::toCharSequence(s.get())) { + return kj::toCharSequence(s.get()); +} + +} // namespace _ (private) + +template +inline constexpr uint64_t typeId() { return CapnpPrivate::typeId; } +template ::typeId> +inline constexpr uint64_t typeId() { return id; } +// typeId() returns the type ID as defined in the schema. Works with structs, enums, and +// interfaces. + +template +inline constexpr uint sizeInWords() { + // Return the size, in words, of a Struct type, if allocated free-standing (not in a list). + // May be useful for pre-computing space needed in order to precisely allocate messages. + + return unbound((upgradeBound(_::structSize().data) + + _::structSize().pointers * WORDS_PER_POINTER) / WORDS); +} + +} // namespace capnp + +#if _MSC_VER +// MSVC doesn't understand floating-point constexpr yet. +// +// TODO(msvc): Remove this hack when MSVC is fixed. +#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) +#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) = value +#else +#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) = value +#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) +#endif + +#if _MSC_VER +// TODO(msvc): A little hack to allow MSVC to use C++14 return type deduction in cases where the +// explicit type exposes bugs in the compiler. +#define CAPNP_AUTO_IF_MSVC(...) auto +#else +#define CAPNP_AUTO_IF_MSVC(...) __VA_ARGS__ +#endif + +#if CAPNP_LITE + +#define CAPNP_DECLARE_SCHEMA(id) \ + extern ::capnp::word const* const bp_##id + +#define CAPNP_DECLARE_ENUM(type, id) \ + inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ + return ::kj::str(static_cast(value)); \ + } \ + template <> struct EnumInfo { \ + struct IsEnum; \ + static constexpr uint64_t typeId = 0x##id; \ + static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ + } + +#if _MSC_VER +// TODO(msvc): MSVC dosen't expect constexprs to have definitions. +#define CAPNP_DEFINE_ENUM(type, id) +#else +#define CAPNP_DEFINE_ENUM(type, id) \ + constexpr uint64_t EnumInfo::typeId +#endif + +#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ + struct IsStruct; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr uint16_t dataWordSize = dataWordSize_; \ + static constexpr uint16_t pointerCount = pointerCount_; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } + +#else // CAPNP_LITE + +#define CAPNP_DECLARE_SCHEMA(id) \ + extern ::capnp::word const* const bp_##id; \ + extern const ::capnp::_::RawSchema s_##id + +#define CAPNP_DECLARE_ENUM(type, id) \ + inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ + return ::capnp::_::enumString(value); \ + } \ + template <> struct EnumInfo { \ + struct IsEnum; \ + static constexpr uint64_t typeId = 0x##id; \ + static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &s_##id; \ + } +#define CAPNP_DEFINE_ENUM(type, id) \ + constexpr uint64_t EnumInfo::typeId; \ + constexpr ::capnp::_::RawSchema const* EnumInfo::schema + +#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ + struct IsStruct; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr ::capnp::Kind kind = ::capnp::Kind::STRUCT; \ + static constexpr uint16_t dataWordSize = dataWordSize_; \ + static constexpr uint16_t pointerCount = pointerCount_; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; + +#define CAPNP_DECLARE_INTERFACE_HEADER(id) \ + struct IsInterface; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr ::capnp::Kind kind = ::capnp::Kind::INTERFACE; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; + +#endif // CAPNP_LITE, else + +#endif // CAPNP_GENERATED_HEADER_SUPPORT_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/layout.h --- a/win32-mingw/include/capnp/layout.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/layout.h Tue May 23 09:16:54 2017 +0100 @@ -1,1225 +1,1274 @@ -// Copyright (c) 2013-2016 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 is NOT intended for use by clients, except in generated code. -// -// This file defines low-level, non-type-safe classes for traversing the Cap'n Proto memory layout -// (which is also its wire format). Code generated by the Cap'n Proto compiler uses these classes, -// as does other parts of the Cap'n proto library which provide a higher-level interface for -// dynamic introspection. - -#ifndef CAPNP_LAYOUT_H_ -#define CAPNP_LAYOUT_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include -#include "common.h" -#include "blob.h" -#include "endian.h" - -#if (defined(__mips__) || defined(__hppa__)) && !defined(CAPNP_CANONICALIZE_NAN) -#define CAPNP_CANONICALIZE_NAN 1 -// Explicitly detect NaNs and canonicalize them to the quiet NaN value as would be returned by -// __builtin_nan("") on systems implementing the IEEE-754 recommended (but not required) NaN -// signalling/quiet differentiation (such as x86). Unfortunately, some architectures -- in -// particular, MIPS -- represent quiet vs. signalling nans differently than the rest of the world. -// Canonicalizing them makes output consistent (which is important!), but hurts performance -// slightly. -// -// Note that trying to convert MIPS NaNs to standard NaNs without losing data doesn't work. -// Signaling vs. quiet is indicated by a bit, with the meaning being the opposite on MIPS vs. -// everyone else. It would be great if we could just flip that bit, but we can't, because if the -// significand is all-zero, then the value is infinity rather than NaN. This means that on most -// machines, where the bit indicates quietness, there is one more quiet NaN value than signalling -// NaN value, whereas on MIPS there is one more sNaN than qNaN, and thus there is no isomorphic -// mapping that properly preserves quietness. Instead of doing something hacky, we just give up -// and blow away NaN payloads, because no one uses them anyway. -#endif - -namespace capnp { - -#if !CAPNP_LITE -class ClientHook; -#endif // !CAPNP_LITE - -namespace _ { // private - -class PointerBuilder; -class PointerReader; -class StructBuilder; -class StructReader; -class ListBuilder; -class ListReader; -class OrphanBuilder; -struct WirePointer; -struct WireHelpers; -class SegmentReader; -class SegmentBuilder; -class Arena; -class BuilderArena; - -// ============================================================================= - -typedef decltype(BITS / ELEMENTS) BitsPerElement; -typedef decltype(POINTERS / ELEMENTS) PointersPerElement; - -static constexpr BitsPerElement BITS_PER_ELEMENT_TABLE[8] = { - 0 * BITS / ELEMENTS, - 1 * BITS / ELEMENTS, - 8 * BITS / ELEMENTS, - 16 * BITS / ELEMENTS, - 32 * BITS / ELEMENTS, - 64 * BITS / ELEMENTS, - 0 * BITS / ELEMENTS, - 0 * BITS / ELEMENTS -}; - -inline KJ_CONSTEXPR() BitsPerElement dataBitsPerElement(ElementSize size) { - return _::BITS_PER_ELEMENT_TABLE[static_cast(size)]; -} - -inline constexpr PointersPerElement pointersPerElement(ElementSize size) { - return size == ElementSize::POINTER ? 1 * POINTERS / ELEMENTS : 0 * POINTERS / ELEMENTS; -} - -template struct ElementSizeForByteSize; -template <> struct ElementSizeForByteSize<1> { static constexpr ElementSize value = ElementSize::BYTE; }; -template <> struct ElementSizeForByteSize<2> { static constexpr ElementSize value = ElementSize::TWO_BYTES; }; -template <> struct ElementSizeForByteSize<4> { static constexpr ElementSize value = ElementSize::FOUR_BYTES; }; -template <> struct ElementSizeForByteSize<8> { static constexpr ElementSize value = ElementSize::EIGHT_BYTES; }; - -template struct ElementSizeForType { - static constexpr ElementSize value = - // Primitive types that aren't special-cased below can be determined from sizeof(). - CAPNP_KIND(T) == Kind::PRIMITIVE ? ElementSizeForByteSize::value : - CAPNP_KIND(T) == Kind::ENUM ? ElementSize::TWO_BYTES : - CAPNP_KIND(T) == Kind::STRUCT ? ElementSize::INLINE_COMPOSITE : - - // Everything else is a pointer. - ElementSize::POINTER; -}; - -// Void and bool are special. -template <> struct ElementSizeForType { static constexpr ElementSize value = ElementSize::VOID; }; -template <> struct ElementSizeForType { static constexpr ElementSize value = ElementSize::BIT; }; - -// Lists and blobs are pointers, not structs. -template struct ElementSizeForType> { - static constexpr ElementSize value = ElementSize::POINTER; -}; -template <> struct ElementSizeForType { - static constexpr ElementSize value = ElementSize::POINTER; -}; -template <> struct ElementSizeForType { - static constexpr ElementSize value = ElementSize::POINTER; -}; - -template -inline constexpr ElementSize elementSizeForType() { - return ElementSizeForType::value; -} - -struct MessageSizeCounts { - WordCount64 wordCount; - uint capCount; - - MessageSizeCounts& operator+=(const MessageSizeCounts& other) { - wordCount += other.wordCount; - capCount += other.capCount; - return *this; - } - - MessageSize asPublic() { - return MessageSize { wordCount / WORDS, capCount }; - } -}; - -// ============================================================================= - -template -union AlignedData { - // Useful for declaring static constant data blobs as an array of bytes, but forcing those - // bytes to be word-aligned. - - uint8_t bytes[wordCount * sizeof(word)]; - word words[wordCount]; -}; - -struct StructSize { - WordCount16 data; - WirePointerCount16 pointers; - - inline constexpr WordCount total() const { return data + pointers * WORDS_PER_POINTER; } - - StructSize() = default; - inline constexpr StructSize(WordCount data, WirePointerCount pointers) - : data(data), pointers(pointers) {} -}; - -template -inline constexpr StructSize structSize() { - return StructSize(CapnpPrivate::dataWordSize * WORDS, CapnpPrivate::pointerCount * POINTERS); -} - -template > -inline constexpr StructSize minStructSizeForElement() { - // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough - // to hold a T. - - return StructSize(CapnpPrivate::dataWordSize * WORDS, CapnpPrivate::pointerCount * POINTERS); -} - -template > -inline constexpr StructSize minStructSizeForElement() { - // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough - // to hold a T. - - return StructSize( - dataBitsPerElement(elementSizeForType()) * ELEMENTS > 0 * BITS ? 1 * WORDS : 0 * WORDS, - pointersPerElement(elementSizeForType()) * ELEMENTS); -} - -// ------------------------------------------------------------------- -// Masking of default values - -template struct Mask_; -template struct Mask_ { typedef T Type; }; -template struct Mask_ { typedef uint16_t Type; }; -template <> struct Mask_ { typedef uint32_t Type; }; -template <> struct Mask_ { typedef uint64_t Type; }; - -template struct Mask_ { - // Union discriminants end up here. - static_assert(sizeof(T) == 2, "Don't know how to mask this type."); - typedef uint16_t Type; -}; - -template -using Mask = typename Mask_::Type; - -template -KJ_ALWAYS_INLINE(Mask mask(T value, Mask mask)); -template -KJ_ALWAYS_INLINE(T unmask(Mask value, Mask mask)); - -template -inline Mask mask(T value, Mask mask) { - return static_cast >(value) ^ mask; -} - -template <> -inline uint32_t mask(float value, uint32_t mask) { -#if CAPNP_CANONICALIZE_NAN - if (value != value) { - return 0x7fc00000u ^ mask; - } -#endif - - uint32_t i; - static_assert(sizeof(i) == sizeof(value), "float is not 32 bits?"); - memcpy(&i, &value, sizeof(value)); - return i ^ mask; -} - -template <> -inline uint64_t mask(double value, uint64_t mask) { -#if CAPNP_CANONICALIZE_NAN - if (value != value) { - return 0x7ff8000000000000ull ^ mask; - } -#endif - - uint64_t i; - static_assert(sizeof(i) == sizeof(value), "double is not 64 bits?"); - memcpy(&i, &value, sizeof(value)); - return i ^ mask; -} - -template -inline T unmask(Mask value, Mask mask) { - return static_cast(value ^ mask); -} - -template <> -inline float unmask(uint32_t value, uint32_t mask) { - value ^= mask; - float result; - static_assert(sizeof(result) == sizeof(value), "float is not 32 bits?"); - memcpy(&result, &value, sizeof(value)); - return result; -} - -template <> -inline double unmask(uint64_t value, uint64_t mask) { - value ^= mask; - double result; - static_assert(sizeof(result) == sizeof(value), "double is not 64 bits?"); - memcpy(&result, &value, sizeof(value)); - return result; -} - -// ------------------------------------------------------------------- - -class CapTableReader { -public: -#if !CAPNP_LITE - virtual kj::Maybe> extractCap(uint index) = 0; - // Extract the capability at the given index. If the index is invalid, returns null. -#endif // !CAPNP_LITE -}; - -class CapTableBuilder: public CapTableReader { -public: -#if !CAPNP_LITE - virtual uint injectCap(kj::Own&& cap) = 0; - // Add the capability to the message and return its index. If the same ClientHook is injected - // twice, this may return the same index both times, but in this case dropCap() needs to be - // called an equal number of times to actually remove the cap. - - virtual void dropCap(uint index) = 0; - // Remove a capability injected earlier. Called when the pointer is overwritten or zero'd out. -#endif // !CAPNP_LITE -}; - -// ------------------------------------------------------------------- - -class PointerBuilder: public kj::DisallowConstCopy { - // Represents a single pointer, usually embedded in a struct or a list. - -public: - inline PointerBuilder(): segment(nullptr), capTable(nullptr), pointer(nullptr) {} - - static inline PointerBuilder getRoot( - SegmentBuilder* segment, CapTableBuilder* capTable, word* location); - // Get a PointerBuilder representing a message root located in the given segment at the given - // location. - - inline bool isNull() { return getPointerType() == PointerType::NULL_; } - PointerType getPointerType(); - - StructBuilder getStruct(StructSize size, const word* defaultValue); - ListBuilder getList(ElementSize elementSize, const word* defaultValue); - ListBuilder getStructList(StructSize elementSize, const word* defaultValue); - ListBuilder getListAnySize(const word* defaultValue); - template typename T::Builder getBlob(const void* defaultValue,ByteCount defaultSize); -#if !CAPNP_LITE - kj::Own getCapability(); -#endif // !CAPNP_LITE - // Get methods: Get the value. If it is null, initialize it to a copy of the default value. - // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a - // simple byte array for blobs. - - StructBuilder initStruct(StructSize size); - ListBuilder initList(ElementSize elementSize, ElementCount elementCount); - ListBuilder initStructList(ElementCount elementCount, StructSize size); - template typename T::Builder initBlob(ByteCount size); - // Init methods: Initialize the pointer to a newly-allocated object, discarding the existing - // object. - - void setStruct(const StructReader& value, bool canonical = false); - void setList(const ListReader& value, bool canonical = false); - template void setBlob(typename T::Reader value); -#if !CAPNP_LITE - void setCapability(kj::Own&& cap); -#endif // !CAPNP_LITE - // Set methods: Initialize the pointer to a newly-allocated copy of the given value, discarding - // the existing object. - - void adopt(OrphanBuilder&& orphan); - // Set the pointer to point at the given orphaned value. - - OrphanBuilder disown(); - // Set the pointer to null and return its previous value as an orphan. - - void clear(); - // Clear the pointer to null, discarding its previous value. - - void transferFrom(PointerBuilder other); - // Equivalent to `adopt(other.disown())`. - - void copyFrom(PointerReader other, bool canonical = false); - // Equivalent to `set(other.get())`. - // If you set the canonical flag, it will attempt to lay the target out - // canonically, provided enough space is available. - - PointerReader asReader() const; - - BuilderArena* getArena() const; - // Get the arena containing this pointer. - - CapTableBuilder* getCapTable(); - // Gets the capability context in which this object is operating. - - PointerBuilder imbue(CapTableBuilder* capTable); - // Return a copy of this builder except using the given capability context. - -private: - SegmentBuilder* segment; // Memory segment in which the pointer resides. - CapTableBuilder* capTable; // Table of capability indexes. - WirePointer* pointer; // Pointer to the pointer. - - inline PointerBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* pointer) - : segment(segment), capTable(capTable), pointer(pointer) {} - - friend class StructBuilder; - friend class ListBuilder; - friend class OrphanBuilder; -}; - -class PointerReader { -public: - inline PointerReader() - : segment(nullptr), capTable(nullptr), pointer(nullptr), nestingLimit(0x7fffffff) {} - - static PointerReader getRoot(SegmentReader* segment, CapTableReader* capTable, - const word* location, int nestingLimit); - // Get a PointerReader representing a message root located in the given segment at the given - // location. - - static inline PointerReader getRootUnchecked(const word* location); - // Get a PointerReader for an unchecked message. - - MessageSizeCounts targetSize() const; - // Return the total size of the target object and everything to which it points. Does not count - // far pointer overhead. This is useful for deciding how much space is needed to copy the object - // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, - // use the result as a hint for allocating the first segment, do the copy, and then throw an - // exception if it overruns. - - inline bool isNull() const { return getPointerType() == PointerType::NULL_; } - PointerType getPointerType() const; - - StructReader getStruct(const word* defaultValue) const; - ListReader getList(ElementSize expectedElementSize, const word* defaultValue) const; - ListReader getListAnySize(const word* defaultValue) const; - template - typename T::Reader getBlob(const void* defaultValue, ByteCount defaultSize) const; -#if !CAPNP_LITE - kj::Own getCapability() const; -#endif // !CAPNP_LITE - // Get methods: Get the value. If it is null, return the default value instead. - // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a - // simple byte array for blobs. - - const word* getUnchecked() const; - // If this is an unchecked message, get a word* pointing at the location of the pointer. This - // word* can actually be passed to readUnchecked() to read the designated sub-object later. If - // this isn't an unchecked message, throws an exception. - - kj::Maybe getArena() const; - // Get the arena containing this pointer. - - CapTableReader* getCapTable(); - // Gets the capability context in which this object is operating. - - PointerReader imbue(CapTableReader* capTable) const; - // Return a copy of this reader except using the given capability context. - - bool isCanonical(const word **readHead); - // Validate this pointer's canonicity, subject to the conditions: - // * All data to the left of readHead has been read thus far (for pointer - // ordering) - // * All pointers in preorder have already been checked - // * This pointer is in the first and only segment of the message - -private: - SegmentReader* segment; // Memory segment in which the pointer resides. - CapTableReader* capTable; // Table of capability indexes. - const WirePointer* pointer; // Pointer to the pointer. null = treat as null pointer. - - int nestingLimit; - // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. - // Once this reaches zero, further pointers will be pruned. - - inline PointerReader(SegmentReader* segment, CapTableReader* capTable, - const WirePointer* pointer, int nestingLimit) - : segment(segment), capTable(capTable), pointer(pointer), nestingLimit(nestingLimit) {} - - friend class StructReader; - friend class ListReader; - friend class PointerBuilder; - friend class OrphanBuilder; -}; - -// ------------------------------------------------------------------- - -class StructBuilder: public kj::DisallowConstCopy { -public: - inline StructBuilder(): segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr) {} - - inline word* getLocation() { return reinterpret_cast(data); } - // Get the object's location. Only valid for independently-allocated objects (i.e. not list - // elements). - - inline BitCount getDataSectionSize() const { return dataSize; } - inline WirePointerCount getPointerSectionSize() const { return pointerCount; } - inline kj::ArrayPtr getDataSectionAsBlob(); - inline _::ListBuilder getPointerSectionAsList(); - - template - KJ_ALWAYS_INLINE(bool hasDataField(ElementCount offset)); - // Return true if the field is set to something other than its default value. - - template - KJ_ALWAYS_INLINE(T getDataField(ElementCount offset)); - // Gets the data field value of the given type at the given offset. The offset is measured in - // multiples of the field size, determined by the type. - - template - KJ_ALWAYS_INLINE(T getDataField(ElementCount offset, Mask mask)); - // Like getDataField() but applies the given XOR mask to the data on load. Used for reading - // fields with non-zero default values. - - template - KJ_ALWAYS_INLINE(void setDataField( - ElementCount offset, kj::NoInfer value)); - // Sets the data field value at the given offset. - - template - KJ_ALWAYS_INLINE(void setDataField( - ElementCount offset, kj::NoInfer value, Mask mask)); - // Like setDataField() but applies the given XOR mask before storing. Used for writing fields - // with non-zero default values. - - KJ_ALWAYS_INLINE(PointerBuilder getPointerField(WirePointerCount ptrIndex)); - // Get a builder for a pointer field given the index within the pointer section. - - void clearAll(); - // Clear all pointers and data. - - void transferContentFrom(StructBuilder other); - // Adopt all pointers from `other`, and also copy all data. If `other`'s sections are larger - // than this, the extra data is not transferred, meaning there is a risk of data loss when - // transferring from messages built with future versions of the protocol. - - void copyContentFrom(StructReader other); - // Copy content from `other`. If `other`'s sections are larger than this, the extra data is not - // copied, meaning there is a risk of data loss when copying from messages built with future - // versions of the protocol. - - StructReader asReader() const; - // Gets a StructReader pointing at the same memory. - - BuilderArena* getArena(); - // Gets the arena in which this object is allocated. - - CapTableBuilder* getCapTable(); - // Gets the capability context in which this object is operating. - - StructBuilder imbue(CapTableBuilder* capTable); - // Return a copy of this builder except using the given capability context. - -private: - SegmentBuilder* segment; // Memory segment in which the struct resides. - CapTableBuilder* capTable; // Table of capability indexes. - void* data; // Pointer to the encoded data. - WirePointer* pointers; // Pointer to the encoded pointers. - - BitCount32 dataSize; - // Size of data section. We use a bit count rather than a word count to more easily handle the - // case of struct lists encoded with less than a word per element. - - WirePointerCount16 pointerCount; // Size of the pointer section. - - inline StructBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, - void* data, WirePointer* pointers, - BitCount dataSize, WirePointerCount pointerCount) - : segment(segment), capTable(capTable), data(data), pointers(pointers), - dataSize(dataSize), pointerCount(pointerCount) {} - - friend class ListBuilder; - friend struct WireHelpers; - friend class OrphanBuilder; -}; - -class StructReader { -public: - inline StructReader() - : segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr), dataSize(0), - pointerCount(0), nestingLimit(0x7fffffff) {} - inline StructReader(kj::ArrayPtr data) - : segment(nullptr), capTable(nullptr), data(data.begin()), pointers(nullptr), - dataSize(data.size() * WORDS * BITS_PER_WORD), pointerCount(0), nestingLimit(0x7fffffff) {} - - const void* getLocation() const { return data; } - - inline BitCount getDataSectionSize() const { return dataSize; } - inline WirePointerCount getPointerSectionSize() const { return pointerCount; } - inline kj::ArrayPtr getDataSectionAsBlob(); - inline _::ListReader getPointerSectionAsList(); - - kj::Array canonicalize(); - - template - KJ_ALWAYS_INLINE(bool hasDataField(ElementCount offset) const); - // Return true if the field is set to something other than its default value. - - template - KJ_ALWAYS_INLINE(T getDataField(ElementCount offset) const); - // Get the data field value of the given type at the given offset. The offset is measured in - // multiples of the field size, determined by the type. Returns zero if the offset is past the - // end of the struct's data section. - - template - KJ_ALWAYS_INLINE( - T getDataField(ElementCount offset, Mask mask) const); - // Like getDataField(offset), but applies the given XOR mask to the result. Used for reading - // fields with non-zero default values. - - KJ_ALWAYS_INLINE(PointerReader getPointerField(WirePointerCount ptrIndex) const); - // Get a reader for a pointer field given the index within the pointer section. If the index - // is out-of-bounds, returns a null pointer. - - MessageSizeCounts totalSize() const; - // Return the total size of the struct and everything to which it points. Does not count far - // pointer overhead. This is useful for deciding how much space is needed to copy the struct - // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, - // use the result as a hint for allocating the first segment, do the copy, and then throw an - // exception if it overruns. - - CapTableReader* getCapTable(); - // Gets the capability context in which this object is operating. - - StructReader imbue(CapTableReader* capTable) const; - // Return a copy of this reader except using the given capability context. - - bool isCanonical(const word **readHead, const word **ptrHead, - bool *dataTrunc, bool *ptrTrunc); - // Validate this pointer's canonicity, subject to the conditions: - // * All data to the left of readHead has been read thus far (for pointer - // ordering) - // * All pointers in preorder have already been checked - // * This pointer is in the first and only segment of the message - // - // If this function returns false, the struct is non-canonical. If it - // returns true, then: - // * If it is a composite in a list, it is canonical if at least one struct - // in the list outputs dataTrunc = 1, and at least one outputs ptrTrunc = 1 - // * If it is derived from a struct pointer, it is canonical if - // dataTrunc = 1 AND ptrTrunc = 1 - -private: - SegmentReader* segment; // Memory segment in which the struct resides. - CapTableReader* capTable; // Table of capability indexes. - - const void* data; - const WirePointer* pointers; - - BitCount32 dataSize; - // Size of data section. We use a bit count rather than a word count to more easily handle the - // case of struct lists encoded with less than a word per element. - - WirePointerCount16 pointerCount; // Size of the pointer section. - - int nestingLimit; - // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. - // Once this reaches zero, further pointers will be pruned. - // TODO(perf): Limit to 16 bits for better packing? - - inline StructReader(SegmentReader* segment, CapTableReader* capTable, - const void* data, const WirePointer* pointers, - BitCount dataSize, WirePointerCount pointerCount, int nestingLimit) - : segment(segment), capTable(capTable), data(data), pointers(pointers), - dataSize(dataSize), pointerCount(pointerCount), - nestingLimit(nestingLimit) {} - - friend class ListReader; - friend class StructBuilder; - friend struct WireHelpers; -}; - -// ------------------------------------------------------------------- - -class ListBuilder: public kj::DisallowConstCopy { -public: - inline explicit ListBuilder(ElementSize elementSize) - : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(0 * ELEMENTS), - step(0 * BITS / ELEMENTS), structDataSize(0 * BITS), structPointerCount(0 * POINTERS), - elementSize(elementSize) {} - - inline word* getLocation() { - // Get the object's location. - - if (elementSize == ElementSize::INLINE_COMPOSITE && ptr != nullptr) { - return reinterpret_cast(ptr) - POINTER_SIZE_IN_WORDS; - } else { - return reinterpret_cast(ptr); - } - } - - inline ElementSize getElementSize() const { return elementSize; } - - inline ElementCount size() const; - // The number of elements in the list. - - Text::Builder asText(); - Data::Builder asData(); - // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. - - template - KJ_ALWAYS_INLINE(T getDataElement(ElementCount index)); - // Get the element of the given type at the given index. - - template - KJ_ALWAYS_INLINE(void setDataElement( - ElementCount index, kj::NoInfer value)); - // Set the element at the given index. - - KJ_ALWAYS_INLINE(PointerBuilder getPointerElement(ElementCount index)); - - StructBuilder getStructElement(ElementCount index); - - ListReader asReader() const; - // Get a ListReader pointing at the same memory. - - BuilderArena* getArena(); - // Gets the arena in which this object is allocated. - - CapTableBuilder* getCapTable(); - // Gets the capability context in which this object is operating. - - ListBuilder imbue(CapTableBuilder* capTable); - // Return a copy of this builder except using the given capability context. - -private: - SegmentBuilder* segment; // Memory segment in which the list resides. - CapTableBuilder* capTable; // Table of capability indexes. - - byte* ptr; // Pointer to list content. - - ElementCount elementCount; // Number of elements in the list. - - decltype(BITS / ELEMENTS) step; - // The distance between elements. - - BitCount32 structDataSize; - WirePointerCount16 structPointerCount; - // The struct properties to use when interpreting the elements as structs. All lists can be - // interpreted as struct lists, so these are always filled in. - - ElementSize elementSize; - // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE - // from other types when the overall size is exactly zero or one words. - - inline ListBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, void* ptr, - decltype(BITS / ELEMENTS) step, ElementCount size, - BitCount structDataSize, WirePointerCount structPointerCount, - ElementSize elementSize) - : segment(segment), capTable(capTable), ptr(reinterpret_cast(ptr)), - elementCount(size), step(step), structDataSize(structDataSize), - structPointerCount(structPointerCount), elementSize(elementSize) {} - - friend class StructBuilder; - friend struct WireHelpers; - friend class OrphanBuilder; -}; - -class ListReader { -public: - inline explicit ListReader(ElementSize elementSize) - : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(0), - step(0 * BITS / ELEMENTS), structDataSize(0), structPointerCount(0), - elementSize(elementSize), nestingLimit(0x7fffffff) {} - - inline ElementCount size() const; - // The number of elements in the list. - - inline ElementSize getElementSize() const { return elementSize; } - - Text::Reader asText(); - Data::Reader asData(); - // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. - - kj::ArrayPtr asRawBytes(); - - template - KJ_ALWAYS_INLINE(T getDataElement(ElementCount index) const); - // Get the element of the given type at the given index. - - KJ_ALWAYS_INLINE(PointerReader getPointerElement(ElementCount index) const); - - StructReader getStructElement(ElementCount index) const; - - CapTableReader* getCapTable(); - // Gets the capability context in which this object is operating. - - ListReader imbue(CapTableReader* capTable) const; - // Return a copy of this reader except using the given capability context. - - bool isCanonical(const word **readHead); - // Validate this pointer's canonicity, subject to the conditions: - // * All data to the left of readHead has been read thus far (for pointer - // ordering) - // * All pointers in preorder have already been checked - // * This pointer is in the first and only segment of the message - -private: - SegmentReader* segment; // Memory segment in which the list resides. - CapTableReader* capTable; // Table of capability indexes. - - const byte* ptr; // Pointer to list content. - - ElementCount elementCount; // Number of elements in the list. - - decltype(BITS / ELEMENTS) step; - // The distance between elements. - - BitCount32 structDataSize; - WirePointerCount16 structPointerCount; - // The struct properties to use when interpreting the elements as structs. All lists can be - // interpreted as struct lists, so these are always filled in. - - ElementSize elementSize; - // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE - // from other types when the overall size is exactly zero or one words. - - int nestingLimit; - // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. - // Once this reaches zero, further pointers will be pruned. - - inline ListReader(SegmentReader* segment, CapTableReader* capTable, const void* ptr, - ElementCount elementCount, decltype(BITS / ELEMENTS) step, - BitCount structDataSize, WirePointerCount structPointerCount, - ElementSize elementSize, int nestingLimit) - : segment(segment), capTable(capTable), ptr(reinterpret_cast(ptr)), - elementCount(elementCount), step(step), structDataSize(structDataSize), - structPointerCount(structPointerCount), elementSize(elementSize), - nestingLimit(nestingLimit) {} - - friend class StructReader; - friend class ListBuilder; - friend struct WireHelpers; - friend class OrphanBuilder; -}; - -// ------------------------------------------------------------------- - -class OrphanBuilder { -public: - inline OrphanBuilder(): segment(nullptr), capTable(nullptr), location(nullptr) { - memset(&tag, 0, sizeof(tag)); - } - OrphanBuilder(const OrphanBuilder& other) = delete; - inline OrphanBuilder(OrphanBuilder&& other) noexcept; - inline ~OrphanBuilder() noexcept(false); - - static OrphanBuilder initStruct(BuilderArena* arena, CapTableBuilder* capTable, StructSize size); - static OrphanBuilder initList(BuilderArena* arena, CapTableBuilder* capTable, - ElementCount elementCount, ElementSize elementSize); - static OrphanBuilder initStructList(BuilderArena* arena, CapTableBuilder* capTable, - ElementCount elementCount, StructSize elementSize); - static OrphanBuilder initText(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); - static OrphanBuilder initData(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); - - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, StructReader copyFrom); - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, ListReader copyFrom); - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, PointerReader copyFrom); - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Text::Reader copyFrom); - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Data::Reader copyFrom); -#if !CAPNP_LITE - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, - kj::Own copyFrom); -#endif // !CAPNP_LITE - - static OrphanBuilder concat(BuilderArena* arena, CapTableBuilder* capTable, - ElementSize expectedElementSize, StructSize expectedStructSize, - kj::ArrayPtr lists); - - static OrphanBuilder referenceExternalData(BuilderArena* arena, Data::Reader data); - - OrphanBuilder& operator=(const OrphanBuilder& other) = delete; - inline OrphanBuilder& operator=(OrphanBuilder&& other); - - inline bool operator==(decltype(nullptr)) const { return location == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return location != nullptr; } - - StructBuilder asStruct(StructSize size); - // Interpret as a struct, or throw an exception if not a struct. - - ListBuilder asList(ElementSize elementSize); - // Interpret as a list, or throw an exception if not a list. elementSize cannot be - // INLINE_COMPOSITE -- use asStructList() instead. - - ListBuilder asStructList(StructSize elementSize); - // Interpret as a struct list, or throw an exception if not a list. - - Text::Builder asText(); - Data::Builder asData(); - // Interpret as a blob, or throw an exception if not a blob. - - StructReader asStructReader(StructSize size) const; - ListReader asListReader(ElementSize elementSize) const; -#if !CAPNP_LITE - kj::Own asCapability() const; -#endif // !CAPNP_LITE - Text::Reader asTextReader() const; - Data::Reader asDataReader() const; - - bool truncate(ElementCount size, bool isText) KJ_WARN_UNUSED_RESULT; - // Resize the orphan list to the given size. Returns false if the list is currently empty but - // the requested size is non-zero, in which case the caller will need to allocate a new list. - - void truncate(ElementCount size, ElementSize elementSize); - void truncate(ElementCount size, StructSize elementSize); - void truncateText(ElementCount size); - // Versions of truncate() that know how to allocate a new list if needed. - -private: - static_assert(1 * POINTERS * WORDS_PER_POINTER == 1 * WORDS, - "This struct assumes a pointer is one word."); - word tag; - // Contains an encoded WirePointer representing this object. WirePointer is defined in - // layout.c++, but fits in a word. - // - // This may be a FAR pointer. Even in that case, `location` points to the eventual destination - // of that far pointer. The reason we keep the far pointer around rather than just making `tag` - // represent the final destination is because if the eventual adopter of the pointer is not in - // the target's segment then it may be useful to reuse the far pointer landing pad. - // - // If `tag` is not a far pointer, its offset is garbage; only `location` points to the actual - // target. - - SegmentBuilder* segment; - // Segment in which the object resides. - - CapTableBuilder* capTable; - // Table of capability indexes. - - word* location; - // Pointer to the object, or nullptr if the pointer is null. For capabilities, we make this - // 0x1 just so that it is non-null for operator==, but it is never used. - - inline OrphanBuilder(const void* tagPtr, SegmentBuilder* segment, - CapTableBuilder* capTable, word* location) - : segment(segment), capTable(capTable), location(location) { - memcpy(&tag, tagPtr, sizeof(tag)); - } - - inline WirePointer* tagAsPtr() { return reinterpret_cast(&tag); } - inline const WirePointer* tagAsPtr() const { return reinterpret_cast(&tag); } - - void euthanize(); - // Erase the target object, zeroing it out and possibly reclaiming the memory. Called when - // the OrphanBuilder is being destroyed or overwritten and it is non-null. - - friend struct WireHelpers; -}; - -// ======================================================================================= -// Internal implementation details... - -// These are defined in the source file. -template <> typename Text::Builder PointerBuilder::initBlob(ByteCount size); -template <> void PointerBuilder::setBlob(typename Text::Reader value); -template <> typename Text::Builder PointerBuilder::getBlob(const void* defaultValue, ByteCount defaultSize); -template <> typename Text::Reader PointerReader::getBlob(const void* defaultValue, ByteCount defaultSize) const; - -template <> typename Data::Builder PointerBuilder::initBlob(ByteCount size); -template <> void PointerBuilder::setBlob(typename Data::Reader value); -template <> typename Data::Builder PointerBuilder::getBlob(const void* defaultValue, ByteCount defaultSize); -template <> typename Data::Reader PointerReader::getBlob(const void* defaultValue, ByteCount defaultSize) const; - -inline PointerBuilder PointerBuilder::getRoot( - SegmentBuilder* segment, CapTableBuilder* capTable, word* location) { - return PointerBuilder(segment, capTable, reinterpret_cast(location)); -} - -inline PointerReader PointerReader::getRootUnchecked(const word* location) { - return PointerReader(nullptr, nullptr, - reinterpret_cast(location), 0x7fffffff); -} - -// ------------------------------------------------------------------- - -inline kj::ArrayPtr StructBuilder::getDataSectionAsBlob() { - return kj::ArrayPtr(reinterpret_cast(data), dataSize / BITS_PER_BYTE / BYTES); -} - -inline _::ListBuilder StructBuilder::getPointerSectionAsList() { - return _::ListBuilder(segment, capTable, pointers, 1 * POINTERS * BITS_PER_POINTER / ELEMENTS, - pointerCount * (1 * ELEMENTS / POINTERS), - 0 * BITS, 1 * POINTERS, ElementSize::POINTER); -} - -template -inline bool StructBuilder::hasDataField(ElementCount offset) { - return getDataField>(offset) != 0; -} - -template <> -inline bool StructBuilder::hasDataField(ElementCount offset) { - return false; -} - -template -inline T StructBuilder::getDataField(ElementCount offset) { - return reinterpret_cast*>(data)[offset / ELEMENTS].get(); -} - -template <> -inline bool StructBuilder::getDataField(ElementCount offset) { - BitCount boffset = offset * (1 * BITS / ELEMENTS); - byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; - return (*reinterpret_cast(b) & (1 << (boffset % BITS_PER_BYTE / BITS))) != 0; -} - -template <> -inline Void StructBuilder::getDataField(ElementCount offset) { - return VOID; -} - -template -inline T StructBuilder::getDataField(ElementCount offset, Mask mask) { - return unmask(getDataField >(offset), mask); -} - -template -inline void StructBuilder::setDataField(ElementCount offset, kj::NoInfer value) { - reinterpret_cast*>(data)[offset / ELEMENTS].set(value); -} - -#if CAPNP_CANONICALIZE_NAN -// Use mask() on floats and doubles to make sure we canonicalize NaNs. -template <> -inline void StructBuilder::setDataField(ElementCount offset, float value) { - setDataField(offset, mask(value, 0)); -} -template <> -inline void StructBuilder::setDataField(ElementCount offset, double value) { - setDataField(offset, mask(value, 0)); -} -#endif - -template <> -inline void StructBuilder::setDataField(ElementCount offset, bool value) { - BitCount boffset = offset * (1 * BITS / ELEMENTS); - byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; - uint bitnum = boffset % BITS_PER_BYTE / BITS; - *reinterpret_cast(b) = (*reinterpret_cast(b) & ~(1 << bitnum)) - | (static_cast(value) << bitnum); -} - -template <> -inline void StructBuilder::setDataField(ElementCount offset, Void value) {} - -template -inline void StructBuilder::setDataField(ElementCount offset, kj::NoInfer value, Mask m) { - setDataField >(offset, mask(value, m)); -} - -inline PointerBuilder StructBuilder::getPointerField(WirePointerCount ptrIndex) { - // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). - return PointerBuilder(segment, capTable, reinterpret_cast( - reinterpret_cast(pointers) + ptrIndex * WORDS_PER_POINTER)); -} - -// ------------------------------------------------------------------- - -inline kj::ArrayPtr StructReader::getDataSectionAsBlob() { - return kj::ArrayPtr(reinterpret_cast(data), dataSize / BITS_PER_BYTE / BYTES); -} - -inline _::ListReader StructReader::getPointerSectionAsList() { - return _::ListReader(segment, capTable, pointers, pointerCount * (1 * ELEMENTS / POINTERS), - 1 * POINTERS * BITS_PER_POINTER / ELEMENTS, 0 * BITS, 1 * POINTERS, - ElementSize::POINTER, nestingLimit); -} - -template -inline bool StructReader::hasDataField(ElementCount offset) const { - return getDataField>(offset) != 0; -} - -template <> -inline bool StructReader::hasDataField(ElementCount offset) const { - return false; -} - -template -inline T StructReader::getDataField(ElementCount offset) const { - if ((offset + 1 * ELEMENTS) * capnp::bitsPerElement() <= dataSize) { - return reinterpret_cast*>(data)[offset / ELEMENTS].get(); - } else { - return static_cast(0); - } -} - -template <> -inline bool StructReader::getDataField(ElementCount offset) const { - BitCount boffset = offset * (1 * BITS / ELEMENTS); - if (boffset < dataSize) { - const byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; - return (*reinterpret_cast(b) & (1 << (boffset % BITS_PER_BYTE / BITS))) != 0; - } else { - return false; - } -} - -template <> -inline Void StructReader::getDataField(ElementCount offset) const { - return VOID; -} - -template -T StructReader::getDataField(ElementCount offset, Mask mask) const { - return unmask(getDataField >(offset), mask); -} - -inline PointerReader StructReader::getPointerField(WirePointerCount ptrIndex) const { - if (ptrIndex < pointerCount) { - // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). - return PointerReader(segment, capTable, reinterpret_cast( - reinterpret_cast(pointers) + ptrIndex * WORDS_PER_POINTER), nestingLimit); - } else{ - return PointerReader(); - } -} - -// ------------------------------------------------------------------- - -inline ElementCount ListBuilder::size() const { return elementCount; } - -template -inline T ListBuilder::getDataElement(ElementCount index) { - return reinterpret_cast*>(ptr + index * step / BITS_PER_BYTE)->get(); - - // TODO(perf): Benchmark this alternate implementation, which I suspect may make better use of - // the x86 SIB byte. Also use it for all the other getData/setData implementations below, and - // the various non-inline methods that look up pointers. - // Also if using this, consider changing ptr back to void* instead of byte*. -// return reinterpret_cast*>(ptr)[ -// index / ELEMENTS * (step / capnp::bitsPerElement())].get(); -} - -template <> -inline bool ListBuilder::getDataElement(ElementCount index) { - // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. - BitCount bindex = index * (1 * BITS / ELEMENTS); - byte* b = ptr + bindex / BITS_PER_BYTE; - return (*reinterpret_cast(b) & (1 << (bindex % BITS_PER_BYTE / BITS))) != 0; -} - -template <> -inline Void ListBuilder::getDataElement(ElementCount index) { - return VOID; -} - -template -inline void ListBuilder::setDataElement(ElementCount index, kj::NoInfer value) { - reinterpret_cast*>(ptr + index * step / BITS_PER_BYTE)->set(value); -} - -#if CAPNP_CANONICALIZE_NAN -// Use mask() on floats and doubles to make sure we canonicalize NaNs. -template <> -inline void ListBuilder::setDataElement(ElementCount index, float value) { - setDataElement(index, mask(value, 0)); -} -template <> -inline void ListBuilder::setDataElement(ElementCount index, double value) { - setDataElement(index, mask(value, 0)); -} -#endif - -template <> -inline void ListBuilder::setDataElement(ElementCount index, bool value) { - // Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists. - BitCount bindex = index * (1 * BITS / ELEMENTS); - byte* b = ptr + bindex / BITS_PER_BYTE; - uint bitnum = bindex % BITS_PER_BYTE / BITS; - *reinterpret_cast(b) = (*reinterpret_cast(b) & ~(1 << bitnum)) - | (static_cast(value) << bitnum); -} - -template <> -inline void ListBuilder::setDataElement(ElementCount index, Void value) {} - -inline PointerBuilder ListBuilder::getPointerElement(ElementCount index) { - return PointerBuilder(segment, capTable, - reinterpret_cast(ptr + index * step / BITS_PER_BYTE)); -} - -// ------------------------------------------------------------------- - -inline ElementCount ListReader::size() const { return elementCount; } - -template -inline T ListReader::getDataElement(ElementCount index) const { - return reinterpret_cast*>(ptr + index * step / BITS_PER_BYTE)->get(); -} - -template <> -inline bool ListReader::getDataElement(ElementCount index) const { - // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. - BitCount bindex = index * (1 * BITS / ELEMENTS); - const byte* b = ptr + bindex / BITS_PER_BYTE; - return (*reinterpret_cast(b) & (1 << (bindex % BITS_PER_BYTE / BITS))) != 0; -} - -template <> -inline Void ListReader::getDataElement(ElementCount index) const { - return VOID; -} - -inline PointerReader ListReader::getPointerElement(ElementCount index) const { - return PointerReader(segment, capTable, - reinterpret_cast(ptr + index * step / BITS_PER_BYTE), nestingLimit); -} - -// ------------------------------------------------------------------- - -inline OrphanBuilder::OrphanBuilder(OrphanBuilder&& other) noexcept - : segment(other.segment), capTable(other.capTable), location(other.location) { - memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. - other.segment = nullptr; - other.location = nullptr; -} - -inline OrphanBuilder::~OrphanBuilder() noexcept(false) { - if (segment != nullptr) euthanize(); -} - -inline OrphanBuilder& OrphanBuilder::operator=(OrphanBuilder&& other) { - // With normal smart pointers, it's important to handle the case where the incoming pointer - // is actually transitively owned by this one. In this case, euthanize() would destroy `other` - // before we copied it. This isn't possible in the case of `OrphanBuilder` because it only - // owns message objects, and `other` is not itself a message object, therefore cannot possibly - // be transitively owned by `this`. - - if (segment != nullptr) euthanize(); - segment = other.segment; - capTable = other.capTable; - location = other.location; - memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. - other.segment = nullptr; - other.location = nullptr; - return *this; -} - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_LAYOUT_H_ +// Copyright (c) 2013-2016 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 is NOT intended for use by clients, except in generated code. +// +// This file defines low-level, non-type-safe classes for traversing the Cap'n Proto memory layout +// (which is also its wire format). Code generated by the Cap'n Proto compiler uses these classes, +// as does other parts of the Cap'n proto library which provide a higher-level interface for +// dynamic introspection. + +#ifndef CAPNP_LAYOUT_H_ +#define CAPNP_LAYOUT_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include +#include +#include "common.h" +#include "blob.h" +#include "endian.h" + +#if (defined(__mips__) || defined(__hppa__)) && !defined(CAPNP_CANONICALIZE_NAN) +#define CAPNP_CANONICALIZE_NAN 1 +// Explicitly detect NaNs and canonicalize them to the quiet NaN value as would be returned by +// __builtin_nan("") on systems implementing the IEEE-754 recommended (but not required) NaN +// signalling/quiet differentiation (such as x86). Unfortunately, some architectures -- in +// particular, MIPS -- represent quiet vs. signalling nans differently than the rest of the world. +// Canonicalizing them makes output consistent (which is important!), but hurts performance +// slightly. +// +// Note that trying to convert MIPS NaNs to standard NaNs without losing data doesn't work. +// Signaling vs. quiet is indicated by a bit, with the meaning being the opposite on MIPS vs. +// everyone else. It would be great if we could just flip that bit, but we can't, because if the +// significand is all-zero, then the value is infinity rather than NaN. This means that on most +// machines, where the bit indicates quietness, there is one more quiet NaN value than signalling +// NaN value, whereas on MIPS there is one more sNaN than qNaN, and thus there is no isomorphic +// mapping that properly preserves quietness. Instead of doing something hacky, we just give up +// and blow away NaN payloads, because no one uses them anyway. +#endif + +namespace capnp { + +#if !CAPNP_LITE +class ClientHook; +#endif // !CAPNP_LITE + +namespace _ { // private + +class PointerBuilder; +class PointerReader; +class StructBuilder; +class StructReader; +class ListBuilder; +class ListReader; +class OrphanBuilder; +struct WirePointer; +struct WireHelpers; +class SegmentReader; +class SegmentBuilder; +class Arena; +class BuilderArena; + +// ============================================================================= + +#if CAPNP_DEBUG_TYPES +typedef kj::UnitRatio, BitLabel, ElementLabel> BitsPerElementTableType; +#else +typedef uint BitsPerElementTableType; +#endif + +static constexpr BitsPerElementTableType BITS_PER_ELEMENT_TABLE[8] = { + bounded< 0>() * BITS / ELEMENTS, + bounded< 1>() * BITS / ELEMENTS, + bounded< 8>() * BITS / ELEMENTS, + bounded<16>() * BITS / ELEMENTS, + bounded<32>() * BITS / ELEMENTS, + bounded<64>() * BITS / ELEMENTS, + bounded< 0>() * BITS / ELEMENTS, + bounded< 0>() * BITS / ELEMENTS +}; + +inline KJ_CONSTEXPR() BitsPerElementTableType dataBitsPerElement(ElementSize size) { + return _::BITS_PER_ELEMENT_TABLE[static_cast(size)]; +} + +inline constexpr PointersPerElementN<1> pointersPerElement(ElementSize size) { + return size == ElementSize::POINTER + ? PointersPerElementN<1>(ONE * POINTERS / ELEMENTS) + : PointersPerElementN<1>(ZERO * POINTERS / ELEMENTS); +} + +static constexpr BitsPerElementTableType BITS_PER_ELEMENT_INCLUDING_PONITERS_TABLE[8] = { + bounded< 0>() * BITS / ELEMENTS, + bounded< 1>() * BITS / ELEMENTS, + bounded< 8>() * BITS / ELEMENTS, + bounded<16>() * BITS / ELEMENTS, + bounded<32>() * BITS / ELEMENTS, + bounded<64>() * BITS / ELEMENTS, + bounded<64>() * BITS / ELEMENTS, + bounded< 0>() * BITS / ELEMENTS +}; + +inline KJ_CONSTEXPR() BitsPerElementTableType bitsPerElementIncludingPointers(ElementSize size) { + return _::BITS_PER_ELEMENT_INCLUDING_PONITERS_TABLE[static_cast(size)]; +} + +template struct ElementSizeForByteSize; +template <> struct ElementSizeForByteSize<1> { static constexpr ElementSize value = ElementSize::BYTE; }; +template <> struct ElementSizeForByteSize<2> { static constexpr ElementSize value = ElementSize::TWO_BYTES; }; +template <> struct ElementSizeForByteSize<4> { static constexpr ElementSize value = ElementSize::FOUR_BYTES; }; +template <> struct ElementSizeForByteSize<8> { static constexpr ElementSize value = ElementSize::EIGHT_BYTES; }; + +template struct ElementSizeForType { + static constexpr ElementSize value = + // Primitive types that aren't special-cased below can be determined from sizeof(). + CAPNP_KIND(T) == Kind::PRIMITIVE ? ElementSizeForByteSize::value : + CAPNP_KIND(T) == Kind::ENUM ? ElementSize::TWO_BYTES : + CAPNP_KIND(T) == Kind::STRUCT ? ElementSize::INLINE_COMPOSITE : + + // Everything else is a pointer. + ElementSize::POINTER; +}; + +// Void and bool are special. +template <> struct ElementSizeForType { static constexpr ElementSize value = ElementSize::VOID; }; +template <> struct ElementSizeForType { static constexpr ElementSize value = ElementSize::BIT; }; + +// Lists and blobs are pointers, not structs. +template struct ElementSizeForType> { + static constexpr ElementSize value = ElementSize::POINTER; +}; +template <> struct ElementSizeForType { + static constexpr ElementSize value = ElementSize::POINTER; +}; +template <> struct ElementSizeForType { + static constexpr ElementSize value = ElementSize::POINTER; +}; + +template +inline constexpr ElementSize elementSizeForType() { + return ElementSizeForType::value; +} + +struct MessageSizeCounts { + WordCountN<61, uint64_t> wordCount; // 2^64 bytes + uint capCount; + + MessageSizeCounts& operator+=(const MessageSizeCounts& other) { + // OK to truncate unchecked because this class is used to count actual stuff in memory, and + // we couldn't possibly have anywhere near 2^61 words. + wordCount = assumeBits<61>(wordCount + other.wordCount); + capCount += other.capCount; + return *this; + } + + void addWords(WordCountN<61, uint64_t> other) { + wordCount = assumeBits<61>(wordCount + other); + } + + MessageSize asPublic() { + return MessageSize { unbound(wordCount / WORDS), capCount }; + } +}; + +// ============================================================================= + +template +union AlignedData { + // Useful for declaring static constant data blobs as an array of bytes, but forcing those + // bytes to be word-aligned. + + uint8_t bytes[wordCount * sizeof(word)]; + word words[wordCount]; +}; + +struct StructSize { + StructDataWordCount data; + StructPointerCount pointers; + + inline constexpr WordCountN<17> total() const { return data + pointers * WORDS_PER_POINTER; } + + StructSize() = default; + inline constexpr StructSize(StructDataWordCount data, StructPointerCount pointers) + : data(data), pointers(pointers) {} +}; + +template +inline constexpr StructSize structSize() { + return StructSize(bounded(CapnpPrivate::dataWordSize) * WORDS, + bounded(CapnpPrivate::pointerCount) * POINTERS); +} + +template > +inline constexpr StructSize minStructSizeForElement() { + // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough + // to hold a T. + + return StructSize(bounded(CapnpPrivate::dataWordSize) * WORDS, + bounded(CapnpPrivate::pointerCount) * POINTERS); +} + +template > +inline constexpr StructSize minStructSizeForElement() { + // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough + // to hold a T. + + return StructSize( + dataBitsPerElement(elementSizeForType()) * ELEMENTS > ZERO * BITS + ? StructDataWordCount(ONE * WORDS) : StructDataWordCount(ZERO * WORDS), + pointersPerElement(elementSizeForType()) * ELEMENTS); +} + +// ------------------------------------------------------------------- +// Masking of default values + +template struct Mask_; +template struct Mask_ { typedef T Type; }; +template struct Mask_ { typedef uint16_t Type; }; +template <> struct Mask_ { typedef uint32_t Type; }; +template <> struct Mask_ { typedef uint64_t Type; }; + +template struct Mask_ { + // Union discriminants end up here. + static_assert(sizeof(T) == 2, "Don't know how to mask this type."); + typedef uint16_t Type; +}; + +template +using Mask = typename Mask_::Type; + +template +KJ_ALWAYS_INLINE(Mask mask(T value, Mask mask)); +template +KJ_ALWAYS_INLINE(T unmask(Mask value, Mask mask)); + +template +inline Mask mask(T value, Mask mask) { + return static_cast >(value) ^ mask; +} + +template <> +inline uint32_t mask(float value, uint32_t mask) { +#if CAPNP_CANONICALIZE_NAN + if (value != value) { + return 0x7fc00000u ^ mask; + } +#endif + + uint32_t i; + static_assert(sizeof(i) == sizeof(value), "float is not 32 bits?"); + memcpy(&i, &value, sizeof(value)); + return i ^ mask; +} + +template <> +inline uint64_t mask(double value, uint64_t mask) { +#if CAPNP_CANONICALIZE_NAN + if (value != value) { + return 0x7ff8000000000000ull ^ mask; + } +#endif + + uint64_t i; + static_assert(sizeof(i) == sizeof(value), "double is not 64 bits?"); + memcpy(&i, &value, sizeof(value)); + return i ^ mask; +} + +template +inline T unmask(Mask value, Mask mask) { + return static_cast(value ^ mask); +} + +template <> +inline float unmask(uint32_t value, uint32_t mask) { + value ^= mask; + float result; + static_assert(sizeof(result) == sizeof(value), "float is not 32 bits?"); + memcpy(&result, &value, sizeof(value)); + return result; +} + +template <> +inline double unmask(uint64_t value, uint64_t mask) { + value ^= mask; + double result; + static_assert(sizeof(result) == sizeof(value), "double is not 64 bits?"); + memcpy(&result, &value, sizeof(value)); + return result; +} + +// ------------------------------------------------------------------- + +class CapTableReader { +public: +#if !CAPNP_LITE + virtual kj::Maybe> extractCap(uint index) = 0; + // Extract the capability at the given index. If the index is invalid, returns null. +#endif // !CAPNP_LITE +}; + +class CapTableBuilder: public CapTableReader { +public: +#if !CAPNP_LITE + virtual uint injectCap(kj::Own&& cap) = 0; + // Add the capability to the message and return its index. If the same ClientHook is injected + // twice, this may return the same index both times, but in this case dropCap() needs to be + // called an equal number of times to actually remove the cap. + + virtual void dropCap(uint index) = 0; + // Remove a capability injected earlier. Called when the pointer is overwritten or zero'd out. +#endif // !CAPNP_LITE +}; + +// ------------------------------------------------------------------- + +class PointerBuilder: public kj::DisallowConstCopy { + // Represents a single pointer, usually embedded in a struct or a list. + +public: + inline PointerBuilder(): segment(nullptr), capTable(nullptr), pointer(nullptr) {} + + static inline PointerBuilder getRoot( + SegmentBuilder* segment, CapTableBuilder* capTable, word* location); + // Get a PointerBuilder representing a message root located in the given segment at the given + // location. + + inline bool isNull() { return getPointerType() == PointerType::NULL_; } + PointerType getPointerType() const; + + StructBuilder getStruct(StructSize size, const word* defaultValue); + ListBuilder getList(ElementSize elementSize, const word* defaultValue); + ListBuilder getStructList(StructSize elementSize, const word* defaultValue); + ListBuilder getListAnySize(const word* defaultValue); + template typename T::Builder getBlob( + const void* defaultValue, ByteCount defaultSize); +#if !CAPNP_LITE + kj::Own getCapability(); +#endif // !CAPNP_LITE + // Get methods: Get the value. If it is null, initialize it to a copy of the default value. + // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a + // simple byte array for blobs. + + StructBuilder initStruct(StructSize size); + ListBuilder initList(ElementSize elementSize, ElementCount elementCount); + ListBuilder initStructList(ElementCount elementCount, StructSize size); + template typename T::Builder initBlob(ByteCount size); + // Init methods: Initialize the pointer to a newly-allocated object, discarding the existing + // object. + + void setStruct(const StructReader& value, bool canonical = false); + void setList(const ListReader& value, bool canonical = false); + template void setBlob(typename T::Reader value); +#if !CAPNP_LITE + void setCapability(kj::Own&& cap); +#endif // !CAPNP_LITE + // Set methods: Initialize the pointer to a newly-allocated copy of the given value, discarding + // the existing object. + + void adopt(OrphanBuilder&& orphan); + // Set the pointer to point at the given orphaned value. + + OrphanBuilder disown(); + // Set the pointer to null and return its previous value as an orphan. + + void clear(); + // Clear the pointer to null, discarding its previous value. + + void transferFrom(PointerBuilder other); + // Equivalent to `adopt(other.disown())`. + + void copyFrom(PointerReader other, bool canonical = false); + // Equivalent to `set(other.get())`. + // If you set the canonical flag, it will attempt to lay the target out + // canonically, provided enough space is available. + + PointerReader asReader() const; + + BuilderArena* getArena() const; + // Get the arena containing this pointer. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + PointerBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the pointer resides. + CapTableBuilder* capTable; // Table of capability indexes. + WirePointer* pointer; // Pointer to the pointer. + + inline PointerBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* pointer) + : segment(segment), capTable(capTable), pointer(pointer) {} + + friend class StructBuilder; + friend class ListBuilder; + friend class OrphanBuilder; +}; + +class PointerReader { +public: + inline PointerReader() + : segment(nullptr), capTable(nullptr), pointer(nullptr), nestingLimit(0x7fffffff) {} + + static PointerReader getRoot(SegmentReader* segment, CapTableReader* capTable, + const word* location, int nestingLimit); + // Get a PointerReader representing a message root located in the given segment at the given + // location. + + static inline PointerReader getRootUnchecked(const word* location); + // Get a PointerReader for an unchecked message. + + MessageSizeCounts targetSize() const; + // Return the total size of the target object and everything to which it points. Does not count + // far pointer overhead. This is useful for deciding how much space is needed to copy the object + // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, + // use the result as a hint for allocating the first segment, do the copy, and then throw an + // exception if it overruns. + + inline bool isNull() const { return getPointerType() == PointerType::NULL_; } + PointerType getPointerType() const; + + StructReader getStruct(const word* defaultValue) const; + ListReader getList(ElementSize expectedElementSize, const word* defaultValue) const; + ListReader getListAnySize(const word* defaultValue) const; + template + typename T::Reader getBlob(const void* defaultValue, ByteCount defaultSize) const; +#if !CAPNP_LITE + kj::Own getCapability() const; +#endif // !CAPNP_LITE + // Get methods: Get the value. If it is null, return the default value instead. + // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a + // simple byte array for blobs. + + const word* getUnchecked() const; + // If this is an unchecked message, get a word* pointing at the location of the pointer. This + // word* can actually be passed to readUnchecked() to read the designated sub-object later. If + // this isn't an unchecked message, throws an exception. + + kj::Maybe getArena() const; + // Get the arena containing this pointer. + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + PointerReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + +private: + SegmentReader* segment; // Memory segment in which the pointer resides. + CapTableReader* capTable; // Table of capability indexes. + const WirePointer* pointer; // Pointer to the pointer. null = treat as null pointer. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + + inline PointerReader(SegmentReader* segment, CapTableReader* capTable, + const WirePointer* pointer, int nestingLimit) + : segment(segment), capTable(capTable), pointer(pointer), nestingLimit(nestingLimit) {} + + friend class StructReader; + friend class ListReader; + friend class PointerBuilder; + friend class OrphanBuilder; +}; + +// ------------------------------------------------------------------- + +class StructBuilder: public kj::DisallowConstCopy { +public: + inline StructBuilder(): segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr) {} + + inline word* getLocation() { return reinterpret_cast(data); } + // Get the object's location. Only valid for independently-allocated objects (i.e. not list + // elements). + + inline StructDataBitCount getDataSectionSize() const { return dataSize; } + inline StructPointerCount getPointerSectionSize() const { return pointerCount; } + inline kj::ArrayPtr getDataSectionAsBlob(); + inline _::ListBuilder getPointerSectionAsList(); + + template + KJ_ALWAYS_INLINE(bool hasDataField(StructDataOffset offset)); + // Return true if the field is set to something other than its default value. + + template + KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset)); + // Gets the data field value of the given type at the given offset. The offset is measured in + // multiples of the field size, determined by the type. + + template + KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset, Mask mask)); + // Like getDataField() but applies the given XOR mask to the data on load. Used for reading + // fields with non-zero default values. + + template + KJ_ALWAYS_INLINE(void setDataField(StructDataOffset offset, kj::NoInfer value)); + // Sets the data field value at the given offset. + + template + KJ_ALWAYS_INLINE(void setDataField(StructDataOffset offset, + kj::NoInfer value, Mask mask)); + // Like setDataField() but applies the given XOR mask before storing. Used for writing fields + // with non-zero default values. + + KJ_ALWAYS_INLINE(PointerBuilder getPointerField(StructPointerOffset ptrIndex)); + // Get a builder for a pointer field given the index within the pointer section. + + void clearAll(); + // Clear all pointers and data. + + void transferContentFrom(StructBuilder other); + // Adopt all pointers from `other`, and also copy all data. If `other`'s sections are larger + // than this, the extra data is not transferred, meaning there is a risk of data loss when + // transferring from messages built with future versions of the protocol. + + void copyContentFrom(StructReader other); + // Copy content from `other`. If `other`'s sections are larger than this, the extra data is not + // copied, meaning there is a risk of data loss when copying from messages built with future + // versions of the protocol. + + StructReader asReader() const; + // Gets a StructReader pointing at the same memory. + + BuilderArena* getArena(); + // Gets the arena in which this object is allocated. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + StructBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the struct resides. + CapTableBuilder* capTable; // Table of capability indexes. + void* data; // Pointer to the encoded data. + WirePointer* pointers; // Pointer to the encoded pointers. + + StructDataBitCount dataSize; + // Size of data section. We use a bit count rather than a word count to more easily handle the + // case of struct lists encoded with less than a word per element. + + StructPointerCount pointerCount; // Size of the pointer section. + + inline StructBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, + void* data, WirePointer* pointers, + StructDataBitCount dataSize, StructPointerCount pointerCount) + : segment(segment), capTable(capTable), data(data), pointers(pointers), + dataSize(dataSize), pointerCount(pointerCount) {} + + friend class ListBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +class StructReader { +public: + inline StructReader() + : segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr), + dataSize(ZERO * BITS), pointerCount(ZERO * POINTERS), nestingLimit(0x7fffffff) {} + inline StructReader(kj::ArrayPtr data) + : segment(nullptr), capTable(nullptr), data(data.begin()), pointers(nullptr), + dataSize(assumeBits(data.size()) * WORDS * BITS_PER_WORD), + pointerCount(ZERO * POINTERS), nestingLimit(0x7fffffff) {} + + const void* getLocation() const { return data; } + + inline StructDataBitCount getDataSectionSize() const { return dataSize; } + inline StructPointerCount getPointerSectionSize() const { return pointerCount; } + inline kj::ArrayPtr getDataSectionAsBlob(); + inline _::ListReader getPointerSectionAsList(); + + kj::Array canonicalize(); + + template + KJ_ALWAYS_INLINE(bool hasDataField(StructDataOffset offset) const); + // Return true if the field is set to something other than its default value. + + template + KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset) const); + // Get the data field value of the given type at the given offset. The offset is measured in + // multiples of the field size, determined by the type. Returns zero if the offset is past the + // end of the struct's data section. + + template + KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset, Mask mask) const); + // Like getDataField(offset), but applies the given XOR mask to the result. Used for reading + // fields with non-zero default values. + + KJ_ALWAYS_INLINE(PointerReader getPointerField(StructPointerOffset ptrIndex) const); + // Get a reader for a pointer field given the index within the pointer section. If the index + // is out-of-bounds, returns a null pointer. + + MessageSizeCounts totalSize() const; + // Return the total size of the struct and everything to which it points. Does not count far + // pointer overhead. This is useful for deciding how much space is needed to copy the struct + // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, + // use the result as a hint for allocating the first segment, do the copy, and then throw an + // exception if it overruns. + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + StructReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead, const word **ptrHead, + bool *dataTrunc, bool *ptrTrunc); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + // + // If this function returns false, the struct is non-canonical. If it + // returns true, then: + // * If it is a composite in a list, it is canonical if at least one struct + // in the list outputs dataTrunc = 1, and at least one outputs ptrTrunc = 1 + // * If it is derived from a struct pointer, it is canonical if + // dataTrunc = 1 AND ptrTrunc = 1 + +private: + SegmentReader* segment; // Memory segment in which the struct resides. + CapTableReader* capTable; // Table of capability indexes. + + const void* data; + const WirePointer* pointers; + + StructDataBitCount dataSize; + // Size of data section. We use a bit count rather than a word count to more easily handle the + // case of struct lists encoded with less than a word per element. + + StructPointerCount pointerCount; // Size of the pointer section. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + // TODO(perf): Limit to 16 bits for better packing? + + inline StructReader(SegmentReader* segment, CapTableReader* capTable, + const void* data, const WirePointer* pointers, + StructDataBitCount dataSize, StructPointerCount pointerCount, + int nestingLimit) + : segment(segment), capTable(capTable), data(data), pointers(pointers), + dataSize(dataSize), pointerCount(pointerCount), + nestingLimit(nestingLimit) {} + + friend class ListReader; + friend class StructBuilder; + friend struct WireHelpers; +}; + +// ------------------------------------------------------------------- + +class ListBuilder: public kj::DisallowConstCopy { +public: + inline explicit ListBuilder(ElementSize elementSize) + : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(ZERO * ELEMENTS), + step(ZERO * BITS / ELEMENTS), structDataSize(ZERO * BITS), + structPointerCount(ZERO * POINTERS), elementSize(elementSize) {} + + inline word* getLocation() { + // Get the object's location. + + if (elementSize == ElementSize::INLINE_COMPOSITE && ptr != nullptr) { + return reinterpret_cast(ptr) - POINTER_SIZE_IN_WORDS; + } else { + return reinterpret_cast(ptr); + } + } + + inline ElementSize getElementSize() const { return elementSize; } + + inline ListElementCount size() const; + // The number of elements in the list. + + Text::Builder asText(); + Data::Builder asData(); + // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. + + template + KJ_ALWAYS_INLINE(T getDataElement(ElementCount index)); + // Get the element of the given type at the given index. + + template + KJ_ALWAYS_INLINE(void setDataElement(ElementCount index, kj::NoInfer value)); + // Set the element at the given index. + + KJ_ALWAYS_INLINE(PointerBuilder getPointerElement(ElementCount index)); + + StructBuilder getStructElement(ElementCount index); + + ListReader asReader() const; + // Get a ListReader pointing at the same memory. + + BuilderArena* getArena(); + // Gets the arena in which this object is allocated. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + ListBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the list resides. + CapTableBuilder* capTable; // Table of capability indexes. + + byte* ptr; // Pointer to list content. + + ListElementCount elementCount; // Number of elements in the list. + + BitsPerElementN<23> step; + // The distance between elements. The maximum value occurs when a struct contains 2^16-1 data + // words and 2^16-1 pointers, i.e. 2^17 - 2 words, or 2^23 - 128 bits. + + StructDataBitCount structDataSize; + StructPointerCount structPointerCount; + // The struct properties to use when interpreting the elements as structs. All lists can be + // interpreted as struct lists, so these are always filled in. + + ElementSize elementSize; + // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE + // from other types when the overall size is exactly zero or one words. + + inline ListBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, void* ptr, + BitsPerElementN<23> step, ListElementCount size, + StructDataBitCount structDataSize, StructPointerCount structPointerCount, + ElementSize elementSize) + : segment(segment), capTable(capTable), ptr(reinterpret_cast(ptr)), + elementCount(size), step(step), structDataSize(structDataSize), + structPointerCount(structPointerCount), elementSize(elementSize) {} + + friend class StructBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +class ListReader { +public: + inline explicit ListReader(ElementSize elementSize) + : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(ZERO * ELEMENTS), + step(ZERO * BITS / ELEMENTS), structDataSize(ZERO * BITS), + structPointerCount(ZERO * POINTERS), elementSize(elementSize), nestingLimit(0x7fffffff) {} + + inline ListElementCount size() const; + // The number of elements in the list. + + inline ElementSize getElementSize() const { return elementSize; } + + Text::Reader asText(); + Data::Reader asData(); + // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. + + kj::ArrayPtr asRawBytes(); + + template + KJ_ALWAYS_INLINE(T getDataElement(ElementCount index) const); + // Get the element of the given type at the given index. + + KJ_ALWAYS_INLINE(PointerReader getPointerElement(ElementCount index) const); + + StructReader getStructElement(ElementCount index) const; + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + ListReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead, const WirePointer* ref); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + +private: + SegmentReader* segment; // Memory segment in which the list resides. + CapTableReader* capTable; // Table of capability indexes. + + const byte* ptr; // Pointer to list content. + + ListElementCount elementCount; // Number of elements in the list. + + BitsPerElementN<23> step; + // The distance between elements. The maximum value occurs when a struct contains 2^16-1 data + // words and 2^16-1 pointers, i.e. 2^17 - 2 words, or 2^23 - 2 bits. + + StructDataBitCount structDataSize; + StructPointerCount structPointerCount; + // The struct properties to use when interpreting the elements as structs. All lists can be + // interpreted as struct lists, so these are always filled in. + + ElementSize elementSize; + // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE + // from other types when the overall size is exactly zero or one words. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + + inline ListReader(SegmentReader* segment, CapTableReader* capTable, const void* ptr, + ListElementCount elementCount, BitsPerElementN<23> step, + StructDataBitCount structDataSize, StructPointerCount structPointerCount, + ElementSize elementSize, int nestingLimit) + : segment(segment), capTable(capTable), ptr(reinterpret_cast(ptr)), + elementCount(elementCount), step(step), structDataSize(structDataSize), + structPointerCount(structPointerCount), elementSize(elementSize), + nestingLimit(nestingLimit) {} + + friend class StructReader; + friend class ListBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +// ------------------------------------------------------------------- + +class OrphanBuilder { +public: + inline OrphanBuilder(): segment(nullptr), capTable(nullptr), location(nullptr) { + memset(&tag, 0, sizeof(tag)); + } + OrphanBuilder(const OrphanBuilder& other) = delete; + inline OrphanBuilder(OrphanBuilder&& other) noexcept; + inline ~OrphanBuilder() noexcept(false); + + static OrphanBuilder initStruct(BuilderArena* arena, CapTableBuilder* capTable, StructSize size); + static OrphanBuilder initList(BuilderArena* arena, CapTableBuilder* capTable, + ElementCount elementCount, ElementSize elementSize); + static OrphanBuilder initStructList(BuilderArena* arena, CapTableBuilder* capTable, + ElementCount elementCount, StructSize elementSize); + static OrphanBuilder initText(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); + static OrphanBuilder initData(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); + + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, StructReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, ListReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, PointerReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Text::Reader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Data::Reader copyFrom); +#if !CAPNP_LITE + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, + kj::Own copyFrom); +#endif // !CAPNP_LITE + + static OrphanBuilder concat(BuilderArena* arena, CapTableBuilder* capTable, + ElementSize expectedElementSize, StructSize expectedStructSize, + kj::ArrayPtr lists); + + static OrphanBuilder referenceExternalData(BuilderArena* arena, Data::Reader data); + + OrphanBuilder& operator=(const OrphanBuilder& other) = delete; + inline OrphanBuilder& operator=(OrphanBuilder&& other); + + inline bool operator==(decltype(nullptr)) const { return location == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return location != nullptr; } + + StructBuilder asStruct(StructSize size); + // Interpret as a struct, or throw an exception if not a struct. + + ListBuilder asList(ElementSize elementSize); + // Interpret as a list, or throw an exception if not a list. elementSize cannot be + // INLINE_COMPOSITE -- use asStructList() instead. + + ListBuilder asStructList(StructSize elementSize); + // Interpret as a struct list, or throw an exception if not a list. + + ListBuilder asListAnySize(); + // For AnyList. + + Text::Builder asText(); + Data::Builder asData(); + // Interpret as a blob, or throw an exception if not a blob. + + StructReader asStructReader(StructSize size) const; + ListReader asListReader(ElementSize elementSize) const; + ListReader asListReaderAnySize() const; +#if !CAPNP_LITE + kj::Own asCapability() const; +#endif // !CAPNP_LITE + Text::Reader asTextReader() const; + Data::Reader asDataReader() const; + + bool truncate(ElementCount size, bool isText) KJ_WARN_UNUSED_RESULT; + // Resize the orphan list to the given size. Returns false if the list is currently empty but + // the requested size is non-zero, in which case the caller will need to allocate a new list. + + void truncate(ElementCount size, ElementSize elementSize); + void truncate(ElementCount size, StructSize elementSize); + void truncateText(ElementCount size); + // Versions of truncate() that know how to allocate a new list if needed. + +private: + static_assert(ONE * POINTERS * WORDS_PER_POINTER == ONE * WORDS, + "This struct assumes a pointer is one word."); + word tag; + // Contains an encoded WirePointer representing this object. WirePointer is defined in + // layout.c++, but fits in a word. + // + // This may be a FAR pointer. Even in that case, `location` points to the eventual destination + // of that far pointer. The reason we keep the far pointer around rather than just making `tag` + // represent the final destination is because if the eventual adopter of the pointer is not in + // the target's segment then it may be useful to reuse the far pointer landing pad. + // + // If `tag` is not a far pointer, its offset is garbage; only `location` points to the actual + // target. + + SegmentBuilder* segment; + // Segment in which the object resides. + + CapTableBuilder* capTable; + // Table of capability indexes. + + word* location; + // Pointer to the object, or nullptr if the pointer is null. For capabilities, we make this + // 0x1 just so that it is non-null for operator==, but it is never used. + + inline OrphanBuilder(const void* tagPtr, SegmentBuilder* segment, + CapTableBuilder* capTable, word* location) + : segment(segment), capTable(capTable), location(location) { + memcpy(&tag, tagPtr, sizeof(tag)); + } + + inline WirePointer* tagAsPtr() { return reinterpret_cast(&tag); } + inline const WirePointer* tagAsPtr() const { return reinterpret_cast(&tag); } + + void euthanize(); + // Erase the target object, zeroing it out and possibly reclaiming the memory. Called when + // the OrphanBuilder is being destroyed or overwritten and it is non-null. + + friend struct WireHelpers; +}; + +// ======================================================================================= +// Internal implementation details... + +// These are defined in the source file. +template <> typename Text::Builder PointerBuilder::initBlob(ByteCount size); +template <> void PointerBuilder::setBlob(typename Text::Reader value); +template <> typename Text::Builder PointerBuilder::getBlob( + const void* defaultValue, ByteCount defaultSize); +template <> typename Text::Reader PointerReader::getBlob( + const void* defaultValue, ByteCount defaultSize) const; + +template <> typename Data::Builder PointerBuilder::initBlob(ByteCount size); +template <> void PointerBuilder::setBlob(typename Data::Reader value); +template <> typename Data::Builder PointerBuilder::getBlob( + const void* defaultValue, ByteCount defaultSize); +template <> typename Data::Reader PointerReader::getBlob( + const void* defaultValue, ByteCount defaultSize) const; + +inline PointerBuilder PointerBuilder::getRoot( + SegmentBuilder* segment, CapTableBuilder* capTable, word* location) { + return PointerBuilder(segment, capTable, reinterpret_cast(location)); +} + +inline PointerReader PointerReader::getRootUnchecked(const word* location) { + return PointerReader(nullptr, nullptr, + reinterpret_cast(location), 0x7fffffff); +} + +// ------------------------------------------------------------------- + +inline kj::ArrayPtr StructBuilder::getDataSectionAsBlob() { + return kj::ArrayPtr(reinterpret_cast(data), + unbound(dataSize / BITS_PER_BYTE / BYTES)); +} + +inline _::ListBuilder StructBuilder::getPointerSectionAsList() { + return _::ListBuilder(segment, capTable, pointers, ONE * POINTERS * BITS_PER_POINTER / ELEMENTS, + pointerCount * (ONE * ELEMENTS / POINTERS), + ZERO * BITS, ONE * POINTERS, ElementSize::POINTER); +} + +template +inline bool StructBuilder::hasDataField(StructDataOffset offset) { + return getDataField>(offset) != 0; +} + +template <> +inline bool StructBuilder::hasDataField(StructDataOffset offset) { + return false; +} + +template +inline T StructBuilder::getDataField(StructDataOffset offset) { + return reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].get(); +} + +template <> +inline bool StructBuilder::getDataField(StructDataOffset offset) { + BitCount32 boffset = offset * (ONE * BITS / ELEMENTS); + byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; + return (*reinterpret_cast(b) & + unbound(ONE << (boffset % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void StructBuilder::getDataField(StructDataOffset offset) { + return VOID; +} + +template +inline T StructBuilder::getDataField(StructDataOffset offset, Mask mask) { + return unmask(getDataField >(offset), mask); +} + +template +inline void StructBuilder::setDataField(StructDataOffset offset, kj::NoInfer value) { + reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].set(value); +} + +#if CAPNP_CANONICALIZE_NAN +// Use mask() on floats and doubles to make sure we canonicalize NaNs. +template <> +inline void StructBuilder::setDataField(StructDataOffset offset, float value) { + setDataField(offset, mask(value, 0)); +} +template <> +inline void StructBuilder::setDataField(StructDataOffset offset, double value) { + setDataField(offset, mask(value, 0)); +} +#endif + +template <> +inline void StructBuilder::setDataField(StructDataOffset offset, bool value) { + auto boffset = offset * (ONE * BITS / ELEMENTS); + byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; + uint bitnum = unboundMaxBits<3>(boffset % BITS_PER_BYTE / BITS); + *reinterpret_cast(b) = (*reinterpret_cast(b) & ~(1 << bitnum)) + | (static_cast(value) << bitnum); +} + +template <> +inline void StructBuilder::setDataField(StructDataOffset offset, Void value) {} + +template +inline void StructBuilder::setDataField(StructDataOffset offset, + kj::NoInfer value, Mask m) { + setDataField >(offset, mask(value, m)); +} + +inline PointerBuilder StructBuilder::getPointerField(StructPointerOffset ptrIndex) { + // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). + return PointerBuilder(segment, capTable, reinterpret_cast( + reinterpret_cast(pointers) + ptrIndex * WORDS_PER_POINTER)); +} + +// ------------------------------------------------------------------- + +inline kj::ArrayPtr StructReader::getDataSectionAsBlob() { + return kj::ArrayPtr(reinterpret_cast(data), + unbound(dataSize / BITS_PER_BYTE / BYTES)); +} + +inline _::ListReader StructReader::getPointerSectionAsList() { + return _::ListReader(segment, capTable, pointers, pointerCount * (ONE * ELEMENTS / POINTERS), + ONE * POINTERS * BITS_PER_POINTER / ELEMENTS, ZERO * BITS, ONE * POINTERS, + ElementSize::POINTER, nestingLimit); +} + +template +inline bool StructReader::hasDataField(StructDataOffset offset) const { + return getDataField>(offset) != 0; +} + +template <> +inline bool StructReader::hasDataField(StructDataOffset offset) const { + return false; +} + +template +inline T StructReader::getDataField(StructDataOffset offset) const { + if ((offset + ONE * ELEMENTS) * capnp::bitsPerElement() <= dataSize) { + return reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].get(); + } else { + return static_cast(0); + } +} + +template <> +inline bool StructReader::getDataField(StructDataOffset offset) const { + auto boffset = offset * (ONE * BITS / ELEMENTS); + if (boffset < dataSize) { + const byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; + return (*reinterpret_cast(b) & + unbound(ONE << (boffset % BITS_PER_BYTE / BITS))) != 0; + } else { + return false; + } +} + +template <> +inline Void StructReader::getDataField(StructDataOffset offset) const { + return VOID; +} + +template +T StructReader::getDataField(StructDataOffset offset, Mask mask) const { + return unmask(getDataField >(offset), mask); +} + +inline PointerReader StructReader::getPointerField(StructPointerOffset ptrIndex) const { + if (ptrIndex < pointerCount) { + // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). + return PointerReader(segment, capTable, reinterpret_cast( + reinterpret_cast(pointers) + ptrIndex * WORDS_PER_POINTER), nestingLimit); + } else{ + return PointerReader(); + } +} + +// ------------------------------------------------------------------- + +inline ListElementCount ListBuilder::size() const { return elementCount; } + +template +inline T ListBuilder::getDataElement(ElementCount index) { + return reinterpret_cast*>( + ptr + upgradeBound(index) * step / BITS_PER_BYTE)->get(); + + // TODO(perf): Benchmark this alternate implementation, which I suspect may make better use of + // the x86 SIB byte. Also use it for all the other getData/setData implementations below, and + // the various non-inline methods that look up pointers. + // Also if using this, consider changing ptr back to void* instead of byte*. +// return reinterpret_cast*>(ptr)[ +// index / ELEMENTS * (step / capnp::bitsPerElement())].get(); +} + +template <> +inline bool ListBuilder::getDataElement(ElementCount index) { + // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. + auto bindex = index * (ONE * BITS / ELEMENTS); + byte* b = ptr + bindex / BITS_PER_BYTE; + return (*reinterpret_cast(b) & + unbound(ONE << (bindex % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void ListBuilder::getDataElement(ElementCount index) { + return VOID; +} + +template +inline void ListBuilder::setDataElement(ElementCount index, kj::NoInfer value) { + reinterpret_cast*>( + ptr + upgradeBound(index) * step / BITS_PER_BYTE)->set(value); +} + +#if CAPNP_CANONICALIZE_NAN +// Use mask() on floats and doubles to make sure we canonicalize NaNs. +template <> +inline void ListBuilder::setDataElement(ElementCount index, float value) { + setDataElement(index, mask(value, 0)); +} +template <> +inline void ListBuilder::setDataElement(ElementCount index, double value) { + setDataElement(index, mask(value, 0)); +} +#endif + +template <> +inline void ListBuilder::setDataElement(ElementCount index, bool value) { + // Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists. + auto bindex = index * (ONE * BITS / ELEMENTS); + byte* b = ptr + bindex / BITS_PER_BYTE; + auto bitnum = bindex % BITS_PER_BYTE / BITS; + *reinterpret_cast(b) = (*reinterpret_cast(b) & ~(1 << unbound(bitnum))) + | (static_cast(value) << unbound(bitnum)); +} + +template <> +inline void ListBuilder::setDataElement(ElementCount index, Void value) {} + +inline PointerBuilder ListBuilder::getPointerElement(ElementCount index) { + return PointerBuilder(segment, capTable, reinterpret_cast(ptr + + upgradeBound(index) * step / BITS_PER_BYTE)); +} + +// ------------------------------------------------------------------- + +inline ListElementCount ListReader::size() const { return elementCount; } + +template +inline T ListReader::getDataElement(ElementCount index) const { + return reinterpret_cast*>( + ptr + upgradeBound(index) * step / BITS_PER_BYTE)->get(); +} + +template <> +inline bool ListReader::getDataElement(ElementCount index) const { + // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. + auto bindex = index * (ONE * BITS / ELEMENTS); + const byte* b = ptr + bindex / BITS_PER_BYTE; + return (*reinterpret_cast(b) & + unbound(ONE << (bindex % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void ListReader::getDataElement(ElementCount index) const { + return VOID; +} + +inline PointerReader ListReader::getPointerElement(ElementCount index) const { + return PointerReader(segment, capTable, reinterpret_cast( + ptr + upgradeBound(index) * step / BITS_PER_BYTE), nestingLimit); +} + +// ------------------------------------------------------------------- + +inline OrphanBuilder::OrphanBuilder(OrphanBuilder&& other) noexcept + : segment(other.segment), capTable(other.capTable), location(other.location) { + memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. + other.segment = nullptr; + other.location = nullptr; +} + +inline OrphanBuilder::~OrphanBuilder() noexcept(false) { + if (segment != nullptr) euthanize(); +} + +inline OrphanBuilder& OrphanBuilder::operator=(OrphanBuilder&& other) { + // With normal smart pointers, it's important to handle the case where the incoming pointer + // is actually transitively owned by this one. In this case, euthanize() would destroy `other` + // before we copied it. This isn't possible in the case of `OrphanBuilder` because it only + // owns message objects, and `other` is not itself a message object, therefore cannot possibly + // be transitively owned by `this`. + + if (segment != nullptr) euthanize(); + segment = other.segment; + capTable = other.capTable; + location = other.location; + memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. + other.segment = nullptr; + other.location = nullptr; + return *this; +} + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_LAYOUT_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/list.h --- a/win32-mingw/include/capnp/list.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/list.h Tue May 23 09:16:54 2017 +0100 @@ -1,543 +1,546 @@ -// 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. - -#ifndef CAPNP_LIST_H_ -#define CAPNP_LIST_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" -#include "orphan.h" -#include -#ifdef KJ_STD_COMPAT -#include -#endif // KJ_STD_COMPAT - -namespace capnp { -namespace _ { // private - -template -class TemporaryPointer { - // This class is a little hack which lets us define operator->() in cases where it needs to - // return a pointer to a temporary value. We instead construct a TemporaryPointer and return that - // (by value). The compiler then invokes operator->() on the TemporaryPointer, which itself is - // able to return a real pointer to its member. - -public: - TemporaryPointer(T&& value): value(kj::mv(value)) {} - TemporaryPointer(const T& value): value(value) {} - - inline T* operator->() { return &value; } -private: - T value; -}; - -template -class IndexingIterator { -public: - IndexingIterator() = default; - - inline Element operator*() const { return (*container)[index]; } - inline TemporaryPointer operator->() const { - return TemporaryPointer((*container)[index]); - } - inline Element operator[]( int off) const { return (*container)[index]; } - inline Element operator[](uint off) const { return (*container)[index]; } - - inline IndexingIterator& operator++() { ++index; return *this; } - inline IndexingIterator operator++(int) { IndexingIterator other = *this; ++index; return other; } - inline IndexingIterator& operator--() { --index; return *this; } - inline IndexingIterator operator--(int) { IndexingIterator other = *this; --index; return other; } - - inline IndexingIterator operator+(uint amount) const { return IndexingIterator(container, index + amount); } - inline IndexingIterator operator-(uint amount) const { return IndexingIterator(container, index - amount); } - inline IndexingIterator operator+( int amount) const { return IndexingIterator(container, index + amount); } - inline IndexingIterator operator-( int amount) const { return IndexingIterator(container, index - amount); } - - inline int operator-(const IndexingIterator& other) const { return index - other.index; } - - inline IndexingIterator& operator+=(uint amount) { index += amount; return *this; } - inline IndexingIterator& operator-=(uint amount) { index -= amount; return *this; } - inline IndexingIterator& operator+=( int amount) { index += amount; return *this; } - inline IndexingIterator& operator-=( int amount) { index -= amount; return *this; } - - // STL says comparing iterators of different containers is not allowed, so we only compare - // indices here. - inline bool operator==(const IndexingIterator& other) const { return index == other.index; } - inline bool operator!=(const IndexingIterator& other) const { return index != other.index; } - inline bool operator<=(const IndexingIterator& other) const { return index <= other.index; } - inline bool operator>=(const IndexingIterator& other) const { return index >= other.index; } - inline bool operator< (const IndexingIterator& other) const { return index < other.index; } - inline bool operator> (const IndexingIterator& other) const { return index > other.index; } - -private: - Container* container; - uint index; - - friend Container; - inline IndexingIterator(Container* container, uint index) - : container(container), index(index) {} -}; - -} // namespace _ (private) - -template -struct List { - // List of primitives. - - List() = delete; - - class Reader { - public: - typedef List Reads; - - inline Reader(): reader(_::elementSizeForType()) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return reader.size() / ELEMENTS; } - inline T operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return reader.template getDataElement(index * ELEMENTS); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - inline Builder(): builder(_::elementSizeForType()) {} - inline Builder(decltype(nullptr)) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return builder.size() / ELEMENTS; } - inline T operator[](uint index) { - KJ_IREQUIRE(index < size()); - return builder.template getDataElement(index * ELEMENTS); - } - inline void set(uint index, T value) { - // Alas, it is not possible to make operator[] return a reference to which you can assign, - // since the encoded representation does not necessarily match the compiler's representation - // of the type. We can't even return a clever class that implements operator T() and - // operator=() because it will lead to surprising behavior when using type inference (e.g. - // calling a template function with inferred argument types, or using "auto" or "decltype"). - - builder.template setDataElement(index * ELEMENTS, value); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Pipeline {}; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initList(_::elementSizeForType(), size * ELEMENTS); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getList(_::elementSizeForType(), defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(_::elementSizeForType(), defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -template -struct List: public List {}; - -template -struct List { - // List of structs. - - List() = delete; - - class Reader { - public: - typedef List Reads; - - inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return reader.size() / ELEMENTS; } - inline typename T::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return typename T::Reader(reader.getStructElement(index * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - inline Builder(): builder(ElementSize::INLINE_COMPOSITE) {} - inline Builder(decltype(nullptr)) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return builder.size() / ELEMENTS; } - inline typename T::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return typename T::Builder(builder.getStructElement(index * ELEMENTS)); - } - - inline void adoptWithCaveats(uint index, Orphan&& orphan) { - // Mostly behaves like you'd expect `adopt` to behave, but with two caveats originating from - // the fact that structs in a struct list are allocated inline rather than by pointer: - // * This actually performs a shallow copy, effectively adopting each of the orphan's - // children rather than adopting the orphan itself. The orphan ends up being discarded, - // possibly wasting space in the message object. - // * If the orphan is larger than the target struct -- say, because the orphan was built - // using a newer version of the schema that has additional fields -- it will be truncated, - // losing data. - - KJ_IREQUIRE(index < size()); - - // We pass a zero-valued StructSize to asStruct() because we do not want the struct to be - // expanded under any circumstances. We're just going to throw it away anyway, and - // transferContentFrom() already carefully compares the struct sizes before transferring. - builder.getStructElement(index * ELEMENTS).transferContentFrom( - orphan.builder.asStruct(_::StructSize(0 * WORDS, 0 * POINTERS))); - } - inline void setWithCaveats(uint index, const typename T::Reader& reader) { - // Mostly behaves like you'd expect `set` to behave, but with a caveat originating from - // the fact that structs in a struct list are allocated inline rather than by pointer: - // If the source struct is larger than the target struct -- say, because the source was built - // using a newer version of the schema that has additional fields -- it will be truncated, - // losing data. - // - // Note: If you are trying to concatenate some lists, use Orphanage::newOrphanConcat() to - // do it without losing any data in case the source lists come from a newer version of the - // protocol. (Plus, it's easier to use anyhow.) - - KJ_IREQUIRE(index < size()); - builder.getStructElement(index * ELEMENTS).copyContentFrom(reader._reader); - } - - // There are no init(), set(), adopt(), or disown() methods for lists of structs because the - // elements of the list are inlined and are initialized when the list is initialized. This - // means that init() would be redundant, and set() would risk data loss if the input struct - // were from a newer version of the protocol. - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Pipeline {}; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initStructList(size * ELEMENTS, _::structSize()); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getStructList(_::structSize(), defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(ElementSize::INLINE_COMPOSITE, defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -template -struct List, Kind::LIST> { - // List of lists. - - List() = delete; - - class Reader { - public: - typedef List> Reads; - - inline Reader(): reader(ElementSize::POINTER) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return reader.size() / ELEMENTS; } - inline typename List::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return typename List::Reader( - _::PointerHelpers>::get(reader.getPointerElement(index * ELEMENTS))); - } - - typedef _::IndexingIterator::Reader> Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List> Builds; - - inline Builder(): builder(ElementSize::POINTER) {} - inline Builder(decltype(nullptr)) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return builder.size() / ELEMENTS; } - inline typename List::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return typename List::Builder( - _::PointerHelpers>::get(builder.getPointerElement(index * ELEMENTS))); - } - inline typename List::Builder init(uint index, uint size) { - KJ_IREQUIRE(index < this->size()); - return typename List::Builder( - _::PointerHelpers>::init(builder.getPointerElement(index * ELEMENTS), size)); - } - inline void set(uint index, typename List::Reader value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(index * ELEMENTS).setList(value.reader); - } - void set(uint index, std::initializer_list> value) { - KJ_IREQUIRE(index < size()); - auto l = init(index, value.size()); - uint i = 0; - for (auto& element: value) { - l.set(i++, element); - } - } - inline void adopt(uint index, Orphan&& value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(index * ELEMENTS).adopt(kj::mv(value.builder)); - } - inline Orphan disown(uint index) { - KJ_IREQUIRE(index < size()); - return Orphan(builder.getPointerElement(index * ELEMENTS).disown()); - } - - typedef _::IndexingIterator::Builder> Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Pipeline {}; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initList(ElementSize::POINTER, size * ELEMENTS); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getList(ElementSize::POINTER, defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(ElementSize::POINTER, defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -template -struct List { - List() = delete; - - class Reader { - public: - typedef List Reads; - - inline Reader(): reader(ElementSize::POINTER) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return reader.size() / ELEMENTS; } - inline typename T::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return reader.getPointerElement(index * ELEMENTS).template getBlob(nullptr, 0 * BYTES); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - inline Builder(): builder(ElementSize::POINTER) {} - inline Builder(decltype(nullptr)) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return builder.size() / ELEMENTS; } - inline typename T::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return builder.getPointerElement(index * ELEMENTS).template getBlob(nullptr, 0 * BYTES); - } - inline void set(uint index, typename T::Reader value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(index * ELEMENTS).template setBlob(value); - } - inline typename T::Builder init(uint index, uint size) { - KJ_IREQUIRE(index < this->size()); - return builder.getPointerElement(index * ELEMENTS).template initBlob(size * BYTES); - } - inline void adopt(uint index, Orphan&& value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(index * ELEMENTS).adopt(kj::mv(value.builder)); - } - inline Orphan disown(uint index) { - KJ_IREQUIRE(index < size()); - return Orphan(builder.getPointerElement(index * ELEMENTS).disown()); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Pipeline {}; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initList(ElementSize::POINTER, size * ELEMENTS); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getList(ElementSize::POINTER, defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(ElementSize::POINTER, defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -} // namespace capnp - -#ifdef KJ_STD_COMPAT -namespace std { - -template -struct iterator_traits> - : public std::iterator {}; - -} // namespace std -#endif // KJ_STD_COMPAT - -#endif // CAPNP_LIST_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. + +#ifndef CAPNP_LIST_H_ +#define CAPNP_LIST_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" +#include "orphan.h" +#include +#ifdef KJ_STD_COMPAT +#include +#endif // KJ_STD_COMPAT + +namespace capnp { +namespace _ { // private + +template +class TemporaryPointer { + // This class is a little hack which lets us define operator->() in cases where it needs to + // return a pointer to a temporary value. We instead construct a TemporaryPointer and return that + // (by value). The compiler then invokes operator->() on the TemporaryPointer, which itself is + // able to return a real pointer to its member. + +public: + TemporaryPointer(T&& value): value(kj::mv(value)) {} + TemporaryPointer(const T& value): value(value) {} + + inline T* operator->() { return &value; } +private: + T value; +}; + +template +class IndexingIterator { +public: + IndexingIterator() = default; + + inline Element operator*() const { return (*container)[index]; } + inline TemporaryPointer operator->() const { + return TemporaryPointer((*container)[index]); + } + inline Element operator[]( int off) const { return (*container)[index]; } + inline Element operator[](uint off) const { return (*container)[index]; } + + inline IndexingIterator& operator++() { ++index; return *this; } + inline IndexingIterator operator++(int) { IndexingIterator other = *this; ++index; return other; } + inline IndexingIterator& operator--() { --index; return *this; } + inline IndexingIterator operator--(int) { IndexingIterator other = *this; --index; return other; } + + inline IndexingIterator operator+(uint amount) const { return IndexingIterator(container, index + amount); } + inline IndexingIterator operator-(uint amount) const { return IndexingIterator(container, index - amount); } + inline IndexingIterator operator+( int amount) const { return IndexingIterator(container, index + amount); } + inline IndexingIterator operator-( int amount) const { return IndexingIterator(container, index - amount); } + + inline int operator-(const IndexingIterator& other) const { return index - other.index; } + + inline IndexingIterator& operator+=(uint amount) { index += amount; return *this; } + inline IndexingIterator& operator-=(uint amount) { index -= amount; return *this; } + inline IndexingIterator& operator+=( int amount) { index += amount; return *this; } + inline IndexingIterator& operator-=( int amount) { index -= amount; return *this; } + + // STL says comparing iterators of different containers is not allowed, so we only compare + // indices here. + inline bool operator==(const IndexingIterator& other) const { return index == other.index; } + inline bool operator!=(const IndexingIterator& other) const { return index != other.index; } + inline bool operator<=(const IndexingIterator& other) const { return index <= other.index; } + inline bool operator>=(const IndexingIterator& other) const { return index >= other.index; } + inline bool operator< (const IndexingIterator& other) const { return index < other.index; } + inline bool operator> (const IndexingIterator& other) const { return index > other.index; } + +private: + Container* container; + uint index; + + friend Container; + inline IndexingIterator(Container* container, uint index) + : container(container), index(index) {} +}; + +} // namespace _ (private) + +template +struct List { + // List of primitives. + + List() = delete; + + class Reader { + public: + typedef List Reads; + + inline Reader(): reader(_::elementSizeForType()) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline T operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return reader.template getDataElement(bounded(index) * ELEMENTS); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + inline Builder(): builder(_::elementSizeForType()) {} + inline Builder(decltype(nullptr)): Builder() {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline T operator[](uint index) { + KJ_IREQUIRE(index < size()); + return builder.template getDataElement(bounded(index) * ELEMENTS); + } + inline void set(uint index, T value) { + // Alas, it is not possible to make operator[] return a reference to which you can assign, + // since the encoded representation does not necessarily match the compiler's representation + // of the type. We can't even return a clever class that implements operator T() and + // operator=() because it will lead to surprising behavior when using type inference (e.g. + // calling a template function with inferred argument types, or using "auto" or "decltype"). + + builder.template setDataElement(bounded(index) * ELEMENTS, value); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(_::elementSizeForType(), bounded(size) * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(_::elementSizeForType(), defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(_::elementSizeForType(), defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +template +struct List: public List {}; + +template +struct List { + // List of structs. + + List() = delete; + + class Reader { + public: + typedef List Reads; + + inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline typename T::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename T::Reader(reader.getStructElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + inline Builder(): builder(ElementSize::INLINE_COMPOSITE) {} + inline Builder(decltype(nullptr)): Builder() {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline typename T::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename T::Builder(builder.getStructElement(bounded(index) * ELEMENTS)); + } + + inline void adoptWithCaveats(uint index, Orphan&& orphan) { + // Mostly behaves like you'd expect `adopt` to behave, but with two caveats originating from + // the fact that structs in a struct list are allocated inline rather than by pointer: + // * This actually performs a shallow copy, effectively adopting each of the orphan's + // children rather than adopting the orphan itself. The orphan ends up being discarded, + // possibly wasting space in the message object. + // * If the orphan is larger than the target struct -- say, because the orphan was built + // using a newer version of the schema that has additional fields -- it will be truncated, + // losing data. + + KJ_IREQUIRE(index < size()); + + // We pass a zero-valued StructSize to asStruct() because we do not want the struct to be + // expanded under any circumstances. We're just going to throw it away anyway, and + // transferContentFrom() already carefully compares the struct sizes before transferring. + builder.getStructElement(bounded(index) * ELEMENTS).transferContentFrom( + orphan.builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); + } + inline void setWithCaveats(uint index, const typename T::Reader& reader) { + // Mostly behaves like you'd expect `set` to behave, but with a caveat originating from + // the fact that structs in a struct list are allocated inline rather than by pointer: + // If the source struct is larger than the target struct -- say, because the source was built + // using a newer version of the schema that has additional fields -- it will be truncated, + // losing data. + // + // Note: If you are trying to concatenate some lists, use Orphanage::newOrphanConcat() to + // do it without losing any data in case the source lists come from a newer version of the + // protocol. (Plus, it's easier to use anyhow.) + + KJ_IREQUIRE(index < size()); + builder.getStructElement(bounded(index) * ELEMENTS).copyContentFrom(reader._reader); + } + + // There are no init(), set(), adopt(), or disown() methods for lists of structs because the + // elements of the list are inlined and are initialized when the list is initialized. This + // means that init() would be redundant, and set() would risk data loss if the input struct + // were from a newer version of the protocol. + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initStructList(bounded(size) * ELEMENTS, _::structSize()); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getStructList(_::structSize(), defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::INLINE_COMPOSITE, defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +template +struct List, Kind::LIST> { + // List of lists. + + List() = delete; + + class Reader { + public: + typedef List> Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline typename List::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename List::Reader(_::PointerHelpers>::get( + reader.getPointerElement(bounded(index) * ELEMENTS))); + } + + typedef _::IndexingIterator::Reader> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List> Builds; + + inline Builder(): builder(ElementSize::POINTER) {} + inline Builder(decltype(nullptr)): Builder() {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline typename List::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename List::Builder(_::PointerHelpers>::get( + builder.getPointerElement(bounded(index) * ELEMENTS))); + } + inline typename List::Builder init(uint index, uint size) { + KJ_IREQUIRE(index < this->size()); + return typename List::Builder(_::PointerHelpers>::init( + builder.getPointerElement(bounded(index) * ELEMENTS), size)); + } + inline void set(uint index, typename List::Reader value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).setList(value.reader); + } + void set(uint index, std::initializer_list> value) { + KJ_IREQUIRE(index < size()); + auto l = init(index, value.size()); + uint i = 0; + for (auto& element: value) { + l.set(i++, element); + } + } + inline void adopt(uint index, Orphan&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value.builder)); + } + inline Orphan disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); + } + + typedef _::IndexingIterator::Builder> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +template +struct List { + List() = delete; + + class Reader { + public: + typedef List Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline typename T::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return reader.getPointerElement(bounded(index) * ELEMENTS) + .template getBlob(nullptr, ZERO * BYTES); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + inline Builder(): builder(ElementSize::POINTER) {} + inline Builder(decltype(nullptr)): Builder() {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline typename T::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return builder.getPointerElement(bounded(index) * ELEMENTS) + .template getBlob(nullptr, ZERO * BYTES); + } + inline void set(uint index, typename T::Reader value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).template setBlob(value); + } + inline typename T::Builder init(uint index, uint size) { + KJ_IREQUIRE(index < this->size()); + return builder.getPointerElement(bounded(index) * ELEMENTS) + .template initBlob(bounded(size) * BYTES); + } + inline void adopt(uint index, Orphan&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value.builder)); + } + inline Orphan disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +} // namespace capnp + +#ifdef KJ_STD_COMPAT +namespace std { + +template +struct iterator_traits> + : public std::iterator {}; + +} // namespace std +#endif // KJ_STD_COMPAT + +#endif // CAPNP_LIST_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/membrane.h --- a/win32-mingw/include/capnp/membrane.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/membrane.h Tue May 23 09:16:54 2017 +0100 @@ -1,202 +1,202 @@ -// Copyright (c) 2015 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. - -#ifndef CAPNP_MEMBRANE_H_ -#define CAPNP_MEMBRANE_H_ -// In capability theory, a "membrane" is a wrapper around a capability which (usually) forwards -// calls but recursively wraps capabilities in those calls in the same membrane. The purpose of a -// membrane is to enforce a barrier between two capabilities that cannot be bypassed by merely -// introducing new objects. -// -// The most common use case for a membrane is revocation: Say Alice wants to give Bob a capability -// to access Carol, but wants to be able to revoke this capability later. Alice can accomplish this -// by wrapping Carol in a revokable wrapper which passes through calls until such a time as Alice -// indicates it should be revoked, after which all calls through the wrapper will throw exceptions. -// However, a naive wrapper approach has a problem: if Bob makes a call to Carol and sends a new -// capability in that call, or if Carol returns a capability to Bob in the response to a call, then -// the two are now able to communicate using this new capability, which Alice cannot revoke. In -// order to avoid this problem, Alice must use not just a wrapper but a "membrane", which -// recursively wraps all objects that pass through it in either direction. Thus, all connections -// formed between Bob and Carol (originating from Alice's original introduction) can be revoked -// together by revoking the membrane. -// -// Note that when a capability is passed into a membrane and then passed back out, the result is -// the original capability, not a double-membraned capability. This means that in our revocation -// example, if Bob uses his capability to Carol to obtain another capability from her, then send -// it back to her, the capability Carol receives back will NOT be revoked when Bob's access to -// Carol is revoked. Thus Bob can create long-term irrevocable connections. In most practical use -// cases, this is what you want. APIs commonly rely on the fact that a capability obtained and then -// passed back can be recognized as the original capability. -// -// Mark Miller on membranes: http://www.eros-os.org/pipermail/e-lang/2003-January/008434.html - -#include "capability.h" - -namespace capnp { - -class MembranePolicy { - // Applications may implement this interface to define a membrane policy, which allows some - // calls crossing the membrane to be blocked or redirected. - -public: - virtual kj::Maybe inboundCall( - uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; - // Given an inbound call (a call originating "outside" the membrane destined for an object - // "inside" the membrane), decides what to do with it. The policy may: - // - // - Return null to indicate that the call should proceed to the destination. All capabilities - // in the parameters or result will be properly wrapped in the same membrane. - // - Return a capability to have the call redirected to that capability. Note that the redirect - // capability will be treated as outside the membrane, so the params and results will not be - // auto-wrapped; however, the callee can easily wrap the returned capability in the membrane - // itself before returning to achieve this effect. - // - Throw an exception to cause the call to fail with that exception. - // - // `target` is the underlying capability (*inside* the membrane) for which the call is destined. - // Generally, the only way you should use `target` is to wrap it in some capability which you - // return as a redirect. The redirect capability may modify the call in some way and send it to - // `target`. Be careful to use `copyIntoMembrane()` and `copyOutOfMembrane()` as appropriate when - // copying parameters or results across the membrane. - // - // Note that since `target` is inside the capability, if you were to directly return it (rather - // than return null), the effect would be that the membrane would be broken: the call would - // proceed directly and any new capabilities introduced through it would not be membraned. You - // generally should not do that. - - virtual kj::Maybe outboundCall( - uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; - // Like `inboundCall()`, but applies to calls originating *inside* the membrane and terminating - // outside. - // - // Note: It is strongly recommended that `outboundCall()` returns null in exactly the same cases - // that `inboundCall()` return null. Conversely, for any case where `inboundCall()` would - // redirect or throw, `outboundCall()` should also redirect or throw. Otherwise, you can run - // into inconsistent behavion when a promise is returned across a membrane, and that promise - // later resolves to a capability on the other side of the membrane: calls on the promise - // will enter and then exit the membrane, but calls on the eventual resolution will not cross - // the membrane at all, so it is important that these two cases behave the same. - - virtual kj::Own addRef() = 0; - // Return a new owned pointer to the same policy. - // - // Typically an implementation of MembranePolicy should also inherit kj::Refcounted and implement - // `addRef()` as `return kj::addRef(*this);`. - // - // Note that the membraning system considers two membranes created with the same MembranePolicy - // object actually to be the *same* membrane. This is relevant when an object passes into the - // membrane and then back out (or out and then back in): instead of double-wrapping the object, - // the wrapping will be removed. -}; - -Capability::Client membrane(Capability::Client inner, kj::Own policy); -// Wrap `inner` in a membrane specified by `policy`. `inner` is considered "inside" the membrane, -// while the returned capability should only be called from outside the membrane. - -Capability::Client reverseMembrane(Capability::Client outer, kj::Own policy); -// Like `membrane` but treat the input capability as "outside" the membrane, and return a -// capability appropriate for use inside. -// -// Applications typically won't use this directly; the membraning code automatically sets up -// reverse membranes where needed. - -template -ClientType membrane(ClientType inner, kj::Own policy); -template -ClientType reverseMembrane(ClientType inner, kj::Own policy); -// Convenience templates which return the same interface type as the input. - -template -typename ServerType::Serves::Client membrane( - kj::Own inner, kj::Own policy); -template -typename ServerType::Serves::Client reverseMembrane( - kj::Own inner, kj::Own policy); -// Convenience templates which input a capability server type and return the appropriate client -// type. - -template -Orphan::Reads> copyIntoMembrane( - Reader&& from, Orphanage to, kj::Own policy); -// Copy a Cap'n Proto object (e.g. struct or list), adding the given membrane to any capabilities -// found within it. `from` is interpreted as "outside" the membrane while `to` is "inside". - -template -Orphan::Reads> copyOutOfMembrane( - Reader&& from, Orphanage to, kj::Own policy); -// Like copyIntoMembrane() except that `from` is "inside" the membrane and `to` is "outside". - -// ======================================================================================= -// inline implementation details - -template -ClientType membrane(ClientType inner, kj::Own policy) { - return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) - .castAs(); -} -template -ClientType reverseMembrane(ClientType inner, kj::Own policy) { - return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) - .castAs(); -} - -template -typename ServerType::Serves::Client membrane( - kj::Own inner, kj::Own policy) { - return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) - .castAs(); -} -template -typename ServerType::Serves::Client reverseMembrane( - kj::Own inner, kj::Own policy) { - return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) - .castAs(); -} - -namespace _ { // private - -OrphanBuilder copyOutOfMembrane(PointerReader from, Orphanage to, - kj::Own policy, bool reverse); -OrphanBuilder copyOutOfMembrane(StructReader from, Orphanage to, - kj::Own policy, bool reverse); -OrphanBuilder copyOutOfMembrane(ListReader from, Orphanage to, - kj::Own policy, bool reverse); - -} // namespace _ (private) - -template -Orphan::Reads> copyIntoMembrane( - Reader&& from, Orphanage to, kj::Own policy) { - return _::copyOutOfMembrane( - _::PointerHelpers::Reads>::getInternalReader(from), - to, kj::mv(policy), true); -} - -template -Orphan::Reads> copyOutOfMembrane( - Reader&& from, Orphanage to, kj::Own policy) { - return _::copyOutOfMembrane( - _::PointerHelpers::Reads>::getInternalReader(from), - to, kj::mv(policy), false); -} - -} // namespace capnp - -#endif // CAPNP_MEMBRANE_H_ +// Copyright (c) 2015 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. + +#ifndef CAPNP_MEMBRANE_H_ +#define CAPNP_MEMBRANE_H_ +// In capability theory, a "membrane" is a wrapper around a capability which (usually) forwards +// calls but recursively wraps capabilities in those calls in the same membrane. The purpose of a +// membrane is to enforce a barrier between two capabilities that cannot be bypassed by merely +// introducing new objects. +// +// The most common use case for a membrane is revocation: Say Alice wants to give Bob a capability +// to access Carol, but wants to be able to revoke this capability later. Alice can accomplish this +// by wrapping Carol in a revokable wrapper which passes through calls until such a time as Alice +// indicates it should be revoked, after which all calls through the wrapper will throw exceptions. +// However, a naive wrapper approach has a problem: if Bob makes a call to Carol and sends a new +// capability in that call, or if Carol returns a capability to Bob in the response to a call, then +// the two are now able to communicate using this new capability, which Alice cannot revoke. In +// order to avoid this problem, Alice must use not just a wrapper but a "membrane", which +// recursively wraps all objects that pass through it in either direction. Thus, all connections +// formed between Bob and Carol (originating from Alice's original introduction) can be revoked +// together by revoking the membrane. +// +// Note that when a capability is passed into a membrane and then passed back out, the result is +// the original capability, not a double-membraned capability. This means that in our revocation +// example, if Bob uses his capability to Carol to obtain another capability from her, then send +// it back to her, the capability Carol receives back will NOT be revoked when Bob's access to +// Carol is revoked. Thus Bob can create long-term irrevocable connections. In most practical use +// cases, this is what you want. APIs commonly rely on the fact that a capability obtained and then +// passed back can be recognized as the original capability. +// +// Mark Miller on membranes: http://www.eros-os.org/pipermail/e-lang/2003-January/008434.html + +#include "capability.h" + +namespace capnp { + +class MembranePolicy { + // Applications may implement this interface to define a membrane policy, which allows some + // calls crossing the membrane to be blocked or redirected. + +public: + virtual kj::Maybe inboundCall( + uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; + // Given an inbound call (a call originating "outside" the membrane destined for an object + // "inside" the membrane), decides what to do with it. The policy may: + // + // - Return null to indicate that the call should proceed to the destination. All capabilities + // in the parameters or result will be properly wrapped in the same membrane. + // - Return a capability to have the call redirected to that capability. Note that the redirect + // capability will be treated as outside the membrane, so the params and results will not be + // auto-wrapped; however, the callee can easily wrap the returned capability in the membrane + // itself before returning to achieve this effect. + // - Throw an exception to cause the call to fail with that exception. + // + // `target` is the underlying capability (*inside* the membrane) for which the call is destined. + // Generally, the only way you should use `target` is to wrap it in some capability which you + // return as a redirect. The redirect capability may modify the call in some way and send it to + // `target`. Be careful to use `copyIntoMembrane()` and `copyOutOfMembrane()` as appropriate when + // copying parameters or results across the membrane. + // + // Note that since `target` is inside the capability, if you were to directly return it (rather + // than return null), the effect would be that the membrane would be broken: the call would + // proceed directly and any new capabilities introduced through it would not be membraned. You + // generally should not do that. + + virtual kj::Maybe outboundCall( + uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; + // Like `inboundCall()`, but applies to calls originating *inside* the membrane and terminating + // outside. + // + // Note: It is strongly recommended that `outboundCall()` returns null in exactly the same cases + // that `inboundCall()` return null. Conversely, for any case where `inboundCall()` would + // redirect or throw, `outboundCall()` should also redirect or throw. Otherwise, you can run + // into inconsistent behavion when a promise is returned across a membrane, and that promise + // later resolves to a capability on the other side of the membrane: calls on the promise + // will enter and then exit the membrane, but calls on the eventual resolution will not cross + // the membrane at all, so it is important that these two cases behave the same. + + virtual kj::Own addRef() = 0; + // Return a new owned pointer to the same policy. + // + // Typically an implementation of MembranePolicy should also inherit kj::Refcounted and implement + // `addRef()` as `return kj::addRef(*this);`. + // + // Note that the membraning system considers two membranes created with the same MembranePolicy + // object actually to be the *same* membrane. This is relevant when an object passes into the + // membrane and then back out (or out and then back in): instead of double-wrapping the object, + // the wrapping will be removed. +}; + +Capability::Client membrane(Capability::Client inner, kj::Own policy); +// Wrap `inner` in a membrane specified by `policy`. `inner` is considered "inside" the membrane, +// while the returned capability should only be called from outside the membrane. + +Capability::Client reverseMembrane(Capability::Client outer, kj::Own policy); +// Like `membrane` but treat the input capability as "outside" the membrane, and return a +// capability appropriate for use inside. +// +// Applications typically won't use this directly; the membraning code automatically sets up +// reverse membranes where needed. + +template +ClientType membrane(ClientType inner, kj::Own policy); +template +ClientType reverseMembrane(ClientType inner, kj::Own policy); +// Convenience templates which return the same interface type as the input. + +template +typename ServerType::Serves::Client membrane( + kj::Own inner, kj::Own policy); +template +typename ServerType::Serves::Client reverseMembrane( + kj::Own inner, kj::Own policy); +// Convenience templates which input a capability server type and return the appropriate client +// type. + +template +Orphan::Reads> copyIntoMembrane( + Reader&& from, Orphanage to, kj::Own policy); +// Copy a Cap'n Proto object (e.g. struct or list), adding the given membrane to any capabilities +// found within it. `from` is interpreted as "outside" the membrane while `to` is "inside". + +template +Orphan::Reads> copyOutOfMembrane( + Reader&& from, Orphanage to, kj::Own policy); +// Like copyIntoMembrane() except that `from` is "inside" the membrane and `to` is "outside". + +// ======================================================================================= +// inline implementation details + +template +ClientType membrane(ClientType inner, kj::Own policy) { + return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs(); +} +template +ClientType reverseMembrane(ClientType inner, kj::Own policy) { + return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs(); +} + +template +typename ServerType::Serves::Client membrane( + kj::Own inner, kj::Own policy) { + return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs(); +} +template +typename ServerType::Serves::Client reverseMembrane( + kj::Own inner, kj::Own policy) { + return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs(); +} + +namespace _ { // private + +OrphanBuilder copyOutOfMembrane(PointerReader from, Orphanage to, + kj::Own policy, bool reverse); +OrphanBuilder copyOutOfMembrane(StructReader from, Orphanage to, + kj::Own policy, bool reverse); +OrphanBuilder copyOutOfMembrane(ListReader from, Orphanage to, + kj::Own policy, bool reverse); + +} // namespace _ (private) + +template +Orphan::Reads> copyIntoMembrane( + Reader&& from, Orphanage to, kj::Own policy) { + return _::copyOutOfMembrane( + _::PointerHelpers::Reads>::getInternalReader(from), + to, kj::mv(policy), true); +} + +template +Orphan::Reads> copyOutOfMembrane( + Reader&& from, Orphanage to, kj::Own policy) { + return _::copyOutOfMembrane( + _::PointerHelpers::Reads>::getInternalReader(from), + to, kj::mv(policy), false); +} + +} // namespace capnp + +#endif // CAPNP_MEMBRANE_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/message.h --- a/win32-mingw/include/capnp/message.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/message.h Tue May 23 09:16:54 2017 +0100 @@ -1,508 +1,508 @@ -// Copyright (c) 2013-2016 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. - -#include -#include -#include -#include -#include "common.h" -#include "layout.h" -#include "any.h" - -#ifndef CAPNP_MESSAGE_H_ -#define CAPNP_MESSAGE_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -namespace capnp { - -namespace _ { // private - class ReaderArena; - class BuilderArena; -} - -class StructSchema; -class Orphanage; -template -class Orphan; - -// ======================================================================================= - -struct ReaderOptions { - // Options controlling how data is read. - - uint64_t traversalLimitInWords = 8 * 1024 * 1024; - // Limits how many total words of data are allowed to be traversed. Traversal is counted when - // a new struct or list builder is obtained, e.g. from a get() accessor. This means that calling - // the getter for the same sub-struct multiple times will cause it to be double-counted. Once - // the traversal limit is reached, an error will be reported. - // - // This limit exists for security reasons. It is possible for an attacker to construct a message - // in which multiple pointers point at the same location. This is technically invalid, but hard - // to detect. Using such a message, an attacker could cause a message which is small on the wire - // to appear much larger when actually traversed, possibly exhausting server resources leading to - // denial-of-service. - // - // It makes sense to set a traversal limit that is much larger than the underlying message. - // Together with sensible coding practices (e.g. trying to avoid calling sub-object getters - // multiple times, which is expensive anyway), this should provide adequate protection without - // inconvenience. - // - // The default limit is 64 MiB. This may or may not be a sensible number for any given use case, - // but probably at least prevents easy exploitation while also avoiding causing problems in most - // typical cases. - - int nestingLimit = 64; - // Limits how deeply-nested a message structure can be, e.g. structs containing other structs or - // lists of structs. - // - // Like the traversal limit, this limit exists for security reasons. Since it is common to use - // recursive code to traverse recursive data structures, an attacker could easily cause a stack - // overflow by sending a very-deeply-nested (or even cyclic) message, without the message even - // being very large. The default limit of 64 is probably low enough to prevent any chance of - // stack overflow, yet high enough that it is never a problem in practice. -}; - -class MessageReader { - // Abstract interface for an object used to read a Cap'n Proto message. Subclasses of - // MessageReader are responsible for reading the raw, flat message content. Callers should - // usually call `messageReader.getRoot()` to get a `MyStructType::Reader` - // representing the root of the message, then use that to traverse the message content. - // - // Some common subclasses of `MessageReader` include `SegmentArrayMessageReader`, whose - // constructor accepts pointers to the raw data, and `StreamFdMessageReader` (from - // `serialize.h`), which reads the message from a file descriptor. One might implement other - // subclasses to handle things like reading from shared memory segments, mmap()ed files, etc. - -public: - MessageReader(ReaderOptions options); - // It is suggested that subclasses take ReaderOptions as a constructor parameter, but give it a - // default value of "ReaderOptions()". The base class constructor doesn't have a default value - // in order to remind subclasses that they really need to give the user a way to provide this. - - virtual ~MessageReader() noexcept(false); - - virtual kj::ArrayPtr getSegment(uint id) = 0; - // Gets the segment with the given ID, or returns null if no such segment exists. This method - // will be called at most once for each segment ID. - - inline const ReaderOptions& getOptions(); - // Get the options passed to the constructor. - - template - typename RootType::Reader getRoot(); - // Get the root struct of the message, interpreting it as the given struct type. - - template - typename RootType::Reader getRoot(SchemaType schema); - // Dynamically interpret the root struct of the message using the given schema (a StructSchema). - // RootType in this case must be DynamicStruct, and you must #include to - // use this. - - bool isCanonical(); - // Returns whether the message encoded in the reader is in canonical form. - -private: - ReaderOptions options; - - // Space in which we can construct a ReaderArena. We don't use ReaderArena directly here - // because we don't want clients to have to #include arena.h, which itself includes a bunch of - // big STL headers. We don't use a pointer to a ReaderArena because that would require an - // extra malloc on every message which could be expensive when processing small messages. - void* arenaSpace[15 + sizeof(kj::MutexGuarded) / sizeof(void*)]; - bool allocatedArena; - - _::ReaderArena* arena() { return reinterpret_cast<_::ReaderArena*>(arenaSpace); } - AnyPointer::Reader getRootInternal(); -}; - -class MessageBuilder { - // Abstract interface for an object used to allocate and build a message. Subclasses of - // MessageBuilder are responsible for allocating the space in which the message will be written. - // The most common subclass is `MallocMessageBuilder`, but other subclasses may be used to do - // tricky things like allocate messages in shared memory or mmap()ed files. - // - // Creating a new message ususually means allocating a new MessageBuilder (ideally on the stack) - // and then calling `messageBuilder.initRoot()` to get a `MyStructType::Builder`. - // That, in turn, can be used to fill in the message content. When done, you can call - // `messageBuilder.getSegmentsForOutput()` to get a list of flat data arrays containing the - // message. - -public: - MessageBuilder(); - virtual ~MessageBuilder() noexcept(false); - KJ_DISALLOW_COPY(MessageBuilder); - - struct SegmentInit { - kj::ArrayPtr space; - - size_t wordsUsed; - // Number of words in `space` which are used; the rest are free space in which additional - // objects may be allocated. - }; - - explicit MessageBuilder(kj::ArrayPtr segments); - // Create a MessageBuilder backed by existing memory. This is an advanced interface that most - // people should not use. THIS METHOD IS INSECURE; see below. - // - // This allows a MessageBuilder to be constructed to modify an in-memory message without first - // making a copy of the content. This is especially useful in conjunction with mmap(). - // - // The contents of each segment must outlive the MessageBuilder, but the SegmentInit array itself - // only need outlive the constructor. - // - // SECURITY: Do not use this in conjunction with untrusted data. This constructor assumes that - // the input message is valid. This constructor is designed to be used with data you control, - // e.g. an mmap'd file which is owned and accessed by only one program. When reading data you - // do not trust, you *must* load it into a Reader and then copy into a Builder as a means of - // validating the content. - // - // WARNING: It is NOT safe to initialize a MessageBuilder in this way from memory that is - // currently in use by another MessageBuilder or MessageReader. Other readers/builders will - // not observe changes to the segment sizes nor newly-allocated segments caused by allocating - // new objects in this message. - - virtual kj::ArrayPtr allocateSegment(uint minimumSize) = 0; - // Allocates an array of at least the given number of words, throwing an exception or crashing if - // this is not possible. It is expected that this method will usually return more space than - // requested, and the caller should use that extra space as much as possible before allocating - // more. The returned space remains valid at least until the MessageBuilder is destroyed. - // - // Cap'n Proto will only call this once at a time, so the subclass need not worry about - // thread-safety. - - template - typename RootType::Builder initRoot(); - // Initialize the root struct of the message as the given struct type. - - template - void setRoot(Reader&& value); - // Set the root struct to a deep copy of the given struct. - - template - typename RootType::Builder getRoot(); - // Get the root struct of the message, interpreting it as the given struct type. - - template - typename RootType::Builder getRoot(SchemaType schema); - // Dynamically interpret the root struct of the message using the given schema (a StructSchema). - // RootType in this case must be DynamicStruct, and you must #include to - // use this. - - template - typename RootType::Builder initRoot(SchemaType schema); - // Dynamically init the root struct of the message using the given schema (a StructSchema). - // RootType in this case must be DynamicStruct, and you must #include to - // use this. - - template - void adoptRoot(Orphan&& orphan); - // Like setRoot() but adopts the orphan without copying. - - kj::ArrayPtr> getSegmentsForOutput(); - // Get the raw data that makes up the message. - - Orphanage getOrphanage(); - - bool isCanonical(); - // Check whether the message builder is in canonical form - -private: - void* arenaSpace[22]; - // Space in which we can construct a BuilderArena. We don't use BuilderArena directly here - // because we don't want clients to have to #include arena.h, which itself includes a bunch of - // big STL headers. We don't use a pointer to a BuilderArena because that would require an - // extra malloc on every message which could be expensive when processing small messages. - - bool allocatedArena = false; - // We have to initialize the arena lazily because when we do so we want to allocate the root - // pointer immediately, and this will allocate a segment, which requires a virtual function - // call on the MessageBuilder. We can't do such a call in the constructor since the subclass - // isn't constructed yet. This is kind of annoying because it means that getOrphanage() is - // not thread-safe, but that shouldn't be a huge deal... - - _::BuilderArena* arena() { return reinterpret_cast<_::BuilderArena*>(arenaSpace); } - _::SegmentBuilder* getRootSegment(); - AnyPointer::Builder getRootInternal(); -}; - -template -typename RootType::Reader readMessageUnchecked(const word* data); -// IF THE INPUT IS INVALID, THIS MAY CRASH, CORRUPT MEMORY, CREATE A SECURITY HOLE IN YOUR APP, -// MURDER YOUR FIRST-BORN CHILD, AND/OR BRING ABOUT ETERNAL DAMNATION ON ALL OF HUMANITY. DO NOT -// USE UNLESS YOU UNDERSTAND THE CONSEQUENCES. -// -// Given a pointer to a known-valid message located in a single contiguous memory segment, -// returns a reader for that message. No bounds-checking will be done while traversing this -// message. Use this only if you have already verified that all pointers are valid and in-bounds, -// and there are no far pointers in the message. -// -// To create a message that can be passed to this function, build a message using a MallocAllocator -// whose preferred segment size is larger than the message size. This guarantees that the message -// will be allocated as a single segment, meaning getSegmentsForOutput() returns a single word -// array. That word array is your message; you may pass a pointer to its first word into -// readMessageUnchecked() to read the message. -// -// This can be particularly handy for embedding messages in generated code: you can -// embed the raw bytes (using AlignedData) then make a Reader for it using this. This is the way -// default values are embedded in code generated by the Cap'n Proto compiler. E.g., if you have -// a message MyMessage, you can read its default value like so: -// MyMessage::Reader reader = Message::readMessageUnchecked(MyMessage::DEFAULT.words); -// -// To sanitize a message from an untrusted source such that it can be safely passed to -// readMessageUnchecked(), use copyToUnchecked(). - -template -void copyToUnchecked(Reader&& reader, kj::ArrayPtr uncheckedBuffer); -// Copy the content of the given reader into the given buffer, such that it can safely be passed to -// readMessageUnchecked(). The buffer's size must be exactly reader.totalSizeInWords() + 1, -// otherwise an exception will be thrown. The buffer must be zero'd before calling. - -template -typename RootType::Reader readDataStruct(kj::ArrayPtr data); -// Interprets the given data as a single, data-only struct. Only primitive fields (booleans, -// numbers, and enums) will be readable; all pointers will be null. This is useful if you want -// to use Cap'n Proto as a language/platform-neutral way to pack some bits. -// -// The input is a word array rather than a byte array to enforce alignment. If you have a byte -// array which you know is word-aligned (or if your platform supports unaligned reads and you don't -// mind the performance penalty), then you can use `reinterpret_cast` to convert a byte array into -// a word array: -// -// kj::arrayPtr(reinterpret_cast(bytes.begin()), -// reinterpret_cast(bytes.end())) - -template -typename kj::ArrayPtr writeDataStruct(BuilderType builder); -// Given a struct builder, get the underlying data section as a word array, suitable for passing -// to `readDataStruct()`. -// -// Note that you may call `.toBytes()` on the returned value to convert to `ArrayPtr`. - -template -static typename Type::Reader defaultValue(); -// Get a default instance of the given struct or list type. -// -// TODO(cleanup): Find a better home for this function? - -// ======================================================================================= - -class SegmentArrayMessageReader: public MessageReader { - // A simple MessageReader that reads from an array of word arrays representing all segments. - // In particular you can read directly from the output of MessageBuilder::getSegmentsForOutput() - // (although it would probably make more sense to call builder.getRoot().asReader() in that case). - -public: - SegmentArrayMessageReader(kj::ArrayPtr> segments, - ReaderOptions options = ReaderOptions()); - // Creates a message pointing at the given segment array, without taking ownership of the - // segments. All arrays passed in must remain valid until the MessageReader is destroyed. - - KJ_DISALLOW_COPY(SegmentArrayMessageReader); - ~SegmentArrayMessageReader() noexcept(false); - - virtual kj::ArrayPtr getSegment(uint id) override; - -private: - kj::ArrayPtr> segments; -}; - -enum class AllocationStrategy: uint8_t { - FIXED_SIZE, - // The builder will prefer to allocate the same amount of space for each segment with no - // heuristic growth. It will still allocate larger segments when the preferred size is too small - // for some single object. This mode is generally not recommended, but can be particularly useful - // for testing in order to force a message to allocate a predictable number of segments. Note - // that you can force every single object in the message to be located in a separate segment by - // using this mode with firstSegmentWords = 0. - - GROW_HEURISTICALLY - // The builder will heuristically decide how much space to allocate for each segment. Each - // allocated segment will be progressively larger than the previous segments on the assumption - // that message sizes are exponentially distributed. The total number of segments that will be - // allocated for a message of size n is O(log n). -}; - -constexpr uint SUGGESTED_FIRST_SEGMENT_WORDS = 1024; -constexpr AllocationStrategy SUGGESTED_ALLOCATION_STRATEGY = AllocationStrategy::GROW_HEURISTICALLY; - -class MallocMessageBuilder: public MessageBuilder { - // A simple MessageBuilder that uses malloc() (actually, calloc()) to allocate segments. This - // implementation should be reasonable for any case that doesn't require writing the message to - // a specific location in memory. - -public: - explicit MallocMessageBuilder(uint firstSegmentWords = SUGGESTED_FIRST_SEGMENT_WORDS, - AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); - // Creates a BuilderContext which allocates at least the given number of words for the first - // segment, and then uses the given strategy to decide how much to allocate for subsequent - // segments. When choosing a value for firstSegmentWords, consider that: - // 1) Reading and writing messages gets slower when multiple segments are involved, so it's good - // if most messages fit in a single segment. - // 2) Unused bytes will not be written to the wire, so generally it is not a big deal to allocate - // more space than you need. It only becomes problematic if you are allocating many messages - // in parallel and thus use lots of memory, or if you allocate so much extra space that just - // zeroing it out becomes a bottleneck. - // The defaults have been chosen to be reasonable for most people, so don't change them unless you - // have reason to believe you need to. - - explicit MallocMessageBuilder(kj::ArrayPtr firstSegment, - AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); - // This version always returns the given array for the first segment, and then proceeds with the - // allocation strategy. This is useful for optimization when building lots of small messages in - // a tight loop: you can reuse the space for the first segment. - // - // firstSegment MUST be zero-initialized. MallocMessageBuilder's destructor will write new zeros - // over any space that was used so that it can be reused. - - KJ_DISALLOW_COPY(MallocMessageBuilder); - virtual ~MallocMessageBuilder() noexcept(false); - - virtual kj::ArrayPtr allocateSegment(uint minimumSize) override; - -private: - uint nextSize; - AllocationStrategy allocationStrategy; - - bool ownFirstSegment; - bool returnedFirstSegment; - - void* firstSegment; - - struct MoreSegments; - kj::Maybe> moreSegments; -}; - -class FlatMessageBuilder: public MessageBuilder { - // THIS IS NOT THE CLASS YOU'RE LOOKING FOR. - // - // If you want to write a message into already-existing scratch space, use `MallocMessageBuilder` - // and pass the scratch space to its constructor. It will then only fall back to malloc() if - // the scratch space is not large enough. - // - // Do NOT use this class unless you really know what you're doing. This class is problematic - // because it requires advance knowledge of the size of your message, which is usually impossible - // to determine without actually building the message. The class was created primarily to - // implement `copyToUnchecked()`, which itself exists only to support other internal parts of - // the Cap'n Proto implementation. - -public: - explicit FlatMessageBuilder(kj::ArrayPtr array); - KJ_DISALLOW_COPY(FlatMessageBuilder); - virtual ~FlatMessageBuilder() noexcept(false); - - void requireFilled(); - // Throws an exception if the flat array is not exactly full. - - virtual kj::ArrayPtr allocateSegment(uint minimumSize) override; - -private: - kj::ArrayPtr array; - bool allocated; -}; - -// ======================================================================================= -// implementation details - -inline const ReaderOptions& MessageReader::getOptions() { - return options; -} - -template -inline typename RootType::Reader MessageReader::getRoot() { - return getRootInternal().getAs(); -} - -template -inline typename RootType::Builder MessageBuilder::initRoot() { - return getRootInternal().initAs(); -} - -template -inline void MessageBuilder::setRoot(Reader&& value) { - getRootInternal().setAs>(value); -} - -template -inline typename RootType::Builder MessageBuilder::getRoot() { - return getRootInternal().getAs(); -} - -template -void MessageBuilder::adoptRoot(Orphan&& orphan) { - return getRootInternal().adopt(kj::mv(orphan)); -} - -template -typename RootType::Reader MessageReader::getRoot(SchemaType schema) { - return getRootInternal().getAs(schema); -} - -template -typename RootType::Builder MessageBuilder::getRoot(SchemaType schema) { - return getRootInternal().getAs(schema); -} - -template -typename RootType::Builder MessageBuilder::initRoot(SchemaType schema) { - return getRootInternal().initAs(schema); -} - -template -typename RootType::Reader readMessageUnchecked(const word* data) { - return AnyPointer::Reader(_::PointerReader::getRootUnchecked(data)).getAs(); -} - -template -void copyToUnchecked(Reader&& reader, kj::ArrayPtr uncheckedBuffer) { - FlatMessageBuilder builder(uncheckedBuffer); - builder.setRoot(kj::fwd(reader)); - builder.requireFilled(); -} - -template -typename RootType::Reader readDataStruct(kj::ArrayPtr data) { - return typename RootType::Reader(_::StructReader(data)); -} - -template -typename kj::ArrayPtr writeDataStruct(BuilderType builder) { - auto bytes = _::PointerHelpers>::getInternalBuilder(kj::mv(builder)) - .getDataSectionAsBlob(); - return kj::arrayPtr(reinterpret_cast(bytes.begin()), - reinterpret_cast(bytes.end())); -} - -template -static typename Type::Reader defaultValue() { - return typename Type::Reader(_::StructReader()); -} - -template -kj::Array canonicalize(T&& reader) { - return _::PointerHelpers>::getInternalReader(reader).canonicalize(); -} - -} // namespace capnp - -#endif // CAPNP_MESSAGE_H_ +// Copyright (c) 2013-2016 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. + +#include +#include +#include +#include +#include "common.h" +#include "layout.h" +#include "any.h" + +#ifndef CAPNP_MESSAGE_H_ +#define CAPNP_MESSAGE_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +namespace capnp { + +namespace _ { // private + class ReaderArena; + class BuilderArena; +} + +class StructSchema; +class Orphanage; +template +class Orphan; + +// ======================================================================================= + +struct ReaderOptions { + // Options controlling how data is read. + + uint64_t traversalLimitInWords = 8 * 1024 * 1024; + // Limits how many total words of data are allowed to be traversed. Traversal is counted when + // a new struct or list builder is obtained, e.g. from a get() accessor. This means that calling + // the getter for the same sub-struct multiple times will cause it to be double-counted. Once + // the traversal limit is reached, an error will be reported. + // + // This limit exists for security reasons. It is possible for an attacker to construct a message + // in which multiple pointers point at the same location. This is technically invalid, but hard + // to detect. Using such a message, an attacker could cause a message which is small on the wire + // to appear much larger when actually traversed, possibly exhausting server resources leading to + // denial-of-service. + // + // It makes sense to set a traversal limit that is much larger than the underlying message. + // Together with sensible coding practices (e.g. trying to avoid calling sub-object getters + // multiple times, which is expensive anyway), this should provide adequate protection without + // inconvenience. + // + // The default limit is 64 MiB. This may or may not be a sensible number for any given use case, + // but probably at least prevents easy exploitation while also avoiding causing problems in most + // typical cases. + + int nestingLimit = 64; + // Limits how deeply-nested a message structure can be, e.g. structs containing other structs or + // lists of structs. + // + // Like the traversal limit, this limit exists for security reasons. Since it is common to use + // recursive code to traverse recursive data structures, an attacker could easily cause a stack + // overflow by sending a very-deeply-nested (or even cyclic) message, without the message even + // being very large. The default limit of 64 is probably low enough to prevent any chance of + // stack overflow, yet high enough that it is never a problem in practice. +}; + +class MessageReader { + // Abstract interface for an object used to read a Cap'n Proto message. Subclasses of + // MessageReader are responsible for reading the raw, flat message content. Callers should + // usually call `messageReader.getRoot()` to get a `MyStructType::Reader` + // representing the root of the message, then use that to traverse the message content. + // + // Some common subclasses of `MessageReader` include `SegmentArrayMessageReader`, whose + // constructor accepts pointers to the raw data, and `StreamFdMessageReader` (from + // `serialize.h`), which reads the message from a file descriptor. One might implement other + // subclasses to handle things like reading from shared memory segments, mmap()ed files, etc. + +public: + MessageReader(ReaderOptions options); + // It is suggested that subclasses take ReaderOptions as a constructor parameter, but give it a + // default value of "ReaderOptions()". The base class constructor doesn't have a default value + // in order to remind subclasses that they really need to give the user a way to provide this. + + virtual ~MessageReader() noexcept(false); + + virtual kj::ArrayPtr getSegment(uint id) = 0; + // Gets the segment with the given ID, or returns null if no such segment exists. This method + // will be called at most once for each segment ID. + + inline const ReaderOptions& getOptions(); + // Get the options passed to the constructor. + + template + typename RootType::Reader getRoot(); + // Get the root struct of the message, interpreting it as the given struct type. + + template + typename RootType::Reader getRoot(SchemaType schema); + // Dynamically interpret the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include to + // use this. + + bool isCanonical(); + // Returns whether the message encoded in the reader is in canonical form. + +private: + ReaderOptions options; + + // Space in which we can construct a ReaderArena. We don't use ReaderArena directly here + // because we don't want clients to have to #include arena.h, which itself includes a bunch of + // big STL headers. We don't use a pointer to a ReaderArena because that would require an + // extra malloc on every message which could be expensive when processing small messages. + void* arenaSpace[15 + sizeof(kj::MutexGuarded) / sizeof(void*)]; + bool allocatedArena; + + _::ReaderArena* arena() { return reinterpret_cast<_::ReaderArena*>(arenaSpace); } + AnyPointer::Reader getRootInternal(); +}; + +class MessageBuilder { + // Abstract interface for an object used to allocate and build a message. Subclasses of + // MessageBuilder are responsible for allocating the space in which the message will be written. + // The most common subclass is `MallocMessageBuilder`, but other subclasses may be used to do + // tricky things like allocate messages in shared memory or mmap()ed files. + // + // Creating a new message ususually means allocating a new MessageBuilder (ideally on the stack) + // and then calling `messageBuilder.initRoot()` to get a `MyStructType::Builder`. + // That, in turn, can be used to fill in the message content. When done, you can call + // `messageBuilder.getSegmentsForOutput()` to get a list of flat data arrays containing the + // message. + +public: + MessageBuilder(); + virtual ~MessageBuilder() noexcept(false); + KJ_DISALLOW_COPY(MessageBuilder); + + struct SegmentInit { + kj::ArrayPtr space; + + size_t wordsUsed; + // Number of words in `space` which are used; the rest are free space in which additional + // objects may be allocated. + }; + + explicit MessageBuilder(kj::ArrayPtr segments); + // Create a MessageBuilder backed by existing memory. This is an advanced interface that most + // people should not use. THIS METHOD IS INSECURE; see below. + // + // This allows a MessageBuilder to be constructed to modify an in-memory message without first + // making a copy of the content. This is especially useful in conjunction with mmap(). + // + // The contents of each segment must outlive the MessageBuilder, but the SegmentInit array itself + // only need outlive the constructor. + // + // SECURITY: Do not use this in conjunction with untrusted data. This constructor assumes that + // the input message is valid. This constructor is designed to be used with data you control, + // e.g. an mmap'd file which is owned and accessed by only one program. When reading data you + // do not trust, you *must* load it into a Reader and then copy into a Builder as a means of + // validating the content. + // + // WARNING: It is NOT safe to initialize a MessageBuilder in this way from memory that is + // currently in use by another MessageBuilder or MessageReader. Other readers/builders will + // not observe changes to the segment sizes nor newly-allocated segments caused by allocating + // new objects in this message. + + virtual kj::ArrayPtr allocateSegment(uint minimumSize) = 0; + // Allocates an array of at least the given number of words, throwing an exception or crashing if + // this is not possible. It is expected that this method will usually return more space than + // requested, and the caller should use that extra space as much as possible before allocating + // more. The returned space remains valid at least until the MessageBuilder is destroyed. + // + // Cap'n Proto will only call this once at a time, so the subclass need not worry about + // thread-safety. + + template + typename RootType::Builder initRoot(); + // Initialize the root struct of the message as the given struct type. + + template + void setRoot(Reader&& value); + // Set the root struct to a deep copy of the given struct. + + template + typename RootType::Builder getRoot(); + // Get the root struct of the message, interpreting it as the given struct type. + + template + typename RootType::Builder getRoot(SchemaType schema); + // Dynamically interpret the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include to + // use this. + + template + typename RootType::Builder initRoot(SchemaType schema); + // Dynamically init the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include to + // use this. + + template + void adoptRoot(Orphan&& orphan); + // Like setRoot() but adopts the orphan without copying. + + kj::ArrayPtr> getSegmentsForOutput(); + // Get the raw data that makes up the message. + + Orphanage getOrphanage(); + + bool isCanonical(); + // Check whether the message builder is in canonical form + +private: + void* arenaSpace[22]; + // Space in which we can construct a BuilderArena. We don't use BuilderArena directly here + // because we don't want clients to have to #include arena.h, which itself includes a bunch of + // big STL headers. We don't use a pointer to a BuilderArena because that would require an + // extra malloc on every message which could be expensive when processing small messages. + + bool allocatedArena = false; + // We have to initialize the arena lazily because when we do so we want to allocate the root + // pointer immediately, and this will allocate a segment, which requires a virtual function + // call on the MessageBuilder. We can't do such a call in the constructor since the subclass + // isn't constructed yet. This is kind of annoying because it means that getOrphanage() is + // not thread-safe, but that shouldn't be a huge deal... + + _::BuilderArena* arena() { return reinterpret_cast<_::BuilderArena*>(arenaSpace); } + _::SegmentBuilder* getRootSegment(); + AnyPointer::Builder getRootInternal(); +}; + +template +typename RootType::Reader readMessageUnchecked(const word* data); +// IF THE INPUT IS INVALID, THIS MAY CRASH, CORRUPT MEMORY, CREATE A SECURITY HOLE IN YOUR APP, +// MURDER YOUR FIRST-BORN CHILD, AND/OR BRING ABOUT ETERNAL DAMNATION ON ALL OF HUMANITY. DO NOT +// USE UNLESS YOU UNDERSTAND THE CONSEQUENCES. +// +// Given a pointer to a known-valid message located in a single contiguous memory segment, +// returns a reader for that message. No bounds-checking will be done while traversing this +// message. Use this only if you have already verified that all pointers are valid and in-bounds, +// and there are no far pointers in the message. +// +// To create a message that can be passed to this function, build a message using a MallocAllocator +// whose preferred segment size is larger than the message size. This guarantees that the message +// will be allocated as a single segment, meaning getSegmentsForOutput() returns a single word +// array. That word array is your message; you may pass a pointer to its first word into +// readMessageUnchecked() to read the message. +// +// This can be particularly handy for embedding messages in generated code: you can +// embed the raw bytes (using AlignedData) then make a Reader for it using this. This is the way +// default values are embedded in code generated by the Cap'n Proto compiler. E.g., if you have +// a message MyMessage, you can read its default value like so: +// MyMessage::Reader reader = Message::readMessageUnchecked(MyMessage::DEFAULT.words); +// +// To sanitize a message from an untrusted source such that it can be safely passed to +// readMessageUnchecked(), use copyToUnchecked(). + +template +void copyToUnchecked(Reader&& reader, kj::ArrayPtr uncheckedBuffer); +// Copy the content of the given reader into the given buffer, such that it can safely be passed to +// readMessageUnchecked(). The buffer's size must be exactly reader.totalSizeInWords() + 1, +// otherwise an exception will be thrown. The buffer must be zero'd before calling. + +template +typename RootType::Reader readDataStruct(kj::ArrayPtr data); +// Interprets the given data as a single, data-only struct. Only primitive fields (booleans, +// numbers, and enums) will be readable; all pointers will be null. This is useful if you want +// to use Cap'n Proto as a language/platform-neutral way to pack some bits. +// +// The input is a word array rather than a byte array to enforce alignment. If you have a byte +// array which you know is word-aligned (or if your platform supports unaligned reads and you don't +// mind the performance penalty), then you can use `reinterpret_cast` to convert a byte array into +// a word array: +// +// kj::arrayPtr(reinterpret_cast(bytes.begin()), +// reinterpret_cast(bytes.end())) + +template +typename kj::ArrayPtr writeDataStruct(BuilderType builder); +// Given a struct builder, get the underlying data section as a word array, suitable for passing +// to `readDataStruct()`. +// +// Note that you may call `.toBytes()` on the returned value to convert to `ArrayPtr`. + +template +static typename Type::Reader defaultValue(); +// Get a default instance of the given struct or list type. +// +// TODO(cleanup): Find a better home for this function? + +// ======================================================================================= + +class SegmentArrayMessageReader: public MessageReader { + // A simple MessageReader that reads from an array of word arrays representing all segments. + // In particular you can read directly from the output of MessageBuilder::getSegmentsForOutput() + // (although it would probably make more sense to call builder.getRoot().asReader() in that case). + +public: + SegmentArrayMessageReader(kj::ArrayPtr> segments, + ReaderOptions options = ReaderOptions()); + // Creates a message pointing at the given segment array, without taking ownership of the + // segments. All arrays passed in must remain valid until the MessageReader is destroyed. + + KJ_DISALLOW_COPY(SegmentArrayMessageReader); + ~SegmentArrayMessageReader() noexcept(false); + + virtual kj::ArrayPtr getSegment(uint id) override; + +private: + kj::ArrayPtr> segments; +}; + +enum class AllocationStrategy: uint8_t { + FIXED_SIZE, + // The builder will prefer to allocate the same amount of space for each segment with no + // heuristic growth. It will still allocate larger segments when the preferred size is too small + // for some single object. This mode is generally not recommended, but can be particularly useful + // for testing in order to force a message to allocate a predictable number of segments. Note + // that you can force every single object in the message to be located in a separate segment by + // using this mode with firstSegmentWords = 0. + + GROW_HEURISTICALLY + // The builder will heuristically decide how much space to allocate for each segment. Each + // allocated segment will be progressively larger than the previous segments on the assumption + // that message sizes are exponentially distributed. The total number of segments that will be + // allocated for a message of size n is O(log n). +}; + +constexpr uint SUGGESTED_FIRST_SEGMENT_WORDS = 1024; +constexpr AllocationStrategy SUGGESTED_ALLOCATION_STRATEGY = AllocationStrategy::GROW_HEURISTICALLY; + +class MallocMessageBuilder: public MessageBuilder { + // A simple MessageBuilder that uses malloc() (actually, calloc()) to allocate segments. This + // implementation should be reasonable for any case that doesn't require writing the message to + // a specific location in memory. + +public: + explicit MallocMessageBuilder(uint firstSegmentWords = SUGGESTED_FIRST_SEGMENT_WORDS, + AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); + // Creates a BuilderContext which allocates at least the given number of words for the first + // segment, and then uses the given strategy to decide how much to allocate for subsequent + // segments. When choosing a value for firstSegmentWords, consider that: + // 1) Reading and writing messages gets slower when multiple segments are involved, so it's good + // if most messages fit in a single segment. + // 2) Unused bytes will not be written to the wire, so generally it is not a big deal to allocate + // more space than you need. It only becomes problematic if you are allocating many messages + // in parallel and thus use lots of memory, or if you allocate so much extra space that just + // zeroing it out becomes a bottleneck. + // The defaults have been chosen to be reasonable for most people, so don't change them unless you + // have reason to believe you need to. + + explicit MallocMessageBuilder(kj::ArrayPtr firstSegment, + AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); + // This version always returns the given array for the first segment, and then proceeds with the + // allocation strategy. This is useful for optimization when building lots of small messages in + // a tight loop: you can reuse the space for the first segment. + // + // firstSegment MUST be zero-initialized. MallocMessageBuilder's destructor will write new zeros + // over any space that was used so that it can be reused. + + KJ_DISALLOW_COPY(MallocMessageBuilder); + virtual ~MallocMessageBuilder() noexcept(false); + + virtual kj::ArrayPtr allocateSegment(uint minimumSize) override; + +private: + uint nextSize; + AllocationStrategy allocationStrategy; + + bool ownFirstSegment; + bool returnedFirstSegment; + + void* firstSegment; + + struct MoreSegments; + kj::Maybe> moreSegments; +}; + +class FlatMessageBuilder: public MessageBuilder { + // THIS IS NOT THE CLASS YOU'RE LOOKING FOR. + // + // If you want to write a message into already-existing scratch space, use `MallocMessageBuilder` + // and pass the scratch space to its constructor. It will then only fall back to malloc() if + // the scratch space is not large enough. + // + // Do NOT use this class unless you really know what you're doing. This class is problematic + // because it requires advance knowledge of the size of your message, which is usually impossible + // to determine without actually building the message. The class was created primarily to + // implement `copyToUnchecked()`, which itself exists only to support other internal parts of + // the Cap'n Proto implementation. + +public: + explicit FlatMessageBuilder(kj::ArrayPtr array); + KJ_DISALLOW_COPY(FlatMessageBuilder); + virtual ~FlatMessageBuilder() noexcept(false); + + void requireFilled(); + // Throws an exception if the flat array is not exactly full. + + virtual kj::ArrayPtr allocateSegment(uint minimumSize) override; + +private: + kj::ArrayPtr array; + bool allocated; +}; + +// ======================================================================================= +// implementation details + +inline const ReaderOptions& MessageReader::getOptions() { + return options; +} + +template +inline typename RootType::Reader MessageReader::getRoot() { + return getRootInternal().getAs(); +} + +template +inline typename RootType::Builder MessageBuilder::initRoot() { + return getRootInternal().initAs(); +} + +template +inline void MessageBuilder::setRoot(Reader&& value) { + getRootInternal().setAs>(value); +} + +template +inline typename RootType::Builder MessageBuilder::getRoot() { + return getRootInternal().getAs(); +} + +template +void MessageBuilder::adoptRoot(Orphan&& orphan) { + return getRootInternal().adopt(kj::mv(orphan)); +} + +template +typename RootType::Reader MessageReader::getRoot(SchemaType schema) { + return getRootInternal().getAs(schema); +} + +template +typename RootType::Builder MessageBuilder::getRoot(SchemaType schema) { + return getRootInternal().getAs(schema); +} + +template +typename RootType::Builder MessageBuilder::initRoot(SchemaType schema) { + return getRootInternal().initAs(schema); +} + +template +typename RootType::Reader readMessageUnchecked(const word* data) { + return AnyPointer::Reader(_::PointerReader::getRootUnchecked(data)).getAs(); +} + +template +void copyToUnchecked(Reader&& reader, kj::ArrayPtr uncheckedBuffer) { + FlatMessageBuilder builder(uncheckedBuffer); + builder.setRoot(kj::fwd(reader)); + builder.requireFilled(); +} + +template +typename RootType::Reader readDataStruct(kj::ArrayPtr data) { + return typename RootType::Reader(_::StructReader(data)); +} + +template +typename kj::ArrayPtr writeDataStruct(BuilderType builder) { + auto bytes = _::PointerHelpers>::getInternalBuilder(kj::mv(builder)) + .getDataSectionAsBlob(); + return kj::arrayPtr(reinterpret_cast(bytes.begin()), + reinterpret_cast(bytes.end())); +} + +template +static typename Type::Reader defaultValue() { + return typename Type::Reader(_::StructReader()); +} + +template +kj::Array canonicalize(T&& reader) { + return _::PointerHelpers>::getInternalReader(reader).canonicalize(); +} + +} // namespace capnp + +#endif // CAPNP_MESSAGE_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/orphan.h --- a/win32-mingw/include/capnp/orphan.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/orphan.h Tue May 23 09:16:54 2017 +0100 @@ -1,440 +1,440 @@ -// 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. - -#ifndef CAPNP_ORPHAN_H_ -#define CAPNP_ORPHAN_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" - -namespace capnp { - -class StructSchema; -class ListSchema; -struct DynamicStruct; -struct DynamicList; -namespace _ { struct OrphanageInternal; } - -template -class Orphan { - // Represents an object which is allocated within some message builder but has no pointers - // pointing at it. An Orphan can later be "adopted" by some other object as one of that object's - // fields, without having to copy the orphan. For a field `foo` of pointer type, the generated - // code will define builder methods `void adoptFoo(Orphan)` and `Orphan disownFoo()`. - // Orphans can also be created independently of any parent using an Orphanage. - // - // `Orphan` can be moved but not copied, like `Own`, so that it is impossible for one - // orphan to be adopted multiple times. If an orphan is destroyed without being adopted, its - // contents are zero'd out (and possibly reused, if we ever implement the ability to reuse space - // in a message arena). - -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - Orphan& operator=(Orphan&&) = default; - inline Orphan(_::OrphanBuilder&& builder): builder(kj::mv(builder)) {} - - inline BuilderFor get(); - // Get the underlying builder. If the orphan is null, this will allocate and return a default - // object rather than crash. This is done for security -- otherwise, you might enable a DoS - // attack any time you disown a field and fail to check if it is null. In the case of structs, - // this means that the orphan is no longer null after get() returns. In the case of lists, - // no actual object is allocated since a simple empty ListBuilder can be returned. - - inline ReaderFor getReader() const; - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - - inline void truncate(uint size); - // Resize an object (which must be a list or a blob) to the given size. - // - // If the new size is less than the original, the remaining elements will be discarded. The - // list is never moved in this case. If the list happens to be located at the end of its segment - // (which is always true if the list was the last thing allocated), the removed memory will be - // reclaimed (reducing the messag size), otherwise it is simply zeroed. The reclaiming behavior - // is particularly useful for allocating buffer space when you aren't sure how much space you - // actually need: you can pre-allocate, say, a 4k byte array, read() from a file into it, and - // then truncate it back to the amount of space actually used. - // - // If the new size is greater than the original, the list is extended with default values. If - // the list is the last object in its segment *and* there is enough space left in the segment to - // extend it to cover the new values, then the list is extended in-place. Otherwise, it must be - // moved to a new location, leaving a zero'd hole in the previous space that won't be filled. - // This copy is shallow; sub-objects will simply be reparented, not copied. - // - // Any existing readers or builders pointing at the object are invalidated by this call (even if - // it doesn't move). You must call `get()` or `getReader()` again to get the new, valid pointer. - -private: - _::OrphanBuilder builder; - - template - friend struct _::PointerHelpers; - template - friend struct List; - template - friend class Orphan; - friend class Orphanage; - friend class MessageBuilder; -}; - -class Orphanage: private kj::DisallowConstCopy { - // Use to directly allocate Orphan objects, without having a parent object allocate and then - // disown the object. - -public: - inline Orphanage(): arena(nullptr) {} - - template - static Orphanage getForMessageContaining(BuilderType builder); - // Construct an Orphanage that allocates within the message containing the given Builder. This - // allows the constructed Orphans to be adopted by objects within said message. - // - // This constructor takes the builder rather than having the builder have a getOrphanage() method - // because this is an advanced feature and we don't want to pollute the builder APIs with it. - // - // Note that if you have a direct pointer to the `MessageBuilder`, you can simply call its - // `getOrphanage()` method. - - template - Orphan newOrphan() const; - // Allocate a new orphaned struct. - - template - Orphan newOrphan(uint size) const; - // Allocate a new orphaned list or blob. - - Orphan newOrphan(StructSchema schema) const; - // Dynamically create an orphan struct with the given schema. You must - // #include to use this. - - Orphan newOrphan(ListSchema schema, uint size) const; - // Dynamically create an orphan list with the given schema. You must #include - // to use this. - - template - Orphan> newOrphanCopy(Reader copyFrom) const; - // Allocate a new orphaned object (struct, list, or blob) and initialize it as a copy of the - // given object. - - template - Orphan>>> newOrphanConcat(kj::ArrayPtr lists) const; - template - Orphan>>> newOrphanConcat(kj::ArrayPtr lists) const; - // Given an array of List readers, copy and concatenate the lists, creating a new Orphan. - // - // Note that compared to allocating the list yourself and using `setWithCaveats()` to set each - // item, this method avoids the "caveats": the new list will be allocated with the element size - // being the maximum of that from all the input lists. This is particularly important when - // concatenating struct lists: if the lists were created using a newer version of the protocol - // in which some new fields had been added to the struct, using `setWithCaveats()` would - // truncate off those new fields. - - Orphan referenceExternalData(Data::Reader data) const; - // Creates an Orphan that points at an existing region of memory (e.g. from another message) - // without copying it. There are some SEVERE restrictions on how this can be used: - // - The memory must remain valid until the `MessageBuilder` is destroyed (even if the orphan is - // abandoned). - // - Because the data is const, you will not be allowed to obtain a `Data::Builder` - // for this blob. Any call which would return such a builder will throw an exception. You - // can, however, obtain a Reader, e.g. via orphan.getReader() or from a parent Reader (once - // the orphan is adopted). It is your responsibility to make sure your code can deal with - // these problems when using this optimization; if you can't, allocate a copy instead. - // - `data.begin()` must be aligned to a machine word boundary (32-bit or 64-bit depending on - // the CPU). Any pointer returned by malloc() as well as any data blob obtained from another - // Cap'n Proto message satisfies this. - // - If `data.size()` is not a multiple of 8, extra bytes past data.end() up until the next 8-byte - // boundary will be visible in the raw message when it is written out. Thus, there must be no - // secrets in these bytes. Data blobs obtained from other Cap'n Proto messages should be safe - // as these bytes should be zero (unless the sender had the same problem). - // - // The array will actually become one of the message's segments. The data can thus be adopted - // into the message tree without copying it. This is particularly useful when referencing very - // large blobs, such as whole mmap'd files. - -private: - _::BuilderArena* arena; - _::CapTableBuilder* capTable; - - inline explicit Orphanage(_::BuilderArena* arena, _::CapTableBuilder* capTable) - : arena(arena), capTable(capTable) {} - - template - struct GetInnerBuilder; - template - struct GetInnerReader; - template - struct NewOrphanListImpl; - - friend class MessageBuilder; - friend struct _::OrphanageInternal; -}; - -// ======================================================================================= -// Inline implementation details. - -namespace _ { // private - -template -struct OrphanGetImpl; - -template -struct OrphanGetImpl { - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, _::elementSizeForType()); - } -}; - -template -struct OrphanGetImpl { - static inline typename T::Builder apply(_::OrphanBuilder& builder) { - return typename T::Builder(builder.asStruct(_::structSize())); - } - static inline typename T::Reader applyReader(const _::OrphanBuilder& builder) { - return typename T::Reader(builder.asStructReader(_::structSize())); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, _::structSize()); - } -}; - -#if !CAPNP_LITE -template -struct OrphanGetImpl { - static inline typename T::Client apply(_::OrphanBuilder& builder) { - return typename T::Client(builder.asCapability()); - } - static inline typename T::Client applyReader(const _::OrphanBuilder& builder) { - return typename T::Client(builder.asCapability()); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; -#endif // !CAPNP_LITE - -template -struct OrphanGetImpl, Kind::LIST> { - static inline typename List::Builder apply(_::OrphanBuilder& builder) { - return typename List::Builder(builder.asList(_::ElementSizeForType::value)); - } - static inline typename List::Reader applyReader(const _::OrphanBuilder& builder) { - return typename List::Reader(builder.asListReader(_::ElementSizeForType::value)); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -template -struct OrphanGetImpl, Kind::LIST> { - static inline typename List::Builder apply(_::OrphanBuilder& builder) { - return typename List::Builder(builder.asStructList(_::structSize())); - } - static inline typename List::Reader applyReader(const _::OrphanBuilder& builder) { - return typename List::Reader(builder.asListReader(_::ElementSizeForType::value)); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -template <> -struct OrphanGetImpl { - static inline Text::Builder apply(_::OrphanBuilder& builder) { - return Text::Builder(builder.asText()); - } - static inline Text::Reader applyReader(const _::OrphanBuilder& builder) { - return Text::Reader(builder.asTextReader()); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -template <> -struct OrphanGetImpl { - static inline Data::Builder apply(_::OrphanBuilder& builder) { - return Data::Builder(builder.asData()); - } - static inline Data::Reader applyReader(const _::OrphanBuilder& builder) { - return Data::Reader(builder.asDataReader()); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -struct OrphanageInternal { - static inline _::BuilderArena* getArena(Orphanage orphanage) { return orphanage.arena; } - static inline _::CapTableBuilder* getCapTable(Orphanage orphanage) { return orphanage.capTable; } -}; - -} // namespace _ (private) - -template -inline BuilderFor Orphan::get() { - return _::OrphanGetImpl::apply(builder); -} - -template -inline ReaderFor Orphan::getReader() const { - return _::OrphanGetImpl::applyReader(builder); -} - -template -inline void Orphan::truncate(uint size) { - _::OrphanGetImpl>::truncateListOf(builder, size * ELEMENTS); -} - -template <> -inline void Orphan::truncate(uint size) { - builder.truncateText(size * ELEMENTS); -} - -template <> -inline void Orphan::truncate(uint size) { - builder.truncate(size * ELEMENTS, ElementSize::BYTE); -} - -template -struct Orphanage::GetInnerBuilder { - static inline _::StructBuilder apply(typename T::Builder& t) { - return t._builder; - } -}; - -template -struct Orphanage::GetInnerBuilder { - static inline _::ListBuilder apply(typename T::Builder& t) { - return t.builder; - } -}; - -template -Orphanage Orphanage::getForMessageContaining(BuilderType builder) { - auto inner = GetInnerBuilder>::apply(builder); - return Orphanage(inner.getArena(), inner.getCapTable()); -} - -template -Orphan Orphanage::newOrphan() const { - return Orphan(_::OrphanBuilder::initStruct(arena, capTable, _::structSize())); -} - -template -struct Orphanage::NewOrphanListImpl> { - static inline _::OrphanBuilder apply( - _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { - return _::OrphanBuilder::initList( - arena, capTable, size * ELEMENTS, _::ElementSizeForType::value); - } -}; - -template -struct Orphanage::NewOrphanListImpl> { - static inline _::OrphanBuilder apply( - _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { - return _::OrphanBuilder::initStructList( - arena, capTable, size * ELEMENTS, _::structSize()); - } -}; - -template <> -struct Orphanage::NewOrphanListImpl { - static inline _::OrphanBuilder apply( - _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { - return _::OrphanBuilder::initText(arena, capTable, size * BYTES); - } -}; - -template <> -struct Orphanage::NewOrphanListImpl { - static inline _::OrphanBuilder apply( - _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { - return _::OrphanBuilder::initData(arena, capTable, size * BYTES); - } -}; - -template -Orphan Orphanage::newOrphan(uint size) const { - return Orphan(NewOrphanListImpl::apply(arena, capTable, size)); -} - -template -struct Orphanage::GetInnerReader { - static inline _::StructReader apply(const typename T::Reader& t) { - return t._reader; - } -}; - -template -struct Orphanage::GetInnerReader { - static inline _::ListReader apply(const typename T::Reader& t) { - return t.reader; - } -}; - -template -struct Orphanage::GetInnerReader { - static inline const typename T::Reader& apply(const typename T::Reader& t) { - return t; - } -}; - -template -inline Orphan> Orphanage::newOrphanCopy(Reader copyFrom) const { - return Orphan>(_::OrphanBuilder::copy( - arena, capTable, GetInnerReader>::apply(copyFrom))); -} - -template -inline Orphan>>> -Orphanage::newOrphanConcat(kj::ArrayPtr lists) const { - return newOrphanConcat(kj::implicitCast>(lists)); -} -template -inline Orphan>>> -Orphanage::newOrphanConcat(kj::ArrayPtr lists) const { - // Optimization / simplification: Rely on List::Reader containing nothing except a - // _::ListReader. - static_assert(sizeof(T) == sizeof(_::ListReader), "lists are not bare readers?"); - kj::ArrayPtr raw( - reinterpret_cast(lists.begin()), lists.size()); - typedef ListElementType> Element; - return Orphan>( - _::OrphanBuilder::concat(arena, capTable, - _::elementSizeForType(), - _::minStructSizeForElement(), raw)); -} - -inline Orphan Orphanage::referenceExternalData(Data::Reader data) const { - return Orphan(_::OrphanBuilder::referenceExternalData(arena, data)); -} - -} // namespace capnp - -#endif // CAPNP_ORPHAN_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. + +#ifndef CAPNP_ORPHAN_H_ +#define CAPNP_ORPHAN_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" + +namespace capnp { + +class StructSchema; +class ListSchema; +struct DynamicStruct; +struct DynamicList; +namespace _ { struct OrphanageInternal; } + +template +class Orphan { + // Represents an object which is allocated within some message builder but has no pointers + // pointing at it. An Orphan can later be "adopted" by some other object as one of that object's + // fields, without having to copy the orphan. For a field `foo` of pointer type, the generated + // code will define builder methods `void adoptFoo(Orphan)` and `Orphan disownFoo()`. + // Orphans can also be created independently of any parent using an Orphanage. + // + // `Orphan` can be moved but not copied, like `Own`, so that it is impossible for one + // orphan to be adopted multiple times. If an orphan is destroyed without being adopted, its + // contents are zero'd out (and possibly reused, if we ever implement the ability to reuse space + // in a message arena). + +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + inline Orphan(_::OrphanBuilder&& builder): builder(kj::mv(builder)) {} + + inline BuilderFor get(); + // Get the underlying builder. If the orphan is null, this will allocate and return a default + // object rather than crash. This is done for security -- otherwise, you might enable a DoS + // attack any time you disown a field and fail to check if it is null. In the case of structs, + // this means that the orphan is no longer null after get() returns. In the case of lists, + // no actual object is allocated since a simple empty ListBuilder can be returned. + + inline ReaderFor getReader() const; + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + + inline void truncate(uint size); + // Resize an object (which must be a list or a blob) to the given size. + // + // If the new size is less than the original, the remaining elements will be discarded. The + // list is never moved in this case. If the list happens to be located at the end of its segment + // (which is always true if the list was the last thing allocated), the removed memory will be + // reclaimed (reducing the messag size), otherwise it is simply zeroed. The reclaiming behavior + // is particularly useful for allocating buffer space when you aren't sure how much space you + // actually need: you can pre-allocate, say, a 4k byte array, read() from a file into it, and + // then truncate it back to the amount of space actually used. + // + // If the new size is greater than the original, the list is extended with default values. If + // the list is the last object in its segment *and* there is enough space left in the segment to + // extend it to cover the new values, then the list is extended in-place. Otherwise, it must be + // moved to a new location, leaving a zero'd hole in the previous space that won't be filled. + // This copy is shallow; sub-objects will simply be reparented, not copied. + // + // Any existing readers or builders pointing at the object are invalidated by this call (even if + // it doesn't move). You must call `get()` or `getReader()` again to get the new, valid pointer. + +private: + _::OrphanBuilder builder; + + template + friend struct _::PointerHelpers; + template + friend struct List; + template + friend class Orphan; + friend class Orphanage; + friend class MessageBuilder; +}; + +class Orphanage: private kj::DisallowConstCopy { + // Use to directly allocate Orphan objects, without having a parent object allocate and then + // disown the object. + +public: + inline Orphanage(): arena(nullptr) {} + + template + static Orphanage getForMessageContaining(BuilderType builder); + // Construct an Orphanage that allocates within the message containing the given Builder. This + // allows the constructed Orphans to be adopted by objects within said message. + // + // This constructor takes the builder rather than having the builder have a getOrphanage() method + // because this is an advanced feature and we don't want to pollute the builder APIs with it. + // + // Note that if you have a direct pointer to the `MessageBuilder`, you can simply call its + // `getOrphanage()` method. + + template + Orphan newOrphan() const; + // Allocate a new orphaned struct. + + template + Orphan newOrphan(uint size) const; + // Allocate a new orphaned list or blob. + + Orphan newOrphan(StructSchema schema) const; + // Dynamically create an orphan struct with the given schema. You must + // #include to use this. + + Orphan newOrphan(ListSchema schema, uint size) const; + // Dynamically create an orphan list with the given schema. You must #include + // to use this. + + template + Orphan> newOrphanCopy(Reader copyFrom) const; + // Allocate a new orphaned object (struct, list, or blob) and initialize it as a copy of the + // given object. + + template + Orphan>>> newOrphanConcat(kj::ArrayPtr lists) const; + template + Orphan>>> newOrphanConcat(kj::ArrayPtr lists) const; + // Given an array of List readers, copy and concatenate the lists, creating a new Orphan. + // + // Note that compared to allocating the list yourself and using `setWithCaveats()` to set each + // item, this method avoids the "caveats": the new list will be allocated with the element size + // being the maximum of that from all the input lists. This is particularly important when + // concatenating struct lists: if the lists were created using a newer version of the protocol + // in which some new fields had been added to the struct, using `setWithCaveats()` would + // truncate off those new fields. + + Orphan referenceExternalData(Data::Reader data) const; + // Creates an Orphan that points at an existing region of memory (e.g. from another message) + // without copying it. There are some SEVERE restrictions on how this can be used: + // - The memory must remain valid until the `MessageBuilder` is destroyed (even if the orphan is + // abandoned). + // - Because the data is const, you will not be allowed to obtain a `Data::Builder` + // for this blob. Any call which would return such a builder will throw an exception. You + // can, however, obtain a Reader, e.g. via orphan.getReader() or from a parent Reader (once + // the orphan is adopted). It is your responsibility to make sure your code can deal with + // these problems when using this optimization; if you can't, allocate a copy instead. + // - `data.begin()` must be aligned to a machine word boundary (32-bit or 64-bit depending on + // the CPU). Any pointer returned by malloc() as well as any data blob obtained from another + // Cap'n Proto message satisfies this. + // - If `data.size()` is not a multiple of 8, extra bytes past data.end() up until the next 8-byte + // boundary will be visible in the raw message when it is written out. Thus, there must be no + // secrets in these bytes. Data blobs obtained from other Cap'n Proto messages should be safe + // as these bytes should be zero (unless the sender had the same problem). + // + // The array will actually become one of the message's segments. The data can thus be adopted + // into the message tree without copying it. This is particularly useful when referencing very + // large blobs, such as whole mmap'd files. + +private: + _::BuilderArena* arena; + _::CapTableBuilder* capTable; + + inline explicit Orphanage(_::BuilderArena* arena, _::CapTableBuilder* capTable) + : arena(arena), capTable(capTable) {} + + template + struct GetInnerBuilder; + template + struct GetInnerReader; + template + struct NewOrphanListImpl; + + friend class MessageBuilder; + friend struct _::OrphanageInternal; +}; + +// ======================================================================================= +// Inline implementation details. + +namespace _ { // private + +template +struct OrphanGetImpl; + +template +struct OrphanGetImpl { + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::elementSizeForType()); + } +}; + +template +struct OrphanGetImpl { + static inline typename T::Builder apply(_::OrphanBuilder& builder) { + return typename T::Builder(builder.asStruct(_::structSize())); + } + static inline typename T::Reader applyReader(const _::OrphanBuilder& builder) { + return typename T::Reader(builder.asStructReader(_::structSize())); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::structSize()); + } +}; + +#if !CAPNP_LITE +template +struct OrphanGetImpl { + static inline typename T::Client apply(_::OrphanBuilder& builder) { + return typename T::Client(builder.asCapability()); + } + static inline typename T::Client applyReader(const _::OrphanBuilder& builder) { + return typename T::Client(builder.asCapability()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; +#endif // !CAPNP_LITE + +template +struct OrphanGetImpl, Kind::LIST> { + static inline typename List::Builder apply(_::OrphanBuilder& builder) { + return typename List::Builder(builder.asList(_::ElementSizeForType::value)); + } + static inline typename List::Reader applyReader(const _::OrphanBuilder& builder) { + return typename List::Reader(builder.asListReader(_::ElementSizeForType::value)); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template +struct OrphanGetImpl, Kind::LIST> { + static inline typename List::Builder apply(_::OrphanBuilder& builder) { + return typename List::Builder(builder.asStructList(_::structSize())); + } + static inline typename List::Reader applyReader(const _::OrphanBuilder& builder) { + return typename List::Reader(builder.asListReader(_::ElementSizeForType::value)); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template <> +struct OrphanGetImpl { + static inline Text::Builder apply(_::OrphanBuilder& builder) { + return Text::Builder(builder.asText()); + } + static inline Text::Reader applyReader(const _::OrphanBuilder& builder) { + return Text::Reader(builder.asTextReader()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template <> +struct OrphanGetImpl { + static inline Data::Builder apply(_::OrphanBuilder& builder) { + return Data::Builder(builder.asData()); + } + static inline Data::Reader applyReader(const _::OrphanBuilder& builder) { + return Data::Reader(builder.asDataReader()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +struct OrphanageInternal { + static inline _::BuilderArena* getArena(Orphanage orphanage) { return orphanage.arena; } + static inline _::CapTableBuilder* getCapTable(Orphanage orphanage) { return orphanage.capTable; } +}; + +} // namespace _ (private) + +template +inline BuilderFor Orphan::get() { + return _::OrphanGetImpl::apply(builder); +} + +template +inline ReaderFor Orphan::getReader() const { + return _::OrphanGetImpl::applyReader(builder); +} + +template +inline void Orphan::truncate(uint size) { + _::OrphanGetImpl>::truncateListOf(builder, bounded(size) * ELEMENTS); +} + +template <> +inline void Orphan::truncate(uint size) { + builder.truncateText(bounded(size) * ELEMENTS); +} + +template <> +inline void Orphan::truncate(uint size) { + builder.truncate(bounded(size) * ELEMENTS, ElementSize::BYTE); +} + +template +struct Orphanage::GetInnerBuilder { + static inline _::StructBuilder apply(typename T::Builder& t) { + return t._builder; + } +}; + +template +struct Orphanage::GetInnerBuilder { + static inline _::ListBuilder apply(typename T::Builder& t) { + return t.builder; + } +}; + +template +Orphanage Orphanage::getForMessageContaining(BuilderType builder) { + auto inner = GetInnerBuilder>::apply(builder); + return Orphanage(inner.getArena(), inner.getCapTable()); +} + +template +Orphan Orphanage::newOrphan() const { + return Orphan(_::OrphanBuilder::initStruct(arena, capTable, _::structSize())); +} + +template +struct Orphanage::NewOrphanListImpl> { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initList( + arena, capTable, bounded(size) * ELEMENTS, _::ElementSizeForType::value); + } +}; + +template +struct Orphanage::NewOrphanListImpl> { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initStructList( + arena, capTable, bounded(size) * ELEMENTS, _::structSize()); + } +}; + +template <> +struct Orphanage::NewOrphanListImpl { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initText(arena, capTable, bounded(size) * BYTES); + } +}; + +template <> +struct Orphanage::NewOrphanListImpl { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initData(arena, capTable, bounded(size) * BYTES); + } +}; + +template +Orphan Orphanage::newOrphan(uint size) const { + return Orphan(NewOrphanListImpl::apply(arena, capTable, size)); +} + +template +struct Orphanage::GetInnerReader { + static inline _::StructReader apply(const typename T::Reader& t) { + return t._reader; + } +}; + +template +struct Orphanage::GetInnerReader { + static inline _::ListReader apply(const typename T::Reader& t) { + return t.reader; + } +}; + +template +struct Orphanage::GetInnerReader { + static inline const typename T::Reader& apply(const typename T::Reader& t) { + return t; + } +}; + +template +inline Orphan> Orphanage::newOrphanCopy(Reader copyFrom) const { + return Orphan>(_::OrphanBuilder::copy( + arena, capTable, GetInnerReader>::apply(copyFrom))); +} + +template +inline Orphan>>> +Orphanage::newOrphanConcat(kj::ArrayPtr lists) const { + return newOrphanConcat(kj::implicitCast>(lists)); +} +template +inline Orphan>>> +Orphanage::newOrphanConcat(kj::ArrayPtr lists) const { + // Optimization / simplification: Rely on List::Reader containing nothing except a + // _::ListReader. + static_assert(sizeof(T) == sizeof(_::ListReader), "lists are not bare readers?"); + kj::ArrayPtr raw( + reinterpret_cast(lists.begin()), lists.size()); + typedef ListElementType> Element; + return Orphan>( + _::OrphanBuilder::concat(arena, capTable, + _::elementSizeForType(), + _::minStructSizeForElement(), raw)); +} + +inline Orphan Orphanage::referenceExternalData(Data::Reader data) const { + return Orphan(_::OrphanBuilder::referenceExternalData(arena, data)); +} + +} // namespace capnp + +#endif // CAPNP_ORPHAN_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/persistent.capnp.h --- a/win32-mingw/include/capnp/persistent.capnp.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/persistent.capnp.h Tue May 23 09:16:54 2017 +0100 @@ -1,1328 +1,1328 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: persistent.capnp - -#ifndef CAPNP_INCLUDED_b8630836983feed7_ -#define CAPNP_INCLUDED_b8630836983feed7_ - -#include -#if !CAPNP_LITE -#include -#endif // !CAPNP_LITE - -#if CAPNP_VERSION != 6000 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(c8cb212fcd9f5691); -CAPNP_DECLARE_SCHEMA(f76fba59183073a5); -CAPNP_DECLARE_SCHEMA(b76848c18c40efbf); -CAPNP_DECLARE_SCHEMA(84ff286cd00a3ed4); -CAPNP_DECLARE_SCHEMA(f0c2cc1d3909574d); -CAPNP_DECLARE_SCHEMA(ecafa18b482da3aa); -CAPNP_DECLARE_SCHEMA(f622595091cafb67); - -} // namespace schemas -} // namespace capnp - -namespace capnp { - -template -struct Persistent { - Persistent() = delete; - -#if !CAPNP_LITE - class Client; - class Server; -#endif // !CAPNP_LITE - - struct SaveParams; - struct SaveResults; - - #if !CAPNP_LITE - struct _capnpPrivate { - CAPNP_DECLARE_INTERFACE_HEADER(c8cb212fcd9f5691) - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand; - }; - #endif // !CAPNP_LITE -}; - -template -struct Persistent::SaveParams { - SaveParams() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f76fba59183073a5, 0, 1) - #if !CAPNP_LITE - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand; - #endif // !CAPNP_LITE - }; -}; - -template -struct Persistent::SaveResults { - SaveResults() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b76848c18c40efbf, 0, 1) - #if !CAPNP_LITE - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand; - #endif // !CAPNP_LITE - }; -}; - -template -struct RealmGateway { - RealmGateway() = delete; - -#if !CAPNP_LITE - class Client; - class Server; -#endif // !CAPNP_LITE - - struct ImportParams; - struct ExportParams; - - #if !CAPNP_LITE - struct _capnpPrivate { - CAPNP_DECLARE_INTERFACE_HEADER(84ff286cd00a3ed4) - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand; - }; - #endif // !CAPNP_LITE -}; - -template -struct RealmGateway::ImportParams { - ImportParams() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f0c2cc1d3909574d, 0, 2) - #if !CAPNP_LITE - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand; - #endif // !CAPNP_LITE - }; -}; - -template -struct RealmGateway::ExportParams { - ExportParams() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ecafa18b482da3aa, 0, 2) - #if !CAPNP_LITE - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand; - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -#if !CAPNP_LITE -template -class Persistent::Client - : public virtual ::capnp::Capability::Client { -public: - typedef Persistent Calls; - typedef Persistent Reads; - - Client(decltype(nullptr)); - explicit Client(::kj::Own< ::capnp::ClientHook>&& hook); - template ()>> - Client(::kj::Own<_t>&& server); - template ()>> - Client(::kj::Promise<_t>&& promise); - Client(::kj::Exception&& exception); - Client(Client&) = default; - Client(Client&&) = default; - Client& operator=(Client& other); - Client& operator=(Client&& other); - - template - typename Persistent::Client asGeneric() { - return castAs>(); - } - - ::capnp::Request::SaveParams, typename ::capnp::Persistent::SaveResults> saveRequest( - ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); - -protected: - Client() = default; -}; - -template -class Persistent::Server - : public virtual ::capnp::Capability::Server { -public: - typedef Persistent Serves; - - ::kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) - override; - -protected: - typedef ::capnp::CallContext::SaveParams, typename ::capnp::Persistent::SaveResults> SaveContext; - virtual ::kj::Promise save(SaveContext context); - - inline typename ::capnp::Persistent::Client thisCap() { - return ::capnp::Capability::Server::thisCap() - .template castAs< ::capnp::Persistent>(); - } - - ::kj::Promise dispatchCallInternal(uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context); -}; -#endif // !CAPNP_LITE - -template -class Persistent::SaveParams::Reader { -public: - typedef SaveParams Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - template - typename Persistent::SaveParams::Reader asPersistentGeneric() { - return typename Persistent::SaveParams::Reader(_reader); - } - - inline bool hasSealFor() const; - inline ::capnp::ReaderFor getSealFor() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -template -class Persistent::SaveParams::Builder { -public: - typedef SaveParams Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - template - typename Persistent::SaveParams::Builder asPersistentGeneric() { - return typename Persistent::SaveParams::Builder(_builder); - } - - inline bool hasSealFor(); - inline ::capnp::BuilderFor getSealFor(); - inline void setSealFor( ::capnp::ReaderFor value); - inline ::capnp::BuilderFor initSealFor(); - inline ::capnp::BuilderFor initSealFor(unsigned int size); - inline void adoptSealFor(::capnp::Orphan&& value); - inline ::capnp::Orphan disownSealFor(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -template -class Persistent::SaveParams::Pipeline { -public: - typedef SaveParams Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::PipelineFor getSealFor(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -template -class Persistent::SaveResults::Reader { -public: - typedef SaveResults Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - template - typename Persistent::SaveResults::Reader asPersistentGeneric() { - return typename Persistent::SaveResults::Reader(_reader); - } - - inline bool hasSturdyRef() const; - inline ::capnp::ReaderFor getSturdyRef() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -template -class Persistent::SaveResults::Builder { -public: - typedef SaveResults Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - template - typename Persistent::SaveResults::Builder asPersistentGeneric() { - return typename Persistent::SaveResults::Builder(_builder); - } - - inline bool hasSturdyRef(); - inline ::capnp::BuilderFor getSturdyRef(); - inline void setSturdyRef( ::capnp::ReaderFor value); - inline ::capnp::BuilderFor initSturdyRef(); - inline ::capnp::BuilderFor initSturdyRef(unsigned int size); - inline void adoptSturdyRef(::capnp::Orphan&& value); - inline ::capnp::Orphan disownSturdyRef(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -template -class Persistent::SaveResults::Pipeline { -public: - typedef SaveResults Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::PipelineFor getSturdyRef(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -#if !CAPNP_LITE -template -class RealmGateway::Client - : public virtual ::capnp::Capability::Client { -public: - typedef RealmGateway Calls; - typedef RealmGateway Reads; - - Client(decltype(nullptr)); - explicit Client(::kj::Own< ::capnp::ClientHook>&& hook); - template ()>> - Client(::kj::Own<_t>&& server); - template ()>> - Client(::kj::Promise<_t>&& promise); - Client(::kj::Exception&& exception); - Client(Client&) = default; - Client(Client&&) = default; - Client& operator=(Client& other); - Client& operator=(Client&& other); - - template - typename RealmGateway::Client asGeneric() { - return castAs>(); - } - - ::capnp::Request::ImportParams, typename ::capnp::Persistent::SaveResults> importRequest( - ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); - ::capnp::Request::ExportParams, typename ::capnp::Persistent::SaveResults> exportRequest( - ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); - -protected: - Client() = default; -}; - -template -class RealmGateway::Server - : public virtual ::capnp::Capability::Server { -public: - typedef RealmGateway Serves; - - ::kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) - override; - -protected: - typedef typename ::capnp::RealmGateway::ImportParams ImportParams; - typedef ::capnp::CallContext::SaveResults> ImportContext; - virtual ::kj::Promise import(ImportContext context); - typedef typename ::capnp::RealmGateway::ExportParams ExportParams; - typedef ::capnp::CallContext::SaveResults> ExportContext; - virtual ::kj::Promise export_(ExportContext context); - - inline typename ::capnp::RealmGateway::Client thisCap() { - return ::capnp::Capability::Server::thisCap() - .template castAs< ::capnp::RealmGateway>(); - } - - ::kj::Promise dispatchCallInternal(uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context); -}; -#endif // !CAPNP_LITE - -template -class RealmGateway::ImportParams::Reader { -public: - typedef ImportParams Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - template - typename RealmGateway::ImportParams::Reader asRealmGatewayGeneric() { - return typename RealmGateway::ImportParams::Reader(_reader); - } - - inline bool hasCap() const; -#if !CAPNP_LITE - inline typename ::capnp::Persistent::Client getCap() const; -#endif // !CAPNP_LITE - - inline bool hasParams() const; - inline typename ::capnp::Persistent::SaveParams::Reader getParams() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -template -class RealmGateway::ImportParams::Builder { -public: - typedef ImportParams Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - template - typename RealmGateway::ImportParams::Builder asRealmGatewayGeneric() { - return typename RealmGateway::ImportParams::Builder(_builder); - } - - inline bool hasCap(); -#if !CAPNP_LITE - inline typename ::capnp::Persistent::Client getCap(); - inline void setCap(typename ::capnp::Persistent::Client&& value); - inline void setCap(typename ::capnp::Persistent::Client& value); - inline void adoptCap(::capnp::Orphan< ::capnp::Persistent>&& value); - inline ::capnp::Orphan< ::capnp::Persistent> disownCap(); -#endif // !CAPNP_LITE - - inline bool hasParams(); - inline typename ::capnp::Persistent::SaveParams::Builder getParams(); - inline void setParams(typename ::capnp::Persistent::SaveParams::Reader value); - inline typename ::capnp::Persistent::SaveParams::Builder initParams(); - inline void adoptParams(::capnp::Orphan::SaveParams>&& value); - inline ::capnp::Orphan::SaveParams> disownParams(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -template -class RealmGateway::ImportParams::Pipeline { -public: - typedef ImportParams Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline typename ::capnp::Persistent::Client getCap(); - inline typename ::capnp::Persistent::SaveParams::Pipeline getParams(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -template -class RealmGateway::ExportParams::Reader { -public: - typedef ExportParams Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - template - typename RealmGateway::ExportParams::Reader asRealmGatewayGeneric() { - return typename RealmGateway::ExportParams::Reader(_reader); - } - - inline bool hasCap() const; -#if !CAPNP_LITE - inline typename ::capnp::Persistent::Client getCap() const; -#endif // !CAPNP_LITE - - inline bool hasParams() const; - inline typename ::capnp::Persistent::SaveParams::Reader getParams() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -template -class RealmGateway::ExportParams::Builder { -public: - typedef ExportParams Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - template - typename RealmGateway::ExportParams::Builder asRealmGatewayGeneric() { - return typename RealmGateway::ExportParams::Builder(_builder); - } - - inline bool hasCap(); -#if !CAPNP_LITE - inline typename ::capnp::Persistent::Client getCap(); - inline void setCap(typename ::capnp::Persistent::Client&& value); - inline void setCap(typename ::capnp::Persistent::Client& value); - inline void adoptCap(::capnp::Orphan< ::capnp::Persistent>&& value); - inline ::capnp::Orphan< ::capnp::Persistent> disownCap(); -#endif // !CAPNP_LITE - - inline bool hasParams(); - inline typename ::capnp::Persistent::SaveParams::Builder getParams(); - inline void setParams(typename ::capnp::Persistent::SaveParams::Reader value); - inline typename ::capnp::Persistent::SaveParams::Builder initParams(); - inline void adoptParams(::capnp::Orphan::SaveParams>&& value); - inline ::capnp::Orphan::SaveParams> disownParams(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -template -class RealmGateway::ExportParams::Pipeline { -public: - typedef ExportParams Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline typename ::capnp::Persistent::Client getCap(); - inline typename ::capnp::Persistent::SaveParams::Pipeline getParams(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -#if !CAPNP_LITE -template -inline Persistent::Client::Client(decltype(nullptr)) - : ::capnp::Capability::Client(nullptr) {} -template -inline Persistent::Client::Client( - ::kj::Own< ::capnp::ClientHook>&& hook) - : ::capnp::Capability::Client(::kj::mv(hook)) {} -template -template -inline Persistent::Client::Client(::kj::Own<_t>&& server) - : ::capnp::Capability::Client(::kj::mv(server)) {} -template -template -inline Persistent::Client::Client(::kj::Promise<_t>&& promise) - : ::capnp::Capability::Client(::kj::mv(promise)) {} -template -inline Persistent::Client::Client(::kj::Exception&& exception) - : ::capnp::Capability::Client(::kj::mv(exception)) {} -template -inline typename ::capnp::Persistent::Client& Persistent::Client::operator=(Client& other) { - ::capnp::Capability::Client::operator=(other); - return *this; -} -template -inline typename ::capnp::Persistent::Client& Persistent::Client::operator=(Client&& other) { - ::capnp::Capability::Client::operator=(kj::mv(other)); - return *this; -} - -#endif // !CAPNP_LITE -template -inline bool Persistent::SaveParams::Reader::hasSealFor() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -template -inline bool Persistent::SaveParams::Builder::hasSealFor() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -template -inline ::capnp::ReaderFor Persistent::SaveParams::Reader::getSealFor() const { - return ::capnp::_::PointerHelpers::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -template -inline ::capnp::BuilderFor Persistent::SaveParams::Builder::getSealFor() { - return ::capnp::_::PointerHelpers::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -template -inline ::capnp::PipelineFor Persistent::SaveParams::Pipeline::getSealFor() { - return ::capnp::PipelineFor(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -template -inline void Persistent::SaveParams::Builder::setSealFor( ::capnp::ReaderFor value) { - ::capnp::_::PointerHelpers::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -template -inline ::capnp::BuilderFor Persistent::SaveParams::Builder::initSealFor() { - return ::capnp::_::PointerHelpers::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -template -inline ::capnp::BuilderFor Persistent::SaveParams::Builder::initSealFor(unsigned int size) { - return ::capnp::_::PointerHelpers::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -template -inline void Persistent::SaveParams::Builder::adoptSealFor( - ::capnp::Orphan&& value) { - ::capnp::_::PointerHelpers::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan Persistent::SaveParams::Builder::disownSealFor() { - return ::capnp::_::PointerHelpers::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -// Persistent::SaveParams -template -constexpr uint16_t Persistent::SaveParams::_capnpPrivate::dataWordSize; -template -constexpr uint16_t Persistent::SaveParams::_capnpPrivate::pointerCount; -#if !CAPNP_LITE -template -constexpr ::capnp::Kind Persistent::SaveParams::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* Persistent::SaveParams::_capnpPrivate::schema; -template -constexpr ::capnp::_::RawBrandedSchema const* Persistent::SaveParams::_capnpPrivate::brand; -template -const ::capnp::_::RawBrandedSchema::Scope Persistent::SaveParams::_capnpPrivate::brandScopes[] = { - { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding Persistent::SaveParams::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema Persistent::SaveParams::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_f76fba59183073a5, brandScopes, nullptr, - sizeof(brandScopes) / sizeof(brandScopes[0]), 0, nullptr -}; -#endif // !CAPNP_LITE - -template -inline bool Persistent::SaveResults::Reader::hasSturdyRef() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -template -inline bool Persistent::SaveResults::Builder::hasSturdyRef() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -template -inline ::capnp::ReaderFor Persistent::SaveResults::Reader::getSturdyRef() const { - return ::capnp::_::PointerHelpers::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -template -inline ::capnp::BuilderFor Persistent::SaveResults::Builder::getSturdyRef() { - return ::capnp::_::PointerHelpers::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -template -inline ::capnp::PipelineFor Persistent::SaveResults::Pipeline::getSturdyRef() { - return ::capnp::PipelineFor(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -template -inline void Persistent::SaveResults::Builder::setSturdyRef( ::capnp::ReaderFor value) { - ::capnp::_::PointerHelpers::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -template -inline ::capnp::BuilderFor Persistent::SaveResults::Builder::initSturdyRef() { - return ::capnp::_::PointerHelpers::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -template -inline ::capnp::BuilderFor Persistent::SaveResults::Builder::initSturdyRef(unsigned int size) { - return ::capnp::_::PointerHelpers::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -template -inline void Persistent::SaveResults::Builder::adoptSturdyRef( - ::capnp::Orphan&& value) { - ::capnp::_::PointerHelpers::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan Persistent::SaveResults::Builder::disownSturdyRef() { - return ::capnp::_::PointerHelpers::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -// Persistent::SaveResults -template -constexpr uint16_t Persistent::SaveResults::_capnpPrivate::dataWordSize; -template -constexpr uint16_t Persistent::SaveResults::_capnpPrivate::pointerCount; -#if !CAPNP_LITE -template -constexpr ::capnp::Kind Persistent::SaveResults::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* Persistent::SaveResults::_capnpPrivate::schema; -template -constexpr ::capnp::_::RawBrandedSchema const* Persistent::SaveResults::_capnpPrivate::brand; -template -const ::capnp::_::RawBrandedSchema::Scope Persistent::SaveResults::_capnpPrivate::brandScopes[] = { - { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding Persistent::SaveResults::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema Persistent::SaveResults::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_b76848c18c40efbf, brandScopes, nullptr, - sizeof(brandScopes) / sizeof(brandScopes[0]), 0, nullptr -}; -#endif // !CAPNP_LITE - -#if !CAPNP_LITE -template -::capnp::Request::SaveParams, typename ::capnp::Persistent::SaveResults> -Persistent::Client::saveRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { - return newCall::SaveParams, typename ::capnp::Persistent::SaveResults>( - 0xc8cb212fcd9f5691ull, 0, sizeHint); -} -template -::kj::Promise Persistent::Server::save(SaveContext) { - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:Persistent", "save", - 0xc8cb212fcd9f5691ull, 0); -} -template -::kj::Promise Persistent::Server::dispatchCall( - uint64_t interfaceId, uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { - switch (interfaceId) { - case 0xc8cb212fcd9f5691ull: - return dispatchCallInternal(methodId, context); - default: - return internalUnimplemented("capnp/persistent.capnp:Persistent", interfaceId); - } -} -template -::kj::Promise Persistent::Server::dispatchCallInternal( - uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { - switch (methodId) { - case 0: - return save(::capnp::Capability::Server::internalGetTypedContext< - typename ::capnp::Persistent::SaveParams, typename ::capnp::Persistent::SaveResults>(context)); - default: - (void)context; - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:Persistent", - 0xc8cb212fcd9f5691ull, methodId); - } -} -#endif // !CAPNP_LITE - -// Persistent -#if !CAPNP_LITE -template -constexpr ::capnp::Kind Persistent::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* Persistent::_capnpPrivate::schema; -template -constexpr ::capnp::_::RawBrandedSchema const* Persistent::_capnpPrivate::brand; -template -const ::capnp::_::RawBrandedSchema::Scope Persistent::_capnpPrivate::brandScopes[] = { - { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding Persistent::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema::Dependency Persistent::_capnpPrivate::brandDependencies[] = { - { 33554432, ::capnp::Persistent::SaveParams::_capnpPrivate::brand }, - { 50331648, ::capnp::Persistent::SaveResults::_capnpPrivate::brand }, -}; -template -const ::capnp::_::RawBrandedSchema Persistent::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_c8cb212fcd9f5691, brandScopes, brandDependencies, - sizeof(brandScopes) / sizeof(brandScopes[0]), sizeof(brandDependencies) / sizeof(brandDependencies[0]), nullptr -}; -#endif // !CAPNP_LITE - -#if !CAPNP_LITE -template -inline RealmGateway::Client::Client(decltype(nullptr)) - : ::capnp::Capability::Client(nullptr) {} -template -inline RealmGateway::Client::Client( - ::kj::Own< ::capnp::ClientHook>&& hook) - : ::capnp::Capability::Client(::kj::mv(hook)) {} -template -template -inline RealmGateway::Client::Client(::kj::Own<_t>&& server) - : ::capnp::Capability::Client(::kj::mv(server)) {} -template -template -inline RealmGateway::Client::Client(::kj::Promise<_t>&& promise) - : ::capnp::Capability::Client(::kj::mv(promise)) {} -template -inline RealmGateway::Client::Client(::kj::Exception&& exception) - : ::capnp::Capability::Client(::kj::mv(exception)) {} -template -inline typename ::capnp::RealmGateway::Client& RealmGateway::Client::operator=(Client& other) { - ::capnp::Capability::Client::operator=(other); - return *this; -} -template -inline typename ::capnp::RealmGateway::Client& RealmGateway::Client::operator=(Client&& other) { - ::capnp::Capability::Client::operator=(kj::mv(other)); - return *this; -} - -#endif // !CAPNP_LITE -template -inline bool RealmGateway::ImportParams::Reader::hasCap() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -template -inline bool RealmGateway::ImportParams::Builder::hasCap() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -#if !CAPNP_LITE -template -inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Reader::getCap() const { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Builder::getCap() { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Pipeline::getCap() { - return typename ::capnp::Persistent::Client(_typeless.getPointerField(0).asCap()); -} -template -inline void RealmGateway::ImportParams::Builder::setCap(typename ::capnp::Persistent::Client&& cap) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(cap)); -} -template -inline void RealmGateway::ImportParams::Builder::setCap(typename ::capnp::Persistent::Client& cap) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), cap); -} -template -inline void RealmGateway::ImportParams::Builder::adoptCap( - ::capnp::Orphan< ::capnp::Persistent>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan< ::capnp::Persistent> RealmGateway::ImportParams::Builder::disownCap() { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#endif // !CAPNP_LITE - -template -inline bool RealmGateway::ImportParams::Reader::hasParams() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -template -inline bool RealmGateway::ImportParams::Builder::hasParams() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -template -inline typename ::capnp::Persistent::SaveParams::Reader RealmGateway::ImportParams::Reader::getParams() const { - return ::capnp::_::PointerHelpers::SaveParams>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ImportParams::Builder::getParams() { - return ::capnp::_::PointerHelpers::SaveParams>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -template -inline typename ::capnp::Persistent::SaveParams::Pipeline RealmGateway::ImportParams::Pipeline::getParams() { - return typename ::capnp::Persistent::SaveParams::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -template -inline void RealmGateway::ImportParams::Builder::setParams(typename ::capnp::Persistent::SaveParams::Reader value) { - ::capnp::_::PointerHelpers::SaveParams>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -template -inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ImportParams::Builder::initParams() { - return ::capnp::_::PointerHelpers::SaveParams>::init( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -template -inline void RealmGateway::ImportParams::Builder::adoptParams( - ::capnp::Orphan::SaveParams>&& value) { - ::capnp::_::PointerHelpers::SaveParams>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan::SaveParams> RealmGateway::ImportParams::Builder::disownParams() { - return ::capnp::_::PointerHelpers::SaveParams>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -// RealmGateway::ImportParams -template -constexpr uint16_t RealmGateway::ImportParams::_capnpPrivate::dataWordSize; -template -constexpr uint16_t RealmGateway::ImportParams::_capnpPrivate::pointerCount; -#if !CAPNP_LITE -template -constexpr ::capnp::Kind RealmGateway::ImportParams::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* RealmGateway::ImportParams::_capnpPrivate::schema; -template -constexpr ::capnp::_::RawBrandedSchema const* RealmGateway::ImportParams::_capnpPrivate::brand; -template -const ::capnp::_::RawBrandedSchema::Scope RealmGateway::ImportParams::_capnpPrivate::brandScopes[] = { - { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding RealmGateway::ImportParams::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::ImportParams::_capnpPrivate::brandDependencies[] = { - { 16777216, ::capnp::Persistent::_capnpPrivate::brand }, - { 16777217, ::capnp::Persistent::SaveParams::_capnpPrivate::brand }, -}; -template -const ::capnp::_::RawBrandedSchema RealmGateway::ImportParams::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_f0c2cc1d3909574d, brandScopes, brandDependencies, - sizeof(brandScopes) / sizeof(brandScopes[0]), sizeof(brandDependencies) / sizeof(brandDependencies[0]), nullptr -}; -#endif // !CAPNP_LITE - -template -inline bool RealmGateway::ExportParams::Reader::hasCap() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -template -inline bool RealmGateway::ExportParams::Builder::hasCap() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -#if !CAPNP_LITE -template -inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Reader::getCap() const { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Builder::getCap() { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Pipeline::getCap() { - return typename ::capnp::Persistent::Client(_typeless.getPointerField(0).asCap()); -} -template -inline void RealmGateway::ExportParams::Builder::setCap(typename ::capnp::Persistent::Client&& cap) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(cap)); -} -template -inline void RealmGateway::ExportParams::Builder::setCap(typename ::capnp::Persistent::Client& cap) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), cap); -} -template -inline void RealmGateway::ExportParams::Builder::adoptCap( - ::capnp::Orphan< ::capnp::Persistent>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan< ::capnp::Persistent> RealmGateway::ExportParams::Builder::disownCap() { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#endif // !CAPNP_LITE - -template -inline bool RealmGateway::ExportParams::Reader::hasParams() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -template -inline bool RealmGateway::ExportParams::Builder::hasParams() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -template -inline typename ::capnp::Persistent::SaveParams::Reader RealmGateway::ExportParams::Reader::getParams() const { - return ::capnp::_::PointerHelpers::SaveParams>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ExportParams::Builder::getParams() { - return ::capnp::_::PointerHelpers::SaveParams>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -template -inline typename ::capnp::Persistent::SaveParams::Pipeline RealmGateway::ExportParams::Pipeline::getParams() { - return typename ::capnp::Persistent::SaveParams::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -template -inline void RealmGateway::ExportParams::Builder::setParams(typename ::capnp::Persistent::SaveParams::Reader value) { - ::capnp::_::PointerHelpers::SaveParams>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -template -inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ExportParams::Builder::initParams() { - return ::capnp::_::PointerHelpers::SaveParams>::init( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -template -inline void RealmGateway::ExportParams::Builder::adoptParams( - ::capnp::Orphan::SaveParams>&& value) { - ::capnp::_::PointerHelpers::SaveParams>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan::SaveParams> RealmGateway::ExportParams::Builder::disownParams() { - return ::capnp::_::PointerHelpers::SaveParams>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -// RealmGateway::ExportParams -template -constexpr uint16_t RealmGateway::ExportParams::_capnpPrivate::dataWordSize; -template -constexpr uint16_t RealmGateway::ExportParams::_capnpPrivate::pointerCount; -#if !CAPNP_LITE -template -constexpr ::capnp::Kind RealmGateway::ExportParams::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* RealmGateway::ExportParams::_capnpPrivate::schema; -template -constexpr ::capnp::_::RawBrandedSchema const* RealmGateway::ExportParams::_capnpPrivate::brand; -template -const ::capnp::_::RawBrandedSchema::Scope RealmGateway::ExportParams::_capnpPrivate::brandScopes[] = { - { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding RealmGateway::ExportParams::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::ExportParams::_capnpPrivate::brandDependencies[] = { - { 16777216, ::capnp::Persistent::_capnpPrivate::brand }, - { 16777217, ::capnp::Persistent::SaveParams::_capnpPrivate::brand }, -}; -template -const ::capnp::_::RawBrandedSchema RealmGateway::ExportParams::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_ecafa18b482da3aa, brandScopes, brandDependencies, - sizeof(brandScopes) / sizeof(brandScopes[0]), sizeof(brandDependencies) / sizeof(brandDependencies[0]), nullptr -}; -#endif // !CAPNP_LITE - -#if !CAPNP_LITE -template -::capnp::Request::ImportParams, typename ::capnp::Persistent::SaveResults> -RealmGateway::Client::importRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { - return newCall::ImportParams, typename ::capnp::Persistent::SaveResults>( - 0x84ff286cd00a3ed4ull, 0, sizeHint); -} -template -::kj::Promise RealmGateway::Server::import(ImportContext) { - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:RealmGateway", "import", - 0x84ff286cd00a3ed4ull, 0); -} -template -::capnp::Request::ExportParams, typename ::capnp::Persistent::SaveResults> -RealmGateway::Client::exportRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { - return newCall::ExportParams, typename ::capnp::Persistent::SaveResults>( - 0x84ff286cd00a3ed4ull, 1, sizeHint); -} -template -::kj::Promise RealmGateway::Server::export_(ExportContext) { - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:RealmGateway", "export", - 0x84ff286cd00a3ed4ull, 1); -} -template -::kj::Promise RealmGateway::Server::dispatchCall( - uint64_t interfaceId, uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { - switch (interfaceId) { - case 0x84ff286cd00a3ed4ull: - return dispatchCallInternal(methodId, context); - default: - return internalUnimplemented("capnp/persistent.capnp:RealmGateway", interfaceId); - } -} -template -::kj::Promise RealmGateway::Server::dispatchCallInternal( - uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { - switch (methodId) { - case 0: - return import(::capnp::Capability::Server::internalGetTypedContext< - typename ::capnp::RealmGateway::ImportParams, typename ::capnp::Persistent::SaveResults>(context)); - case 1: - return export_(::capnp::Capability::Server::internalGetTypedContext< - typename ::capnp::RealmGateway::ExportParams, typename ::capnp::Persistent::SaveResults>(context)); - default: - (void)context; - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:RealmGateway", - 0x84ff286cd00a3ed4ull, methodId); - } -} -#endif // !CAPNP_LITE - -// RealmGateway -#if !CAPNP_LITE -template -constexpr ::capnp::Kind RealmGateway::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* RealmGateway::_capnpPrivate::schema; -template -constexpr ::capnp::_::RawBrandedSchema const* RealmGateway::_capnpPrivate::brand; -template -const ::capnp::_::RawBrandedSchema::Scope RealmGateway::_capnpPrivate::brandScopes[] = { - { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding RealmGateway::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::_capnpPrivate::brandDependencies[] = { - { 33554432, ::capnp::RealmGateway::ImportParams::_capnpPrivate::brand }, - { 33554433, ::capnp::RealmGateway::ExportParams::_capnpPrivate::brand }, - { 50331648, ::capnp::Persistent::SaveResults::_capnpPrivate::brand }, - { 50331649, ::capnp::Persistent::SaveResults::_capnpPrivate::brand }, -}; -template -const ::capnp::_::RawBrandedSchema RealmGateway::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_84ff286cd00a3ed4, brandScopes, brandDependencies, - sizeof(brandScopes) / sizeof(brandScopes[0]), sizeof(brandDependencies) / sizeof(brandDependencies[0]), nullptr -}; -#endif // !CAPNP_LITE - -} // namespace - -#endif // CAPNP_INCLUDED_b8630836983feed7_ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: persistent.capnp + +#ifndef CAPNP_INCLUDED_b8630836983feed7_ +#define CAPNP_INCLUDED_b8630836983feed7_ + +#include +#if !CAPNP_LITE +#include +#endif // !CAPNP_LITE + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(c8cb212fcd9f5691); +CAPNP_DECLARE_SCHEMA(f76fba59183073a5); +CAPNP_DECLARE_SCHEMA(b76848c18c40efbf); +CAPNP_DECLARE_SCHEMA(84ff286cd00a3ed4); +CAPNP_DECLARE_SCHEMA(f0c2cc1d3909574d); +CAPNP_DECLARE_SCHEMA(ecafa18b482da3aa); +CAPNP_DECLARE_SCHEMA(f622595091cafb67); + +} // namespace schemas +} // namespace capnp + +namespace capnp { + +template +struct Persistent { + Persistent() = delete; + +#if !CAPNP_LITE + class Client; + class Server; +#endif // !CAPNP_LITE + + struct SaveParams; + struct SaveResults; + + #if !CAPNP_LITE + struct _capnpPrivate { + CAPNP_DECLARE_INTERFACE_HEADER(c8cb212fcd9f5691) + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand(); } + }; + #endif // !CAPNP_LITE +}; + +template +struct Persistent::SaveParams { + SaveParams() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f76fba59183073a5, 0, 1) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand(); } + #endif // !CAPNP_LITE + }; +}; + +template +struct Persistent::SaveResults { + SaveResults() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b76848c18c40efbf, 0, 1) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand(); } + #endif // !CAPNP_LITE + }; +}; + +template +struct RealmGateway { + RealmGateway() = delete; + +#if !CAPNP_LITE + class Client; + class Server; +#endif // !CAPNP_LITE + + struct ImportParams; + struct ExportParams; + + #if !CAPNP_LITE + struct _capnpPrivate { + CAPNP_DECLARE_INTERFACE_HEADER(84ff286cd00a3ed4) + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand(); } + }; + #endif // !CAPNP_LITE +}; + +template +struct RealmGateway::ImportParams { + ImportParams() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f0c2cc1d3909574d, 0, 2) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand(); } + #endif // !CAPNP_LITE + }; +}; + +template +struct RealmGateway::ExportParams { + ExportParams() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ecafa18b482da3aa, 0, 2) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand(); } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +#if !CAPNP_LITE +template +class Persistent::Client + : public virtual ::capnp::Capability::Client { +public: + typedef Persistent Calls; + typedef Persistent Reads; + + Client(decltype(nullptr)); + explicit Client(::kj::Own< ::capnp::ClientHook>&& hook); + template ()>> + Client(::kj::Own<_t>&& server); + template ()>> + Client(::kj::Promise<_t>&& promise); + Client(::kj::Exception&& exception); + Client(Client&) = default; + Client(Client&&) = default; + Client& operator=(Client& other); + Client& operator=(Client&& other); + + template + typename Persistent::Client asGeneric() { + return castAs>(); + } + + CAPNP_AUTO_IF_MSVC(::capnp::Request::SaveParams, typename ::capnp::Persistent::SaveResults>) saveRequest( + ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); + +protected: + Client() = default; +}; + +template +class Persistent::Server + : public virtual ::capnp::Capability::Server { +public: + typedef Persistent Serves; + + ::kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) + override; + +protected: + typedef ::capnp::CallContext::SaveParams, typename ::capnp::Persistent::SaveResults> SaveContext; + virtual ::kj::Promise save(SaveContext context); + + inline typename ::capnp::Persistent::Client thisCap() { + return ::capnp::Capability::Server::thisCap() + .template castAs< ::capnp::Persistent>(); + } + + ::kj::Promise dispatchCallInternal(uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context); +}; +#endif // !CAPNP_LITE + +template +class Persistent::SaveParams::Reader { +public: + typedef SaveParams Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + template + typename Persistent::SaveParams::Reader asPersistentGeneric() { + return typename Persistent::SaveParams::Reader(_reader); + } + + inline bool hasSealFor() const; + inline ::capnp::ReaderFor getSealFor() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +template +class Persistent::SaveParams::Builder { +public: + typedef SaveParams Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + template + typename Persistent::SaveParams::Builder asPersistentGeneric() { + return typename Persistent::SaveParams::Builder(_builder); + } + + inline bool hasSealFor(); + inline ::capnp::BuilderFor getSealFor(); + inline void setSealFor( ::capnp::ReaderFor value); + inline ::capnp::BuilderFor initSealFor(); + inline ::capnp::BuilderFor initSealFor(unsigned int size); + inline void adoptSealFor(::capnp::Orphan&& value); + inline ::capnp::Orphan disownSealFor(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +template +class Persistent::SaveParams::Pipeline { +public: + typedef SaveParams Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::PipelineFor getSealFor(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +template +class Persistent::SaveResults::Reader { +public: + typedef SaveResults Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + template + typename Persistent::SaveResults::Reader asPersistentGeneric() { + return typename Persistent::SaveResults::Reader(_reader); + } + + inline bool hasSturdyRef() const; + inline ::capnp::ReaderFor getSturdyRef() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +template +class Persistent::SaveResults::Builder { +public: + typedef SaveResults Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + template + typename Persistent::SaveResults::Builder asPersistentGeneric() { + return typename Persistent::SaveResults::Builder(_builder); + } + + inline bool hasSturdyRef(); + inline ::capnp::BuilderFor getSturdyRef(); + inline void setSturdyRef( ::capnp::ReaderFor value); + inline ::capnp::BuilderFor initSturdyRef(); + inline ::capnp::BuilderFor initSturdyRef(unsigned int size); + inline void adoptSturdyRef(::capnp::Orphan&& value); + inline ::capnp::Orphan disownSturdyRef(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +template +class Persistent::SaveResults::Pipeline { +public: + typedef SaveResults Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::PipelineFor getSturdyRef(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +#if !CAPNP_LITE +template +class RealmGateway::Client + : public virtual ::capnp::Capability::Client { +public: + typedef RealmGateway Calls; + typedef RealmGateway Reads; + + Client(decltype(nullptr)); + explicit Client(::kj::Own< ::capnp::ClientHook>&& hook); + template ()>> + Client(::kj::Own<_t>&& server); + template ()>> + Client(::kj::Promise<_t>&& promise); + Client(::kj::Exception&& exception); + Client(Client&) = default; + Client(Client&&) = default; + Client& operator=(Client& other); + Client& operator=(Client&& other); + + template + typename RealmGateway::Client asGeneric() { + return castAs>(); + } + + CAPNP_AUTO_IF_MSVC(::capnp::Request::ImportParams, typename ::capnp::Persistent::SaveResults>) importRequest( + ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); + CAPNP_AUTO_IF_MSVC(::capnp::Request::ExportParams, typename ::capnp::Persistent::SaveResults>) exportRequest( + ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); + +protected: + Client() = default; +}; + +template +class RealmGateway::Server + : public virtual ::capnp::Capability::Server { +public: + typedef RealmGateway Serves; + + ::kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) + override; + +protected: + typedef typename ::capnp::RealmGateway::ImportParams ImportParams; + typedef ::capnp::CallContext::SaveResults> ImportContext; + virtual ::kj::Promise import(ImportContext context); + typedef typename ::capnp::RealmGateway::ExportParams ExportParams; + typedef ::capnp::CallContext::SaveResults> ExportContext; + virtual ::kj::Promise export_(ExportContext context); + + inline typename ::capnp::RealmGateway::Client thisCap() { + return ::capnp::Capability::Server::thisCap() + .template castAs< ::capnp::RealmGateway>(); + } + + ::kj::Promise dispatchCallInternal(uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context); +}; +#endif // !CAPNP_LITE + +template +class RealmGateway::ImportParams::Reader { +public: + typedef ImportParams Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + template + typename RealmGateway::ImportParams::Reader asRealmGatewayGeneric() { + return typename RealmGateway::ImportParams::Reader(_reader); + } + + inline bool hasCap() const; +#if !CAPNP_LITE + inline typename ::capnp::Persistent::Client getCap() const; +#endif // !CAPNP_LITE + + inline bool hasParams() const; + inline typename ::capnp::Persistent::SaveParams::Reader getParams() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +template +class RealmGateway::ImportParams::Builder { +public: + typedef ImportParams Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + template + typename RealmGateway::ImportParams::Builder asRealmGatewayGeneric() { + return typename RealmGateway::ImportParams::Builder(_builder); + } + + inline bool hasCap(); +#if !CAPNP_LITE + inline typename ::capnp::Persistent::Client getCap(); + inline void setCap(typename ::capnp::Persistent::Client&& value); + inline void setCap(typename ::capnp::Persistent::Client& value); + inline void adoptCap(::capnp::Orphan< ::capnp::Persistent>&& value); + inline ::capnp::Orphan< ::capnp::Persistent> disownCap(); +#endif // !CAPNP_LITE + + inline bool hasParams(); + inline typename ::capnp::Persistent::SaveParams::Builder getParams(); + inline void setParams(typename ::capnp::Persistent::SaveParams::Reader value); + inline typename ::capnp::Persistent::SaveParams::Builder initParams(); + inline void adoptParams(::capnp::Orphan::SaveParams>&& value); + inline ::capnp::Orphan::SaveParams> disownParams(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +template +class RealmGateway::ImportParams::Pipeline { +public: + typedef ImportParams Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename ::capnp::Persistent::Client getCap(); + inline typename ::capnp::Persistent::SaveParams::Pipeline getParams(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +template +class RealmGateway::ExportParams::Reader { +public: + typedef ExportParams Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + template + typename RealmGateway::ExportParams::Reader asRealmGatewayGeneric() { + return typename RealmGateway::ExportParams::Reader(_reader); + } + + inline bool hasCap() const; +#if !CAPNP_LITE + inline typename ::capnp::Persistent::Client getCap() const; +#endif // !CAPNP_LITE + + inline bool hasParams() const; + inline typename ::capnp::Persistent::SaveParams::Reader getParams() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +template +class RealmGateway::ExportParams::Builder { +public: + typedef ExportParams Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + template + typename RealmGateway::ExportParams::Builder asRealmGatewayGeneric() { + return typename RealmGateway::ExportParams::Builder(_builder); + } + + inline bool hasCap(); +#if !CAPNP_LITE + inline typename ::capnp::Persistent::Client getCap(); + inline void setCap(typename ::capnp::Persistent::Client&& value); + inline void setCap(typename ::capnp::Persistent::Client& value); + inline void adoptCap(::capnp::Orphan< ::capnp::Persistent>&& value); + inline ::capnp::Orphan< ::capnp::Persistent> disownCap(); +#endif // !CAPNP_LITE + + inline bool hasParams(); + inline typename ::capnp::Persistent::SaveParams::Builder getParams(); + inline void setParams(typename ::capnp::Persistent::SaveParams::Reader value); + inline typename ::capnp::Persistent::SaveParams::Builder initParams(); + inline void adoptParams(::capnp::Orphan::SaveParams>&& value); + inline ::capnp::Orphan::SaveParams> disownParams(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +template +class RealmGateway::ExportParams::Pipeline { +public: + typedef ExportParams Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename ::capnp::Persistent::Client getCap(); + inline typename ::capnp::Persistent::SaveParams::Pipeline getParams(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +#if !CAPNP_LITE +template +inline Persistent::Client::Client(decltype(nullptr)) + : ::capnp::Capability::Client(nullptr) {} +template +inline Persistent::Client::Client( + ::kj::Own< ::capnp::ClientHook>&& hook) + : ::capnp::Capability::Client(::kj::mv(hook)) {} +template +template +inline Persistent::Client::Client(::kj::Own<_t>&& server) + : ::capnp::Capability::Client(::kj::mv(server)) {} +template +template +inline Persistent::Client::Client(::kj::Promise<_t>&& promise) + : ::capnp::Capability::Client(::kj::mv(promise)) {} +template +inline Persistent::Client::Client(::kj::Exception&& exception) + : ::capnp::Capability::Client(::kj::mv(exception)) {} +template +inline typename ::capnp::Persistent::Client& Persistent::Client::operator=(Client& other) { + ::capnp::Capability::Client::operator=(other); + return *this; +} +template +inline typename ::capnp::Persistent::Client& Persistent::Client::operator=(Client&& other) { + ::capnp::Capability::Client::operator=(kj::mv(other)); + return *this; +} + +#endif // !CAPNP_LITE +template +inline bool Persistent::SaveParams::Reader::hasSealFor() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline bool Persistent::SaveParams::Builder::hasSealFor() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline ::capnp::ReaderFor Persistent::SaveParams::Reader::getSealFor() const { + return ::capnp::_::PointerHelpers::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor Persistent::SaveParams::Builder::getSealFor() { + return ::capnp::_::PointerHelpers::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template +inline ::capnp::PipelineFor Persistent::SaveParams::Pipeline::getSealFor() { + return ::capnp::PipelineFor(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +template +inline void Persistent::SaveParams::Builder::setSealFor( ::capnp::ReaderFor value) { + ::capnp::_::PointerHelpers::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +template +inline ::capnp::BuilderFor Persistent::SaveParams::Builder::initSealFor() { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor Persistent::SaveParams::Builder::initSealFor(unsigned int size) { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +template +inline void Persistent::SaveParams::Builder::adoptSealFor( + ::capnp::Orphan&& value) { + ::capnp::_::PointerHelpers::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan Persistent::SaveParams::Builder::disownSealFor() { + return ::capnp::_::PointerHelpers::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +// Persistent::SaveParams +template +constexpr uint16_t Persistent::SaveParams::_capnpPrivate::dataWordSize; +template +constexpr uint16_t Persistent::SaveParams::_capnpPrivate::pointerCount; +#if !CAPNP_LITE +template +constexpr ::capnp::Kind Persistent::SaveParams::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* Persistent::SaveParams::_capnpPrivate::schema; +template +const ::capnp::_::RawBrandedSchema::Scope Persistent::SaveParams::_capnpPrivate::brandScopes[] = { + { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding Persistent::SaveParams::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema Persistent::SaveParams::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_f76fba59183073a5, brandScopes, nullptr, + 1, 0, nullptr +}; +#endif // !CAPNP_LITE + +template +inline bool Persistent::SaveResults::Reader::hasSturdyRef() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline bool Persistent::SaveResults::Builder::hasSturdyRef() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline ::capnp::ReaderFor Persistent::SaveResults::Reader::getSturdyRef() const { + return ::capnp::_::PointerHelpers::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor Persistent::SaveResults::Builder::getSturdyRef() { + return ::capnp::_::PointerHelpers::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template +inline ::capnp::PipelineFor Persistent::SaveResults::Pipeline::getSturdyRef() { + return ::capnp::PipelineFor(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +template +inline void Persistent::SaveResults::Builder::setSturdyRef( ::capnp::ReaderFor value) { + ::capnp::_::PointerHelpers::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +template +inline ::capnp::BuilderFor Persistent::SaveResults::Builder::initSturdyRef() { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor Persistent::SaveResults::Builder::initSturdyRef(unsigned int size) { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +template +inline void Persistent::SaveResults::Builder::adoptSturdyRef( + ::capnp::Orphan&& value) { + ::capnp::_::PointerHelpers::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan Persistent::SaveResults::Builder::disownSturdyRef() { + return ::capnp::_::PointerHelpers::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +// Persistent::SaveResults +template +constexpr uint16_t Persistent::SaveResults::_capnpPrivate::dataWordSize; +template +constexpr uint16_t Persistent::SaveResults::_capnpPrivate::pointerCount; +#if !CAPNP_LITE +template +constexpr ::capnp::Kind Persistent::SaveResults::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* Persistent::SaveResults::_capnpPrivate::schema; +template +const ::capnp::_::RawBrandedSchema::Scope Persistent::SaveResults::_capnpPrivate::brandScopes[] = { + { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding Persistent::SaveResults::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema Persistent::SaveResults::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_b76848c18c40efbf, brandScopes, nullptr, + 1, 0, nullptr +}; +#endif // !CAPNP_LITE + +#if !CAPNP_LITE +template +CAPNP_AUTO_IF_MSVC(::capnp::Request::SaveParams, typename ::capnp::Persistent::SaveResults>) +Persistent::Client::saveRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { + return newCall::SaveParams, typename ::capnp::Persistent::SaveResults>( + 0xc8cb212fcd9f5691ull, 0, sizeHint); +} +template +::kj::Promise Persistent::Server::save(SaveContext) { + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:Persistent", "save", + 0xc8cb212fcd9f5691ull, 0); +} +template +::kj::Promise Persistent::Server::dispatchCall( + uint64_t interfaceId, uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { + switch (interfaceId) { + case 0xc8cb212fcd9f5691ull: + return dispatchCallInternal(methodId, context); + default: + return internalUnimplemented("capnp/persistent.capnp:Persistent", interfaceId); + } +} +template +::kj::Promise Persistent::Server::dispatchCallInternal( + uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { + switch (methodId) { + case 0: + return save(::capnp::Capability::Server::internalGetTypedContext< + typename ::capnp::Persistent::SaveParams, typename ::capnp::Persistent::SaveResults>(context)); + default: + (void)context; + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:Persistent", + 0xc8cb212fcd9f5691ull, methodId); + } +} +#endif // !CAPNP_LITE + +// Persistent +#if !CAPNP_LITE +template +constexpr ::capnp::Kind Persistent::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* Persistent::_capnpPrivate::schema; +template +const ::capnp::_::RawBrandedSchema::Scope Persistent::_capnpPrivate::brandScopes[] = { + { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding Persistent::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema::Dependency Persistent::_capnpPrivate::brandDependencies[] = { + { 33554432, ::capnp::Persistent::SaveParams::_capnpPrivate::brand() }, + { 50331648, ::capnp::Persistent::SaveResults::_capnpPrivate::brand() }, +}; +template +const ::capnp::_::RawBrandedSchema Persistent::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_c8cb212fcd9f5691, brandScopes, brandDependencies, + 1, 2, nullptr +}; +#endif // !CAPNP_LITE + +#if !CAPNP_LITE +template +inline RealmGateway::Client::Client(decltype(nullptr)) + : ::capnp::Capability::Client(nullptr) {} +template +inline RealmGateway::Client::Client( + ::kj::Own< ::capnp::ClientHook>&& hook) + : ::capnp::Capability::Client(::kj::mv(hook)) {} +template +template +inline RealmGateway::Client::Client(::kj::Own<_t>&& server) + : ::capnp::Capability::Client(::kj::mv(server)) {} +template +template +inline RealmGateway::Client::Client(::kj::Promise<_t>&& promise) + : ::capnp::Capability::Client(::kj::mv(promise)) {} +template +inline RealmGateway::Client::Client(::kj::Exception&& exception) + : ::capnp::Capability::Client(::kj::mv(exception)) {} +template +inline typename ::capnp::RealmGateway::Client& RealmGateway::Client::operator=(Client& other) { + ::capnp::Capability::Client::operator=(other); + return *this; +} +template +inline typename ::capnp::RealmGateway::Client& RealmGateway::Client::operator=(Client&& other) { + ::capnp::Capability::Client::operator=(kj::mv(other)); + return *this; +} + +#endif // !CAPNP_LITE +template +inline bool RealmGateway::ImportParams::Reader::hasCap() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline bool RealmGateway::ImportParams::Builder::hasCap() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +#if !CAPNP_LITE +template +inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Reader::getCap() const { + return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Builder::getCap() { + return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Pipeline::getCap() { + return typename ::capnp::Persistent::Client(_typeless.getPointerField(0).asCap()); +} +template +inline void RealmGateway::ImportParams::Builder::setCap(typename ::capnp::Persistent::Client&& cap) { + ::capnp::_::PointerHelpers< ::capnp::Persistent>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(cap)); +} +template +inline void RealmGateway::ImportParams::Builder::setCap(typename ::capnp::Persistent::Client& cap) { + ::capnp::_::PointerHelpers< ::capnp::Persistent>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), cap); +} +template +inline void RealmGateway::ImportParams::Builder::adoptCap( + ::capnp::Orphan< ::capnp::Persistent>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Persistent>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan< ::capnp::Persistent> RealmGateway::ImportParams::Builder::disownCap() { + return ::capnp::_::PointerHelpers< ::capnp::Persistent>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#endif // !CAPNP_LITE + +template +inline bool RealmGateway::ImportParams::Reader::hasParams() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +template +inline bool RealmGateway::ImportParams::Builder::hasParams() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +template +inline typename ::capnp::Persistent::SaveParams::Reader RealmGateway::ImportParams::Reader::getParams() const { + return ::capnp::_::PointerHelpers::SaveParams>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ImportParams::Builder::getParams() { + return ::capnp::_::PointerHelpers::SaveParams>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template +inline typename ::capnp::Persistent::SaveParams::Pipeline RealmGateway::ImportParams::Pipeline::getParams() { + return typename ::capnp::Persistent::SaveParams::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +template +inline void RealmGateway::ImportParams::Builder::setParams(typename ::capnp::Persistent::SaveParams::Reader value) { + ::capnp::_::PointerHelpers::SaveParams>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +template +inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ImportParams::Builder::initParams() { + return ::capnp::_::PointerHelpers::SaveParams>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +template +inline void RealmGateway::ImportParams::Builder::adoptParams( + ::capnp::Orphan::SaveParams>&& value) { + ::capnp::_::PointerHelpers::SaveParams>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan::SaveParams> RealmGateway::ImportParams::Builder::disownParams() { + return ::capnp::_::PointerHelpers::SaveParams>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +// RealmGateway::ImportParams +template +constexpr uint16_t RealmGateway::ImportParams::_capnpPrivate::dataWordSize; +template +constexpr uint16_t RealmGateway::ImportParams::_capnpPrivate::pointerCount; +#if !CAPNP_LITE +template +constexpr ::capnp::Kind RealmGateway::ImportParams::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* RealmGateway::ImportParams::_capnpPrivate::schema; +template +const ::capnp::_::RawBrandedSchema::Scope RealmGateway::ImportParams::_capnpPrivate::brandScopes[] = { + { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding RealmGateway::ImportParams::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::ImportParams::_capnpPrivate::brandDependencies[] = { + { 16777216, ::capnp::Persistent::_capnpPrivate::brand() }, + { 16777217, ::capnp::Persistent::SaveParams::_capnpPrivate::brand() }, +}; +template +const ::capnp::_::RawBrandedSchema RealmGateway::ImportParams::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_f0c2cc1d3909574d, brandScopes, brandDependencies, + 1, 2, nullptr +}; +#endif // !CAPNP_LITE + +template +inline bool RealmGateway::ExportParams::Reader::hasCap() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline bool RealmGateway::ExportParams::Builder::hasCap() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +#if !CAPNP_LITE +template +inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Reader::getCap() const { + return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Builder::getCap() { + return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Pipeline::getCap() { + return typename ::capnp::Persistent::Client(_typeless.getPointerField(0).asCap()); +} +template +inline void RealmGateway::ExportParams::Builder::setCap(typename ::capnp::Persistent::Client&& cap) { + ::capnp::_::PointerHelpers< ::capnp::Persistent>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(cap)); +} +template +inline void RealmGateway::ExportParams::Builder::setCap(typename ::capnp::Persistent::Client& cap) { + ::capnp::_::PointerHelpers< ::capnp::Persistent>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), cap); +} +template +inline void RealmGateway::ExportParams::Builder::adoptCap( + ::capnp::Orphan< ::capnp::Persistent>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Persistent>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan< ::capnp::Persistent> RealmGateway::ExportParams::Builder::disownCap() { + return ::capnp::_::PointerHelpers< ::capnp::Persistent>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#endif // !CAPNP_LITE + +template +inline bool RealmGateway::ExportParams::Reader::hasParams() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +template +inline bool RealmGateway::ExportParams::Builder::hasParams() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +template +inline typename ::capnp::Persistent::SaveParams::Reader RealmGateway::ExportParams::Reader::getParams() const { + return ::capnp::_::PointerHelpers::SaveParams>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ExportParams::Builder::getParams() { + return ::capnp::_::PointerHelpers::SaveParams>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template +inline typename ::capnp::Persistent::SaveParams::Pipeline RealmGateway::ExportParams::Pipeline::getParams() { + return typename ::capnp::Persistent::SaveParams::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +template +inline void RealmGateway::ExportParams::Builder::setParams(typename ::capnp::Persistent::SaveParams::Reader value) { + ::capnp::_::PointerHelpers::SaveParams>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +template +inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ExportParams::Builder::initParams() { + return ::capnp::_::PointerHelpers::SaveParams>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +template +inline void RealmGateway::ExportParams::Builder::adoptParams( + ::capnp::Orphan::SaveParams>&& value) { + ::capnp::_::PointerHelpers::SaveParams>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan::SaveParams> RealmGateway::ExportParams::Builder::disownParams() { + return ::capnp::_::PointerHelpers::SaveParams>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +// RealmGateway::ExportParams +template +constexpr uint16_t RealmGateway::ExportParams::_capnpPrivate::dataWordSize; +template +constexpr uint16_t RealmGateway::ExportParams::_capnpPrivate::pointerCount; +#if !CAPNP_LITE +template +constexpr ::capnp::Kind RealmGateway::ExportParams::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* RealmGateway::ExportParams::_capnpPrivate::schema; +template +const ::capnp::_::RawBrandedSchema::Scope RealmGateway::ExportParams::_capnpPrivate::brandScopes[] = { + { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding RealmGateway::ExportParams::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::ExportParams::_capnpPrivate::brandDependencies[] = { + { 16777216, ::capnp::Persistent::_capnpPrivate::brand() }, + { 16777217, ::capnp::Persistent::SaveParams::_capnpPrivate::brand() }, +}; +template +const ::capnp::_::RawBrandedSchema RealmGateway::ExportParams::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_ecafa18b482da3aa, brandScopes, brandDependencies, + 1, 2, nullptr +}; +#endif // !CAPNP_LITE + +#if !CAPNP_LITE +template +CAPNP_AUTO_IF_MSVC(::capnp::Request::ImportParams, typename ::capnp::Persistent::SaveResults>) +RealmGateway::Client::importRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { + return newCall::ImportParams, typename ::capnp::Persistent::SaveResults>( + 0x84ff286cd00a3ed4ull, 0, sizeHint); +} +template +::kj::Promise RealmGateway::Server::import(ImportContext) { + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:RealmGateway", "import", + 0x84ff286cd00a3ed4ull, 0); +} +template +CAPNP_AUTO_IF_MSVC(::capnp::Request::ExportParams, typename ::capnp::Persistent::SaveResults>) +RealmGateway::Client::exportRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { + return newCall::ExportParams, typename ::capnp::Persistent::SaveResults>( + 0x84ff286cd00a3ed4ull, 1, sizeHint); +} +template +::kj::Promise RealmGateway::Server::export_(ExportContext) { + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:RealmGateway", "export", + 0x84ff286cd00a3ed4ull, 1); +} +template +::kj::Promise RealmGateway::Server::dispatchCall( + uint64_t interfaceId, uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { + switch (interfaceId) { + case 0x84ff286cd00a3ed4ull: + return dispatchCallInternal(methodId, context); + default: + return internalUnimplemented("capnp/persistent.capnp:RealmGateway", interfaceId); + } +} +template +::kj::Promise RealmGateway::Server::dispatchCallInternal( + uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { + switch (methodId) { + case 0: + return import(::capnp::Capability::Server::internalGetTypedContext< + typename ::capnp::RealmGateway::ImportParams, typename ::capnp::Persistent::SaveResults>(context)); + case 1: + return export_(::capnp::Capability::Server::internalGetTypedContext< + typename ::capnp::RealmGateway::ExportParams, typename ::capnp::Persistent::SaveResults>(context)); + default: + (void)context; + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:RealmGateway", + 0x84ff286cd00a3ed4ull, methodId); + } +} +#endif // !CAPNP_LITE + +// RealmGateway +#if !CAPNP_LITE +template +constexpr ::capnp::Kind RealmGateway::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* RealmGateway::_capnpPrivate::schema; +template +const ::capnp::_::RawBrandedSchema::Scope RealmGateway::_capnpPrivate::brandScopes[] = { + { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding RealmGateway::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::_capnpPrivate::brandDependencies[] = { + { 33554432, ::capnp::RealmGateway::ImportParams::_capnpPrivate::brand() }, + { 33554433, ::capnp::RealmGateway::ExportParams::_capnpPrivate::brand() }, + { 50331648, ::capnp::Persistent::SaveResults::_capnpPrivate::brand() }, + { 50331649, ::capnp::Persistent::SaveResults::_capnpPrivate::brand() }, +}; +template +const ::capnp::_::RawBrandedSchema RealmGateway::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_84ff286cd00a3ed4, brandScopes, brandDependencies, + 1, 4, nullptr +}; +#endif // !CAPNP_LITE + +} // namespace + +#endif // CAPNP_INCLUDED_b8630836983feed7_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/pointer-helpers.h --- a/win32-mingw/include/capnp/pointer-helpers.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/pointer-helpers.h Tue May 23 09:16:54 2017 +0100 @@ -1,160 +1,160 @@ -// 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. - -#ifndef CAPNP_POINTER_HELPERS_H_ -#define CAPNP_POINTER_HELPERS_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" -#include "list.h" - -namespace capnp { -namespace _ { // private - -// PointerHelpers is a template class that assists in wrapping/unwrapping the low-level types in -// layout.h with the high-level public API and generated types. This way, the code generator -// and other templates do not have to specialize on each kind of pointer. - -template -struct PointerHelpers { - static inline typename T::Reader get(PointerReader reader, const word* defaultValue = nullptr) { - return typename T::Reader(reader.getStruct(defaultValue)); - } - static inline typename T::Builder get(PointerBuilder builder, - const word* defaultValue = nullptr) { - return typename T::Builder(builder.getStruct(structSize(), defaultValue)); - } - static inline void set(PointerBuilder builder, typename T::Reader value) { - builder.setStruct(value._reader); - } - static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { - builder.setStruct(value._reader, true); - } - static inline typename T::Builder init(PointerBuilder builder) { - return typename T::Builder(builder.initStruct(structSize())); - } - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } - static inline _::StructReader getInternalReader(const typename T::Reader& reader) { - return reader._reader; - } - static inline _::StructBuilder getInternalBuilder(typename T::Builder&& builder) { - return builder._builder; - } -}; - -template -struct PointerHelpers, Kind::LIST> { - static inline typename List::Reader get(PointerReader reader, - const word* defaultValue = nullptr) { - return typename List::Reader(List::getFromPointer(reader, defaultValue)); - } - static inline typename List::Builder get(PointerBuilder builder, - const word* defaultValue = nullptr) { - return typename List::Builder(List::getFromPointer(builder, defaultValue)); - } - static inline void set(PointerBuilder builder, typename List::Reader value) { - builder.setList(value.reader); - } - static inline void setCanonical(PointerBuilder builder, typename List::Reader value) { - builder.setList(value.reader, true); - } - static void set(PointerBuilder builder, kj::ArrayPtr> value) { - auto l = init(builder, value.size()); - uint i = 0; - for (auto& element: value) { - l.set(i++, element); - } - } - static inline typename List::Builder init(PointerBuilder builder, uint size) { - return typename List::Builder(List::initPointer(builder, size)); - } - static inline void adopt(PointerBuilder builder, Orphan>&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan> disown(PointerBuilder builder) { - return Orphan>(builder.disown()); - } - static inline _::ListReader getInternalReader(const typename List::Reader& reader) { - return reader.reader; - } - static inline _::ListBuilder getInternalBuilder(typename List::Builder&& builder) { - return builder.builder; - } -}; - -template -struct PointerHelpers { - static inline typename T::Reader get(PointerReader reader, - const void* defaultValue = nullptr, - uint defaultBytes = 0) { - return reader.getBlob(defaultValue, defaultBytes * BYTES); - } - static inline typename T::Builder get(PointerBuilder builder, - const void* defaultValue = nullptr, - uint defaultBytes = 0) { - return builder.getBlob(defaultValue, defaultBytes * BYTES); - } - static inline void set(PointerBuilder builder, typename T::Reader value) { - builder.setBlob(value); - } - static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { - builder.setBlob(value); - } - static inline typename T::Builder init(PointerBuilder builder, uint size) { - return builder.initBlob(size * BYTES); - } - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } -}; - -struct UncheckedMessage { - typedef const word* Reader; -}; - -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; - -template <> -struct PointerHelpers { - // Reads an AnyPointer field as an unchecked message pointer. Requires that the containing - // message is itself unchecked. This hack is currently private. It is used to locate default - // values within encoded schemas. - - static inline const word* get(PointerReader reader) { - return reader.getUnchecked(); - } -}; - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_POINTER_HELPERS_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. + +#ifndef CAPNP_POINTER_HELPERS_H_ +#define CAPNP_POINTER_HELPERS_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" +#include "list.h" + +namespace capnp { +namespace _ { // private + +// PointerHelpers is a template class that assists in wrapping/unwrapping the low-level types in +// layout.h with the high-level public API and generated types. This way, the code generator +// and other templates do not have to specialize on each kind of pointer. + +template +struct PointerHelpers { + static inline typename T::Reader get(PointerReader reader, const word* defaultValue = nullptr) { + return typename T::Reader(reader.getStruct(defaultValue)); + } + static inline typename T::Builder get(PointerBuilder builder, + const word* defaultValue = nullptr) { + return typename T::Builder(builder.getStruct(structSize(), defaultValue)); + } + static inline void set(PointerBuilder builder, typename T::Reader value) { + builder.setStruct(value._reader); + } + static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { + builder.setStruct(value._reader, true); + } + static inline typename T::Builder init(PointerBuilder builder) { + return typename T::Builder(builder.initStruct(structSize())); + } + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } + static inline _::StructReader getInternalReader(const typename T::Reader& reader) { + return reader._reader; + } + static inline _::StructBuilder getInternalBuilder(typename T::Builder&& builder) { + return builder._builder; + } +}; + +template +struct PointerHelpers, Kind::LIST> { + static inline typename List::Reader get(PointerReader reader, + const word* defaultValue = nullptr) { + return typename List::Reader(List::getFromPointer(reader, defaultValue)); + } + static inline typename List::Builder get(PointerBuilder builder, + const word* defaultValue = nullptr) { + return typename List::Builder(List::getFromPointer(builder, defaultValue)); + } + static inline void set(PointerBuilder builder, typename List::Reader value) { + builder.setList(value.reader); + } + static inline void setCanonical(PointerBuilder builder, typename List::Reader value) { + builder.setList(value.reader, true); + } + static void set(PointerBuilder builder, kj::ArrayPtr> value) { + auto l = init(builder, value.size()); + uint i = 0; + for (auto& element: value) { + l.set(i++, element); + } + } + static inline typename List::Builder init(PointerBuilder builder, uint size) { + return typename List::Builder(List::initPointer(builder, size)); + } + static inline void adopt(PointerBuilder builder, Orphan>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan> disown(PointerBuilder builder) { + return Orphan>(builder.disown()); + } + static inline _::ListReader getInternalReader(const typename List::Reader& reader) { + return reader.reader; + } + static inline _::ListBuilder getInternalBuilder(typename List::Builder&& builder) { + return builder.builder; + } +}; + +template +struct PointerHelpers { + static inline typename T::Reader get(PointerReader reader, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return reader.getBlob(defaultValue, bounded(defaultBytes) * BYTES); + } + static inline typename T::Builder get(PointerBuilder builder, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return builder.getBlob(defaultValue, bounded(defaultBytes) * BYTES); + } + static inline void set(PointerBuilder builder, typename T::Reader value) { + builder.setBlob(value); + } + static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { + builder.setBlob(value); + } + static inline typename T::Builder init(PointerBuilder builder, uint size) { + return builder.initBlob(bounded(size) * BYTES); + } + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } +}; + +struct UncheckedMessage { + typedef const word* Reader; +}; + +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; + +template <> +struct PointerHelpers { + // Reads an AnyPointer field as an unchecked message pointer. Requires that the containing + // message is itself unchecked. This hack is currently private. It is used to locate default + // values within encoded schemas. + + static inline const word* get(PointerReader reader) { + return reader.getUnchecked(); + } +}; + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_POINTER_HELPERS_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/pretty-print.h --- a/win32-mingw/include/capnp/pretty-print.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/pretty-print.h Tue May 23 09:16:54 2017 +0100 @@ -1,47 +1,47 @@ -// 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. - -#ifndef CAPNP_PRETTY_PRINT_H_ -#define CAPNP_PRETTY_PRINT_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "dynamic.h" -#include - -namespace capnp { - -kj::StringTree prettyPrint(DynamicStruct::Reader value); -kj::StringTree prettyPrint(DynamicStruct::Builder value); -kj::StringTree prettyPrint(DynamicList::Reader value); -kj::StringTree prettyPrint(DynamicList::Builder value); -// Print the given Cap'n Proto struct or list with nice indentation. Note that you can pass any -// struct or list reader or builder type to this method, since they can be implicitly converted -// to one of the dynamic types. -// -// If you don't want indentation, just use the value's KJ stringifier (e.g. pass it to kj::str(), -// any of the KJ debug macros, etc.). - -} // namespace capnp - -#endif // PRETTY_PRINT_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. + +#ifndef CAPNP_PRETTY_PRINT_H_ +#define CAPNP_PRETTY_PRINT_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "dynamic.h" +#include + +namespace capnp { + +kj::StringTree prettyPrint(DynamicStruct::Reader value); +kj::StringTree prettyPrint(DynamicStruct::Builder value); +kj::StringTree prettyPrint(DynamicList::Reader value); +kj::StringTree prettyPrint(DynamicList::Builder value); +// Print the given Cap'n Proto struct or list with nice indentation. Note that you can pass any +// struct or list reader or builder type to this method, since they can be implicitly converted +// to one of the dynamic types. +// +// If you don't want indentation, just use the value's KJ stringifier (e.g. pass it to kj::str(), +// any of the KJ debug macros, etc.). + +} // namespace capnp + +#endif // PRETTY_PRINT_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/raw-schema.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/raw-schema.h Tue May 23 09:16:54 2017 +0100 @@ -0,0 +1,242 @@ +// 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. + +#ifndef CAPNP_RAW_SCHEMA_H_ +#define CAPNP_RAW_SCHEMA_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "common.h" // for uint and friends + +#if _MSC_VER +#include +#endif + +namespace capnp { +namespace _ { // private + +struct RawSchema; + +struct RawBrandedSchema { + // Represents a combination of a schema and bindings for its generic parameters. + // + // Note that while we generate one `RawSchema` per type, we generate a `RawBrandedSchema` for + // every _instance_ of a generic type -- or, at least, every instance that is actually used. For + // generated-code types, we use template magic to initialize these. + + const RawSchema* generic; + // Generic type which we're branding. + + struct Binding { + uint8_t which; // Numeric value of one of schema::Type::Which. + + bool isImplicitParameter; + // For AnyPointer, true if it's an implicit method parameter. + + uint16_t listDepth; // Number of times to wrap the base type in List(). + + uint16_t paramIndex; + // For AnyPointer. If it's a type parameter (scopeId is non-zero) or it's an implicit parameter + // (isImplicitParameter is true), then this is the parameter index. Otherwise this is a numeric + // value of one of schema::Type::AnyPointer::Unconstrained::Which. + + union { + const RawBrandedSchema* schema; // for struct, enum, interface + uint64_t scopeId; // for AnyPointer, if it's a type parameter + }; + + Binding() = default; + inline constexpr Binding(uint8_t which, uint16_t listDepth, const RawBrandedSchema* schema) + : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(0), + schema(schema) {} + inline constexpr Binding(uint8_t which, uint16_t listDepth, + uint64_t scopeId, uint16_t paramIndex) + : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(paramIndex), + scopeId(scopeId) {} + inline constexpr Binding(uint8_t which, uint16_t listDepth, uint16_t implicitParamIndex) + : which(which), isImplicitParameter(true), listDepth(listDepth), + paramIndex(implicitParamIndex), scopeId(0) {} + }; + + struct Scope { + uint64_t typeId; + // Type ID whose parameters are being bound. + + const Binding* bindings; + uint bindingCount; + // Bindings for those parameters. + + bool isUnbound; + // This scope is unbound, in the sense of SchemaLoader::getUnbound(). + }; + + const Scope* scopes; + // Array of enclosing scopes for which generic variables have been bound, sorted by type ID. + + struct Dependency { + uint location; + const RawBrandedSchema* schema; + }; + + const Dependency* dependencies; + // Map of branded schemas for dependencies of this type, given our brand. Only dependencies that + // are branded are included in this map; if a dependency is missing, use its `defaultBrand`. + + uint32_t scopeCount; + uint32_t dependencyCount; + + enum class DepKind { + // Component of a Dependency::location. Specifies what sort of dependency this is. + + INVALID, + // Mostly defined to ensure that zero is not a valid location. + + FIELD, + // Binding needed for a field's type. The index is the field index (NOT ordinal!). + + METHOD_PARAMS, + // Bindings needed for a method's params type. The index is the method number. + + METHOD_RESULTS, + // Bindings needed for a method's results type. The index is the method ordinal. + + SUPERCLASS, + // Bindings needed for a superclass type. The index is the superclass's index in the + // "extends" list. + + CONST_TYPE + // Bindings needed for the type of a constant. The index is zero. + }; + + static inline uint makeDepLocation(DepKind kind, uint index) { + // Make a number representing the location of a particular dependency within its parent + // schema. + + return (static_cast(kind) << 24) | index; + } + + class Initializer { + public: + virtual void init(const RawBrandedSchema* generic) const = 0; + }; + + const Initializer* lazyInitializer; + // Lazy initializer, invoked by ensureInitialized(). + + inline void ensureInitialized() const { + // Lazy initialization support. Invoke to ensure that initialization has taken place. This + // is required in particular when traversing the dependency list. RawSchemas for compiled-in + // types are always initialized; only dynamically-loaded schemas may be lazy. + +#if __GNUC__ + const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); +#elif _MSC_VER + const Initializer* i = *static_cast(&lazyInitializer); + std::atomic_thread_fence(std::memory_order_acquire); +#else +#error "Platform not supported" +#endif + if (i != nullptr) i->init(this); + } + + inline bool isUnbound() const; + // Checks if this schema is the result of calling SchemaLoader::getUnbound(), in which case + // binding lookups need to be handled specially. +}; + +struct RawSchema { + // The generated code defines a constant RawSchema for every compiled declaration. + // + // This is an internal structure which could change in the future. + + uint64_t id; + + const word* encodedNode; + // Encoded SchemaNode, readable via readMessageUnchecked(encodedNode). + + uint32_t encodedSize; + // Size of encodedNode, in words. + + const RawSchema* const* dependencies; + // Pointers to other types on which this one depends, sorted by ID. The schemas in this table + // may be uninitialized -- you must call ensureInitialized() on the one you wish to use before + // using it. + // + // TODO(someday): Make this a hashtable. + + const uint16_t* membersByName; + // Indexes of members sorted by name. Used to implement name lookup. + // TODO(someday): Make this a hashtable. + + uint32_t dependencyCount; + uint32_t memberCount; + // Sizes of above tables. + + const uint16_t* membersByDiscriminant; + // List of all member indexes ordered by discriminant value. Those which don't have a + // discriminant value are listed at the end, in order by ordinal. + + const RawSchema* canCastTo; + // Points to the RawSchema of a compiled-in type to which it is safe to cast any DynamicValue + // with this schema. This is null for all compiled-in types; it is only set by SchemaLoader on + // dynamically-loaded types. + + class Initializer { + public: + virtual void init(const RawSchema* schema) const = 0; + }; + + const Initializer* lazyInitializer; + // Lazy initializer, invoked by ensureInitialized(). + + inline void ensureInitialized() const { + // Lazy initialization support. Invoke to ensure that initialization has taken place. This + // is required in particular when traversing the dependency list. RawSchemas for compiled-in + // types are always initialized; only dynamically-loaded schemas may be lazy. + +#if __GNUC__ + const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); +#elif _MSC_VER + const Initializer* i = *static_cast(&lazyInitializer); + std::atomic_thread_fence(std::memory_order_acquire); +#else +#error "Platform not supported" +#endif + if (i != nullptr) i->init(this); + } + + RawBrandedSchema defaultBrand; + // Specifies the brand to use for this schema if no generic parameters have been bound to + // anything. Generally, in the default brand, all generic parameters are treated as if they were + // bound to `AnyPointer`. +}; + +inline bool RawBrandedSchema::isUnbound() const { + // The unbound schema is the only one that has no scopes but is not the default schema. + return scopeCount == 0 && this != &generic->defaultBrand; +} + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_RAW_SCHEMA_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/rpc-prelude.h --- a/win32-mingw/include/capnp/rpc-prelude.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/rpc-prelude.h Tue May 23 09:16:54 2017 +0100 @@ -1,130 +1,130 @@ -// 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 a bunch of internal declarations that must appear before rpc.h can start. -// We don't define these directly in rpc.h because it makes the file hard to read. - -#ifndef CAPNP_RPC_PRELUDE_H_ -#define CAPNP_RPC_PRELUDE_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "capability.h" -#include "persistent.capnp.h" - -namespace capnp { - -class OutgoingRpcMessage; -class IncomingRpcMessage; - -template -class RpcSystem; - -namespace _ { // private - -class VatNetworkBase { - // Non-template version of VatNetwork. Ignore this class; see VatNetwork in rpc.h. - -public: - class Connection; - - struct ConnectionAndProvisionId { - kj::Own connection; - kj::Own firstMessage; - Orphan provisionId; - }; - - class Connection { - public: - virtual kj::Own newOutgoingMessage(uint firstSegmentWordSize) = 0; - virtual kj::Promise>> receiveIncomingMessage() = 0; - virtual kj::Promise shutdown() = 0; - virtual AnyStruct::Reader baseGetPeerVatId() = 0; - }; - virtual kj::Maybe> baseConnect(AnyStruct::Reader vatId) = 0; - virtual kj::Promise> baseAccept() = 0; -}; - -class SturdyRefRestorerBase { -public: - virtual Capability::Client baseRestore(AnyPointer::Reader ref) = 0; -}; - -class BootstrapFactoryBase { - // Non-template version of BootstrapFactory. Ignore this class; see BootstrapFactory in rpc.h. -public: - virtual Capability::Client baseCreateFor(AnyStruct::Reader clientId) = 0; -}; - -class RpcSystemBase { - // Non-template version of RpcSystem. Ignore this class; see RpcSystem in rpc.h. - -public: - RpcSystemBase(VatNetworkBase& network, kj::Maybe bootstrapInterface, - kj::Maybe::Client> gateway); - RpcSystemBase(VatNetworkBase& network, BootstrapFactoryBase& bootstrapFactory, - kj::Maybe::Client> gateway); - RpcSystemBase(VatNetworkBase& network, SturdyRefRestorerBase& restorer); - RpcSystemBase(RpcSystemBase&& other) noexcept; - ~RpcSystemBase() noexcept(false); - -private: - class Impl; - kj::Own impl; - - Capability::Client baseBootstrap(AnyStruct::Reader vatId); - Capability::Client baseRestore(AnyStruct::Reader vatId, AnyPointer::Reader objectId); - void baseSetFlowLimit(size_t words); - - template - friend class capnp::RpcSystem; -}; - -template struct InternalRefFromRealmGateway_; -template -struct InternalRefFromRealmGateway_> { - typedef InternalRef Type; -}; -template -using InternalRefFromRealmGateway = typename InternalRefFromRealmGateway_::Type; -template -using InternalRefFromRealmGatewayClient = InternalRefFromRealmGateway; - -template struct ExternalRefFromRealmGateway_; -template -struct ExternalRefFromRealmGateway_> { - typedef ExternalRef Type; -}; -template -using ExternalRefFromRealmGateway = typename ExternalRefFromRealmGateway_::Type; -template -using ExternalRefFromRealmGatewayClient = ExternalRefFromRealmGateway; - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_RPC_PRELUDE_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 a bunch of internal declarations that must appear before rpc.h can start. +// We don't define these directly in rpc.h because it makes the file hard to read. + +#ifndef CAPNP_RPC_PRELUDE_H_ +#define CAPNP_RPC_PRELUDE_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "capability.h" +#include "persistent.capnp.h" + +namespace capnp { + +class OutgoingRpcMessage; +class IncomingRpcMessage; + +template +class RpcSystem; + +namespace _ { // private + +class VatNetworkBase { + // Non-template version of VatNetwork. Ignore this class; see VatNetwork in rpc.h. + +public: + class Connection; + + struct ConnectionAndProvisionId { + kj::Own connection; + kj::Own firstMessage; + Orphan provisionId; + }; + + class Connection { + public: + virtual kj::Own newOutgoingMessage(uint firstSegmentWordSize) = 0; + virtual kj::Promise>> receiveIncomingMessage() = 0; + virtual kj::Promise shutdown() = 0; + virtual AnyStruct::Reader baseGetPeerVatId() = 0; + }; + virtual kj::Maybe> baseConnect(AnyStruct::Reader vatId) = 0; + virtual kj::Promise> baseAccept() = 0; +}; + +class SturdyRefRestorerBase { +public: + virtual Capability::Client baseRestore(AnyPointer::Reader ref) = 0; +}; + +class BootstrapFactoryBase { + // Non-template version of BootstrapFactory. Ignore this class; see BootstrapFactory in rpc.h. +public: + virtual Capability::Client baseCreateFor(AnyStruct::Reader clientId) = 0; +}; + +class RpcSystemBase { + // Non-template version of RpcSystem. Ignore this class; see RpcSystem in rpc.h. + +public: + RpcSystemBase(VatNetworkBase& network, kj::Maybe bootstrapInterface, + kj::Maybe::Client> gateway); + RpcSystemBase(VatNetworkBase& network, BootstrapFactoryBase& bootstrapFactory, + kj::Maybe::Client> gateway); + RpcSystemBase(VatNetworkBase& network, SturdyRefRestorerBase& restorer); + RpcSystemBase(RpcSystemBase&& other) noexcept; + ~RpcSystemBase() noexcept(false); + +private: + class Impl; + kj::Own impl; + + Capability::Client baseBootstrap(AnyStruct::Reader vatId); + Capability::Client baseRestore(AnyStruct::Reader vatId, AnyPointer::Reader objectId); + void baseSetFlowLimit(size_t words); + + template + friend class capnp::RpcSystem; +}; + +template struct InternalRefFromRealmGateway_; +template +struct InternalRefFromRealmGateway_> { + typedef InternalRef Type; +}; +template +using InternalRefFromRealmGateway = typename InternalRefFromRealmGateway_::Type; +template +using InternalRefFromRealmGatewayClient = InternalRefFromRealmGateway; + +template struct ExternalRefFromRealmGateway_; +template +struct ExternalRefFromRealmGateway_> { + typedef ExternalRef Type; +}; +template +using ExternalRefFromRealmGateway = typename ExternalRefFromRealmGateway_::Type; +template +using ExternalRefFromRealmGatewayClient = ExternalRefFromRealmGateway; + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_RPC_PRELUDE_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/rpc-twoparty.capnp.h --- a/win32-mingw/include/capnp/rpc-twoparty.capnp.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/rpc-twoparty.capnp.h Tue May 23 09:16:54 2017 +0100 @@ -1,724 +1,726 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: rpc-twoparty.capnp - -#ifndef CAPNP_INCLUDED_a184c7885cdaf2a1_ -#define CAPNP_INCLUDED_a184c7885cdaf2a1_ - -#include - -#if CAPNP_VERSION != 6000 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(9fd69ebc87b9719c); -enum class Side_9fd69ebc87b9719c: uint16_t { - SERVER, - CLIENT, -}; -CAPNP_DECLARE_ENUM(Side, 9fd69ebc87b9719c); -CAPNP_DECLARE_SCHEMA(d20b909fee733a8e); -CAPNP_DECLARE_SCHEMA(b88d09a9c5f39817); -CAPNP_DECLARE_SCHEMA(89f389b6fd4082c1); -CAPNP_DECLARE_SCHEMA(b47f4979672cb59d); -CAPNP_DECLARE_SCHEMA(95b29059097fca83); -CAPNP_DECLARE_SCHEMA(9d263a3630b7ebee); - -} // namespace schemas -} // namespace capnp - -namespace capnp { -namespace rpc { -namespace twoparty { - -typedef ::capnp::schemas::Side_9fd69ebc87b9719c Side; - -struct VatId { - VatId() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d20b909fee733a8e, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct ProvisionId { - ProvisionId() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b88d09a9c5f39817, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct RecipientId { - RecipientId() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(89f389b6fd4082c1, 0, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct ThirdPartyCapId { - ThirdPartyCapId() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b47f4979672cb59d, 0, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct JoinKeyPart { - JoinKeyPart() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(95b29059097fca83, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct JoinResult { - JoinResult() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9d263a3630b7ebee, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -class VatId::Reader { -public: - typedef VatId Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::capnp::rpc::twoparty::Side getSide() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class VatId::Builder { -public: - typedef VatId Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::capnp::rpc::twoparty::Side getSide(); - inline void setSide( ::capnp::rpc::twoparty::Side value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class VatId::Pipeline { -public: - typedef VatId Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class ProvisionId::Reader { -public: - typedef ProvisionId Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class ProvisionId::Builder { -public: - typedef ProvisionId Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId(); - inline void setJoinId( ::uint32_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class ProvisionId::Pipeline { -public: - typedef ProvisionId Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class RecipientId::Reader { -public: - typedef RecipientId Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class RecipientId::Builder { -public: - typedef RecipientId Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class RecipientId::Pipeline { -public: - typedef RecipientId Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class ThirdPartyCapId::Reader { -public: - typedef ThirdPartyCapId Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class ThirdPartyCapId::Builder { -public: - typedef ThirdPartyCapId Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class ThirdPartyCapId::Pipeline { -public: - typedef ThirdPartyCapId Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class JoinKeyPart::Reader { -public: - typedef JoinKeyPart Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId() const; - - inline ::uint16_t getPartCount() const; - - inline ::uint16_t getPartNum() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class JoinKeyPart::Builder { -public: - typedef JoinKeyPart Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId(); - inline void setJoinId( ::uint32_t value); - - inline ::uint16_t getPartCount(); - inline void setPartCount( ::uint16_t value); - - inline ::uint16_t getPartNum(); - inline void setPartNum( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class JoinKeyPart::Pipeline { -public: - typedef JoinKeyPart Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class JoinResult::Reader { -public: - typedef JoinResult Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId() const; - - inline bool getSucceeded() const; - - inline bool hasCap() const; - inline ::capnp::AnyPointer::Reader getCap() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class JoinResult::Builder { -public: - typedef JoinResult Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId(); - inline void setJoinId( ::uint32_t value); - - inline bool getSucceeded(); - inline void setSucceeded(bool value); - - inline bool hasCap(); - inline ::capnp::AnyPointer::Builder getCap(); - inline ::capnp::AnyPointer::Builder initCap(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class JoinResult::Pipeline { -public: - typedef JoinResult Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -inline ::capnp::rpc::twoparty::Side VatId::Reader::getSide() const { - return _reader.getDataField< ::capnp::rpc::twoparty::Side>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::rpc::twoparty::Side VatId::Builder::getSide() { - return _builder.getDataField< ::capnp::rpc::twoparty::Side>( - 0 * ::capnp::ELEMENTS); -} -inline void VatId::Builder::setSide( ::capnp::rpc::twoparty::Side value) { - _builder.setDataField< ::capnp::rpc::twoparty::Side>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t ProvisionId::Reader::getJoinId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t ProvisionId::Builder::getJoinId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void ProvisionId::Builder::setJoinId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t JoinKeyPart::Reader::getJoinId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t JoinKeyPart::Builder::getJoinId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void JoinKeyPart::Builder::setJoinId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t JoinKeyPart::Reader::getPartCount() const { - return _reader.getDataField< ::uint16_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint16_t JoinKeyPart::Builder::getPartCount() { - return _builder.getDataField< ::uint16_t>( - 2 * ::capnp::ELEMENTS); -} -inline void JoinKeyPart::Builder::setPartCount( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t JoinKeyPart::Reader::getPartNum() const { - return _reader.getDataField< ::uint16_t>( - 3 * ::capnp::ELEMENTS); -} - -inline ::uint16_t JoinKeyPart::Builder::getPartNum() { - return _builder.getDataField< ::uint16_t>( - 3 * ::capnp::ELEMENTS); -} -inline void JoinKeyPart::Builder::setPartNum( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 3 * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t JoinResult::Reader::getJoinId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t JoinResult::Builder::getJoinId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void JoinResult::Builder::setJoinId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool JoinResult::Reader::getSucceeded() const { - return _reader.getDataField( - 32 * ::capnp::ELEMENTS); -} - -inline bool JoinResult::Builder::getSucceeded() { - return _builder.getDataField( - 32 * ::capnp::ELEMENTS); -} -inline void JoinResult::Builder::setSucceeded(bool value) { - _builder.setDataField( - 32 * ::capnp::ELEMENTS, value); -} - -inline bool JoinResult::Reader::hasCap() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool JoinResult::Builder::hasCap() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader JoinResult::Reader::getCap() const { - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder JoinResult::Builder::getCap() { - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder JoinResult::Builder::initCap() { - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -} // namespace -} // namespace -} // namespace - -#endif // CAPNP_INCLUDED_a184c7885cdaf2a1_ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: rpc-twoparty.capnp + +#ifndef CAPNP_INCLUDED_a184c7885cdaf2a1_ +#define CAPNP_INCLUDED_a184c7885cdaf2a1_ + +#include + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(9fd69ebc87b9719c); +enum class Side_9fd69ebc87b9719c: uint16_t { + SERVER, + CLIENT, +}; +CAPNP_DECLARE_ENUM(Side, 9fd69ebc87b9719c); +CAPNP_DECLARE_SCHEMA(d20b909fee733a8e); +CAPNP_DECLARE_SCHEMA(b88d09a9c5f39817); +CAPNP_DECLARE_SCHEMA(89f389b6fd4082c1); +CAPNP_DECLARE_SCHEMA(b47f4979672cb59d); +CAPNP_DECLARE_SCHEMA(95b29059097fca83); +CAPNP_DECLARE_SCHEMA(9d263a3630b7ebee); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace rpc { +namespace twoparty { + +typedef ::capnp::schemas::Side_9fd69ebc87b9719c Side; + +struct VatId { + VatId() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d20b909fee733a8e, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct ProvisionId { + ProvisionId() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b88d09a9c5f39817, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct RecipientId { + RecipientId() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(89f389b6fd4082c1, 0, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct ThirdPartyCapId { + ThirdPartyCapId() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b47f4979672cb59d, 0, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct JoinKeyPart { + JoinKeyPart() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(95b29059097fca83, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct JoinResult { + JoinResult() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9d263a3630b7ebee, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class VatId::Reader { +public: + typedef VatId Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::capnp::rpc::twoparty::Side getSide() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class VatId::Builder { +public: + typedef VatId Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::capnp::rpc::twoparty::Side getSide(); + inline void setSide( ::capnp::rpc::twoparty::Side value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class VatId::Pipeline { +public: + typedef VatId Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class ProvisionId::Reader { +public: + typedef ProvisionId Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getJoinId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class ProvisionId::Builder { +public: + typedef ProvisionId Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getJoinId(); + inline void setJoinId( ::uint32_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class ProvisionId::Pipeline { +public: + typedef ProvisionId Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class RecipientId::Reader { +public: + typedef RecipientId Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class RecipientId::Builder { +public: + typedef RecipientId Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class RecipientId::Pipeline { +public: + typedef RecipientId Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class ThirdPartyCapId::Reader { +public: + typedef ThirdPartyCapId Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class ThirdPartyCapId::Builder { +public: + typedef ThirdPartyCapId Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class ThirdPartyCapId::Pipeline { +public: + typedef ThirdPartyCapId Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class JoinKeyPart::Reader { +public: + typedef JoinKeyPart Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getJoinId() const; + + inline ::uint16_t getPartCount() const; + + inline ::uint16_t getPartNum() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class JoinKeyPart::Builder { +public: + typedef JoinKeyPart Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getJoinId(); + inline void setJoinId( ::uint32_t value); + + inline ::uint16_t getPartCount(); + inline void setPartCount( ::uint16_t value); + + inline ::uint16_t getPartNum(); + inline void setPartNum( ::uint16_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class JoinKeyPart::Pipeline { +public: + typedef JoinKeyPart Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class JoinResult::Reader { +public: + typedef JoinResult Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getJoinId() const; + + inline bool getSucceeded() const; + + inline bool hasCap() const; + inline ::capnp::AnyPointer::Reader getCap() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class JoinResult::Builder { +public: + typedef JoinResult Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getJoinId(); + inline void setJoinId( ::uint32_t value); + + inline bool getSucceeded(); + inline void setSucceeded(bool value); + + inline bool hasCap(); + inline ::capnp::AnyPointer::Builder getCap(); + inline ::capnp::AnyPointer::Builder initCap(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class JoinResult::Pipeline { +public: + typedef JoinResult Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline ::capnp::rpc::twoparty::Side VatId::Reader::getSide() const { + return _reader.getDataField< ::capnp::rpc::twoparty::Side>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::rpc::twoparty::Side VatId::Builder::getSide() { + return _builder.getDataField< ::capnp::rpc::twoparty::Side>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void VatId::Builder::setSide( ::capnp::rpc::twoparty::Side value) { + _builder.setDataField< ::capnp::rpc::twoparty::Side>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t ProvisionId::Reader::getJoinId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t ProvisionId::Builder::getJoinId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void ProvisionId::Builder::setJoinId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t JoinKeyPart::Reader::getJoinId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t JoinKeyPart::Builder::getJoinId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void JoinKeyPart::Builder::setJoinId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t JoinKeyPart::Reader::getPartCount() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t JoinKeyPart::Builder::getPartCount() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void JoinKeyPart::Builder::setPartCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t JoinKeyPart::Reader::getPartNum() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t JoinKeyPart::Builder::getPartNum() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} +inline void JoinKeyPart::Builder::setPartNum( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t JoinResult::Reader::getJoinId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t JoinResult::Builder::getJoinId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void JoinResult::Builder::setJoinId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool JoinResult::Reader::getSucceeded() const { + return _reader.getDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS); +} + +inline bool JoinResult::Builder::getSucceeded() { + return _builder.getDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS); +} +inline void JoinResult::Builder::setSucceeded(bool value) { + _builder.setDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS, value); +} + +inline bool JoinResult::Reader::hasCap() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool JoinResult::Builder::hasCap() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader JoinResult::Reader::getCap() const { + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder JoinResult::Builder::getCap() { + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder JoinResult::Builder::initCap() { + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +} // namespace +} // namespace +} // namespace + +#endif // CAPNP_INCLUDED_a184c7885cdaf2a1_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/rpc-twoparty.h --- a/win32-mingw/include/capnp/rpc-twoparty.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/rpc-twoparty.h Tue May 23 09:16:54 2017 +0100 @@ -1,160 +1,160 @@ -// 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. - -#ifndef CAPNP_RPC_TWOPARTY_H_ -#define CAPNP_RPC_TWOPARTY_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "rpc.h" -#include "message.h" -#include -#include - -namespace capnp { - -namespace rpc { - namespace twoparty { - typedef VatId SturdyRefHostId; // For backwards-compatibility with version 0.4. - } -} - -typedef VatNetwork - TwoPartyVatNetworkBase; - -class TwoPartyVatNetwork: public TwoPartyVatNetworkBase, - private TwoPartyVatNetworkBase::Connection { - // A `VatNetwork` that consists of exactly two parties communicating over an arbitrary byte - // stream. This is used to implement the common case of a client/server network. - // - // See `ez-rpc.h` for a simple interface for setting up two-party clients and servers. - // Use `TwoPartyVatNetwork` only if you need the advanced features. - -public: - TwoPartyVatNetwork(kj::AsyncIoStream& stream, rpc::twoparty::Side side, - ReaderOptions receiveOptions = ReaderOptions()); - KJ_DISALLOW_COPY(TwoPartyVatNetwork); - - kj::Promise onDisconnect() { return disconnectPromise.addBranch(); } - // Returns a promise that resolves when the peer disconnects. - - rpc::twoparty::Side getSide() { return side; } - - // implements VatNetwork ----------------------------------------------------- - - kj::Maybe> connect( - rpc::twoparty::VatId::Reader ref) override; - kj::Promise> accept() override; - -private: - class OutgoingMessageImpl; - class IncomingMessageImpl; - - kj::AsyncIoStream& stream; - rpc::twoparty::Side side; - MallocMessageBuilder peerVatId; - ReaderOptions receiveOptions; - bool accepted = false; - - kj::Maybe> previousWrite; - // Resolves when the previous write completes. This effectively serves as the write queue. - // Becomes null when shutdown() is called. - - kj::Own>> acceptFulfiller; - // Fulfiller for the promise returned by acceptConnectionAsRefHost() on the client side, or the - // second call on the server side. Never fulfilled, because there is only one connection. - - kj::ForkedPromise disconnectPromise = nullptr; - - class FulfillerDisposer: public kj::Disposer { - // Hack: TwoPartyVatNetwork is both a VatNetwork and a VatNetwork::Connection. When the RPC - // system detects (or initiates) a disconnection, it drops its reference to the Connection. - // When all references have been dropped, then we want disconnectPromise to be fulfilled. - // So we hand out Owns with this disposer attached, so that we can detect when - // they are dropped. - - public: - mutable kj::Own> fulfiller; - mutable uint refcount = 0; - - void disposeImpl(void* pointer) const override; - }; - FulfillerDisposer disconnectFulfiller; - - kj::Own asConnection(); - // Returns a pointer to this with the disposer set to disconnectFulfiller. - - // implements Connection ----------------------------------------------------- - - rpc::twoparty::VatId::Reader getPeerVatId() override; - kj::Own newOutgoingMessage(uint firstSegmentWordSize) override; - kj::Promise>> receiveIncomingMessage() override; - kj::Promise shutdown() override; -}; - -class TwoPartyServer: private kj::TaskSet::ErrorHandler { - // Convenience class which implements a simple server which accepts connections on a listener - // socket and serices them as two-party connections. - -public: - explicit TwoPartyServer(Capability::Client bootstrapInterface); - - void accept(kj::Own&& connection); - // Accepts the connection for servicing. - - kj::Promise listen(kj::ConnectionReceiver& listener); - // Listens for connections on the given listener. The returned promise never resolves unless an - // exception is thrown while trying to accept. You may discard the returned promise to cancel - // listening. - -private: - Capability::Client bootstrapInterface; - kj::TaskSet tasks; - - struct AcceptedConnection; - - void taskFailed(kj::Exception&& exception) override; -}; - -class TwoPartyClient { - // Convenience class which implements a simple client. - -public: - explicit TwoPartyClient(kj::AsyncIoStream& connection); - TwoPartyClient(kj::AsyncIoStream& connection, Capability::Client bootstrapInterface, - rpc::twoparty::Side side = rpc::twoparty::Side::CLIENT); - - Capability::Client bootstrap(); - // Get the server's bootstrap interface. - - inline kj::Promise onDisconnect() { return network.onDisconnect(); } - -private: - TwoPartyVatNetwork network; - RpcSystem rpcSystem; -}; - -} // namespace capnp - -#endif // CAPNP_RPC_TWOPARTY_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. + +#ifndef CAPNP_RPC_TWOPARTY_H_ +#define CAPNP_RPC_TWOPARTY_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "rpc.h" +#include "message.h" +#include +#include + +namespace capnp { + +namespace rpc { + namespace twoparty { + typedef VatId SturdyRefHostId; // For backwards-compatibility with version 0.4. + } +} + +typedef VatNetwork + TwoPartyVatNetworkBase; + +class TwoPartyVatNetwork: public TwoPartyVatNetworkBase, + private TwoPartyVatNetworkBase::Connection { + // A `VatNetwork` that consists of exactly two parties communicating over an arbitrary byte + // stream. This is used to implement the common case of a client/server network. + // + // See `ez-rpc.h` for a simple interface for setting up two-party clients and servers. + // Use `TwoPartyVatNetwork` only if you need the advanced features. + +public: + TwoPartyVatNetwork(kj::AsyncIoStream& stream, rpc::twoparty::Side side, + ReaderOptions receiveOptions = ReaderOptions()); + KJ_DISALLOW_COPY(TwoPartyVatNetwork); + + kj::Promise onDisconnect() { return disconnectPromise.addBranch(); } + // Returns a promise that resolves when the peer disconnects. + + rpc::twoparty::Side getSide() { return side; } + + // implements VatNetwork ----------------------------------------------------- + + kj::Maybe> connect( + rpc::twoparty::VatId::Reader ref) override; + kj::Promise> accept() override; + +private: + class OutgoingMessageImpl; + class IncomingMessageImpl; + + kj::AsyncIoStream& stream; + rpc::twoparty::Side side; + MallocMessageBuilder peerVatId; + ReaderOptions receiveOptions; + bool accepted = false; + + kj::Maybe> previousWrite; + // Resolves when the previous write completes. This effectively serves as the write queue. + // Becomes null when shutdown() is called. + + kj::Own>> acceptFulfiller; + // Fulfiller for the promise returned by acceptConnectionAsRefHost() on the client side, or the + // second call on the server side. Never fulfilled, because there is only one connection. + + kj::ForkedPromise disconnectPromise = nullptr; + + class FulfillerDisposer: public kj::Disposer { + // Hack: TwoPartyVatNetwork is both a VatNetwork and a VatNetwork::Connection. When the RPC + // system detects (or initiates) a disconnection, it drops its reference to the Connection. + // When all references have been dropped, then we want disconnectPromise to be fulfilled. + // So we hand out Owns with this disposer attached, so that we can detect when + // they are dropped. + + public: + mutable kj::Own> fulfiller; + mutable uint refcount = 0; + + void disposeImpl(void* pointer) const override; + }; + FulfillerDisposer disconnectFulfiller; + + kj::Own asConnection(); + // Returns a pointer to this with the disposer set to disconnectFulfiller. + + // implements Connection ----------------------------------------------------- + + rpc::twoparty::VatId::Reader getPeerVatId() override; + kj::Own newOutgoingMessage(uint firstSegmentWordSize) override; + kj::Promise>> receiveIncomingMessage() override; + kj::Promise shutdown() override; +}; + +class TwoPartyServer: private kj::TaskSet::ErrorHandler { + // Convenience class which implements a simple server which accepts connections on a listener + // socket and serices them as two-party connections. + +public: + explicit TwoPartyServer(Capability::Client bootstrapInterface); + + void accept(kj::Own&& connection); + // Accepts the connection for servicing. + + kj::Promise listen(kj::ConnectionReceiver& listener); + // Listens for connections on the given listener. The returned promise never resolves unless an + // exception is thrown while trying to accept. You may discard the returned promise to cancel + // listening. + +private: + Capability::Client bootstrapInterface; + kj::TaskSet tasks; + + struct AcceptedConnection; + + void taskFailed(kj::Exception&& exception) override; +}; + +class TwoPartyClient { + // Convenience class which implements a simple client. + +public: + explicit TwoPartyClient(kj::AsyncIoStream& connection); + TwoPartyClient(kj::AsyncIoStream& connection, Capability::Client bootstrapInterface, + rpc::twoparty::Side side = rpc::twoparty::Side::CLIENT); + + Capability::Client bootstrap(); + // Get the server's bootstrap interface. + + inline kj::Promise onDisconnect() { return network.onDisconnect(); } + +private: + TwoPartyVatNetwork network; + RpcSystem rpcSystem; +}; + +} // namespace capnp + +#endif // CAPNP_RPC_TWOPARTY_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/rpc.capnp.h --- a/win32-mingw/include/capnp/rpc.capnp.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/rpc.capnp.h Tue May 23 09:16:54 2017 +0100 @@ -1,4808 +1,4898 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: rpc.capnp - -#ifndef CAPNP_INCLUDED_b312981b2552a250_ -#define CAPNP_INCLUDED_b312981b2552a250_ - -#include - -#if CAPNP_VERSION != 6000 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(91b79f1f808db032); -CAPNP_DECLARE_SCHEMA(e94ccf8031176ec4); -CAPNP_DECLARE_SCHEMA(836a53ce789d4cd4); -CAPNP_DECLARE_SCHEMA(dae8b0f61aab5f99); -CAPNP_DECLARE_SCHEMA(9e19b28d3db3573a); -CAPNP_DECLARE_SCHEMA(d37d2eb2c2f80e63); -CAPNP_DECLARE_SCHEMA(bbc29655fa89086e); -CAPNP_DECLARE_SCHEMA(ad1a6c0d7dd07497); -CAPNP_DECLARE_SCHEMA(f964368b0fbd3711); -CAPNP_DECLARE_SCHEMA(d562b4df655bdd4d); -CAPNP_DECLARE_SCHEMA(9c6a046bfbc1ac5a); -CAPNP_DECLARE_SCHEMA(d4c9b56290554016); -CAPNP_DECLARE_SCHEMA(fbe1980490e001af); -CAPNP_DECLARE_SCHEMA(95bc14545813fbc1); -CAPNP_DECLARE_SCHEMA(9a0e61223d96743b); -CAPNP_DECLARE_SCHEMA(8523ddc40b86b8b0); -CAPNP_DECLARE_SCHEMA(d800b1d6cd6f1ca0); -CAPNP_DECLARE_SCHEMA(f316944415569081); -CAPNP_DECLARE_SCHEMA(d37007fde1f0027d); -CAPNP_DECLARE_SCHEMA(d625b7063acf691a); -CAPNP_DECLARE_SCHEMA(b28c96e23f4cbd58); -enum class Type_b28c96e23f4cbd58: uint16_t { - FAILED, - OVERLOADED, - DISCONNECTED, - UNIMPLEMENTED, -}; -CAPNP_DECLARE_ENUM(Type, b28c96e23f4cbd58); - -} // namespace schemas -} // namespace capnp - -namespace capnp { -namespace rpc { - -struct Message { - Message() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - UNIMPLEMENTED, - ABORT, - CALL, - RETURN, - FINISH, - RESOLVE, - RELEASE, - OBSOLETE_SAVE, - BOOTSTRAP, - OBSOLETE_DELETE, - PROVIDE, - ACCEPT, - JOIN, - DISEMBARGO, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(91b79f1f808db032, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Bootstrap { - Bootstrap() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(e94ccf8031176ec4, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Call { - Call() = delete; - - class Reader; - class Builder; - class Pipeline; - struct SendResultsTo; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(836a53ce789d4cd4, 3, 3) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Call::SendResultsTo { - SendResultsTo() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - CALLER, - YOURSELF, - THIRD_PARTY, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(dae8b0f61aab5f99, 3, 3) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Return { - Return() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - RESULTS, - EXCEPTION, - CANCELED, - RESULTS_SENT_ELSEWHERE, - TAKE_FROM_OTHER_QUESTION, - ACCEPT_FROM_THIRD_PARTY, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9e19b28d3db3573a, 2, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Finish { - Finish() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d37d2eb2c2f80e63, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Resolve { - Resolve() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - CAP, - EXCEPTION, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(bbc29655fa89086e, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Release { - Release() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ad1a6c0d7dd07497, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Disembargo { - Disembargo() = delete; - - class Reader; - class Builder; - class Pipeline; - struct Context; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f964368b0fbd3711, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Disembargo::Context { - Context() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - SENDER_LOOPBACK, - RECEIVER_LOOPBACK, - ACCEPT, - PROVIDE, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d562b4df655bdd4d, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Provide { - Provide() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9c6a046bfbc1ac5a, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Accept { - Accept() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d4c9b56290554016, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Join { - Join() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(fbe1980490e001af, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct MessageTarget { - MessageTarget() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - IMPORTED_CAP, - PROMISED_ANSWER, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(95bc14545813fbc1, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Payload { - Payload() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9a0e61223d96743b, 0, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct CapDescriptor { - CapDescriptor() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - NONE, - SENDER_HOSTED, - SENDER_PROMISE, - RECEIVER_HOSTED, - RECEIVER_ANSWER, - THIRD_PARTY_HOSTED, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(8523ddc40b86b8b0, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct PromisedAnswer { - PromisedAnswer() = delete; - - class Reader; - class Builder; - class Pipeline; - struct Op; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d800b1d6cd6f1ca0, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct PromisedAnswer::Op { - Op() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - NOOP, - GET_POINTER_FIELD, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f316944415569081, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct ThirdPartyCapDescriptor { - ThirdPartyCapDescriptor() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d37007fde1f0027d, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Exception { - Exception() = delete; - - class Reader; - class Builder; - class Pipeline; - typedef ::capnp::schemas::Type_b28c96e23f4cbd58 Type; - - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d625b7063acf691a, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -class Message::Reader { -public: - typedef Message Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isUnimplemented() const; - inline bool hasUnimplemented() const; - inline ::capnp::rpc::Message::Reader getUnimplemented() const; - - inline bool isAbort() const; - inline bool hasAbort() const; - inline ::capnp::rpc::Exception::Reader getAbort() const; - - inline bool isCall() const; - inline bool hasCall() const; - inline ::capnp::rpc::Call::Reader getCall() const; - - inline bool isReturn() const; - inline bool hasReturn() const; - inline ::capnp::rpc::Return::Reader getReturn() const; - - inline bool isFinish() const; - inline bool hasFinish() const; - inline ::capnp::rpc::Finish::Reader getFinish() const; - - inline bool isResolve() const; - inline bool hasResolve() const; - inline ::capnp::rpc::Resolve::Reader getResolve() const; - - inline bool isRelease() const; - inline bool hasRelease() const; - inline ::capnp::rpc::Release::Reader getRelease() const; - - inline bool isObsoleteSave() const; - inline bool hasObsoleteSave() const; - inline ::capnp::AnyPointer::Reader getObsoleteSave() const; - - inline bool isBootstrap() const; - inline bool hasBootstrap() const; - inline ::capnp::rpc::Bootstrap::Reader getBootstrap() const; - - inline bool isObsoleteDelete() const; - inline bool hasObsoleteDelete() const; - inline ::capnp::AnyPointer::Reader getObsoleteDelete() const; - - inline bool isProvide() const; - inline bool hasProvide() const; - inline ::capnp::rpc::Provide::Reader getProvide() const; - - inline bool isAccept() const; - inline bool hasAccept() const; - inline ::capnp::rpc::Accept::Reader getAccept() const; - - inline bool isJoin() const; - inline bool hasJoin() const; - inline ::capnp::rpc::Join::Reader getJoin() const; - - inline bool isDisembargo() const; - inline bool hasDisembargo() const; - inline ::capnp::rpc::Disembargo::Reader getDisembargo() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Message::Builder { -public: - typedef Message Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isUnimplemented(); - inline bool hasUnimplemented(); - inline ::capnp::rpc::Message::Builder getUnimplemented(); - inline void setUnimplemented( ::capnp::rpc::Message::Reader value); - inline ::capnp::rpc::Message::Builder initUnimplemented(); - inline void adoptUnimplemented(::capnp::Orphan< ::capnp::rpc::Message>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Message> disownUnimplemented(); - - inline bool isAbort(); - inline bool hasAbort(); - inline ::capnp::rpc::Exception::Builder getAbort(); - inline void setAbort( ::capnp::rpc::Exception::Reader value); - inline ::capnp::rpc::Exception::Builder initAbort(); - inline void adoptAbort(::capnp::Orphan< ::capnp::rpc::Exception>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Exception> disownAbort(); - - inline bool isCall(); - inline bool hasCall(); - inline ::capnp::rpc::Call::Builder getCall(); - inline void setCall( ::capnp::rpc::Call::Reader value); - inline ::capnp::rpc::Call::Builder initCall(); - inline void adoptCall(::capnp::Orphan< ::capnp::rpc::Call>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Call> disownCall(); - - inline bool isReturn(); - inline bool hasReturn(); - inline ::capnp::rpc::Return::Builder getReturn(); - inline void setReturn( ::capnp::rpc::Return::Reader value); - inline ::capnp::rpc::Return::Builder initReturn(); - inline void adoptReturn(::capnp::Orphan< ::capnp::rpc::Return>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Return> disownReturn(); - - inline bool isFinish(); - inline bool hasFinish(); - inline ::capnp::rpc::Finish::Builder getFinish(); - inline void setFinish( ::capnp::rpc::Finish::Reader value); - inline ::capnp::rpc::Finish::Builder initFinish(); - inline void adoptFinish(::capnp::Orphan< ::capnp::rpc::Finish>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Finish> disownFinish(); - - inline bool isResolve(); - inline bool hasResolve(); - inline ::capnp::rpc::Resolve::Builder getResolve(); - inline void setResolve( ::capnp::rpc::Resolve::Reader value); - inline ::capnp::rpc::Resolve::Builder initResolve(); - inline void adoptResolve(::capnp::Orphan< ::capnp::rpc::Resolve>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Resolve> disownResolve(); - - inline bool isRelease(); - inline bool hasRelease(); - inline ::capnp::rpc::Release::Builder getRelease(); - inline void setRelease( ::capnp::rpc::Release::Reader value); - inline ::capnp::rpc::Release::Builder initRelease(); - inline void adoptRelease(::capnp::Orphan< ::capnp::rpc::Release>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Release> disownRelease(); - - inline bool isObsoleteSave(); - inline bool hasObsoleteSave(); - inline ::capnp::AnyPointer::Builder getObsoleteSave(); - inline ::capnp::AnyPointer::Builder initObsoleteSave(); - - inline bool isBootstrap(); - inline bool hasBootstrap(); - inline ::capnp::rpc::Bootstrap::Builder getBootstrap(); - inline void setBootstrap( ::capnp::rpc::Bootstrap::Reader value); - inline ::capnp::rpc::Bootstrap::Builder initBootstrap(); - inline void adoptBootstrap(::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Bootstrap> disownBootstrap(); - - inline bool isObsoleteDelete(); - inline bool hasObsoleteDelete(); - inline ::capnp::AnyPointer::Builder getObsoleteDelete(); - inline ::capnp::AnyPointer::Builder initObsoleteDelete(); - - inline bool isProvide(); - inline bool hasProvide(); - inline ::capnp::rpc::Provide::Builder getProvide(); - inline void setProvide( ::capnp::rpc::Provide::Reader value); - inline ::capnp::rpc::Provide::Builder initProvide(); - inline void adoptProvide(::capnp::Orphan< ::capnp::rpc::Provide>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Provide> disownProvide(); - - inline bool isAccept(); - inline bool hasAccept(); - inline ::capnp::rpc::Accept::Builder getAccept(); - inline void setAccept( ::capnp::rpc::Accept::Reader value); - inline ::capnp::rpc::Accept::Builder initAccept(); - inline void adoptAccept(::capnp::Orphan< ::capnp::rpc::Accept>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Accept> disownAccept(); - - inline bool isJoin(); - inline bool hasJoin(); - inline ::capnp::rpc::Join::Builder getJoin(); - inline void setJoin( ::capnp::rpc::Join::Reader value); - inline ::capnp::rpc::Join::Builder initJoin(); - inline void adoptJoin(::capnp::Orphan< ::capnp::rpc::Join>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Join> disownJoin(); - - inline bool isDisembargo(); - inline bool hasDisembargo(); - inline ::capnp::rpc::Disembargo::Builder getDisembargo(); - inline void setDisembargo( ::capnp::rpc::Disembargo::Reader value); - inline ::capnp::rpc::Disembargo::Builder initDisembargo(); - inline void adoptDisembargo(::capnp::Orphan< ::capnp::rpc::Disembargo>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Disembargo> disownDisembargo(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Message::Pipeline { -public: - typedef Message Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Bootstrap::Reader { -public: - typedef Bootstrap Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasDeprecatedObjectId() const; - inline ::capnp::AnyPointer::Reader getDeprecatedObjectId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Bootstrap::Builder { -public: - typedef Bootstrap Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasDeprecatedObjectId(); - inline ::capnp::AnyPointer::Builder getDeprecatedObjectId(); - inline ::capnp::AnyPointer::Builder initDeprecatedObjectId(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Bootstrap::Pipeline { -public: - typedef Bootstrap Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Call::Reader { -public: - typedef Call Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasTarget() const; - inline ::capnp::rpc::MessageTarget::Reader getTarget() const; - - inline ::uint64_t getInterfaceId() const; - - inline ::uint16_t getMethodId() const; - - inline bool hasParams() const; - inline ::capnp::rpc::Payload::Reader getParams() const; - - inline typename SendResultsTo::Reader getSendResultsTo() const; - - inline bool getAllowThirdPartyTailCall() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Call::Builder { -public: - typedef Call Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasTarget(); - inline ::capnp::rpc::MessageTarget::Builder getTarget(); - inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); - inline ::capnp::rpc::MessageTarget::Builder initTarget(); - inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); - inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); - - inline ::uint64_t getInterfaceId(); - inline void setInterfaceId( ::uint64_t value); - - inline ::uint16_t getMethodId(); - inline void setMethodId( ::uint16_t value); - - inline bool hasParams(); - inline ::capnp::rpc::Payload::Builder getParams(); - inline void setParams( ::capnp::rpc::Payload::Reader value); - inline ::capnp::rpc::Payload::Builder initParams(); - inline void adoptParams(::capnp::Orphan< ::capnp::rpc::Payload>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Payload> disownParams(); - - inline typename SendResultsTo::Builder getSendResultsTo(); - inline typename SendResultsTo::Builder initSendResultsTo(); - - inline bool getAllowThirdPartyTailCall(); - inline void setAllowThirdPartyTailCall(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Call::Pipeline { -public: - typedef Call Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); - inline ::capnp::rpc::Payload::Pipeline getParams(); - inline typename SendResultsTo::Pipeline getSendResultsTo(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Call::SendResultsTo::Reader { -public: - typedef SendResultsTo Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isCaller() const; - inline ::capnp::Void getCaller() const; - - inline bool isYourself() const; - inline ::capnp::Void getYourself() const; - - inline bool isThirdParty() const; - inline bool hasThirdParty() const; - inline ::capnp::AnyPointer::Reader getThirdParty() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Call::SendResultsTo::Builder { -public: - typedef SendResultsTo Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isCaller(); - inline ::capnp::Void getCaller(); - inline void setCaller( ::capnp::Void value = ::capnp::VOID); - - inline bool isYourself(); - inline ::capnp::Void getYourself(); - inline void setYourself( ::capnp::Void value = ::capnp::VOID); - - inline bool isThirdParty(); - inline bool hasThirdParty(); - inline ::capnp::AnyPointer::Builder getThirdParty(); - inline ::capnp::AnyPointer::Builder initThirdParty(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Call::SendResultsTo::Pipeline { -public: - typedef SendResultsTo Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Return::Reader { -public: - typedef Return Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline ::uint32_t getAnswerId() const; - - inline bool getReleaseParamCaps() const; - - inline bool isResults() const; - inline bool hasResults() const; - inline ::capnp::rpc::Payload::Reader getResults() const; - - inline bool isException() const; - inline bool hasException() const; - inline ::capnp::rpc::Exception::Reader getException() const; - - inline bool isCanceled() const; - inline ::capnp::Void getCanceled() const; - - inline bool isResultsSentElsewhere() const; - inline ::capnp::Void getResultsSentElsewhere() const; - - inline bool isTakeFromOtherQuestion() const; - inline ::uint32_t getTakeFromOtherQuestion() const; - - inline bool isAcceptFromThirdParty() const; - inline bool hasAcceptFromThirdParty() const; - inline ::capnp::AnyPointer::Reader getAcceptFromThirdParty() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Return::Builder { -public: - typedef Return Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline ::uint32_t getAnswerId(); - inline void setAnswerId( ::uint32_t value); - - inline bool getReleaseParamCaps(); - inline void setReleaseParamCaps(bool value); - - inline bool isResults(); - inline bool hasResults(); - inline ::capnp::rpc::Payload::Builder getResults(); - inline void setResults( ::capnp::rpc::Payload::Reader value); - inline ::capnp::rpc::Payload::Builder initResults(); - inline void adoptResults(::capnp::Orphan< ::capnp::rpc::Payload>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Payload> disownResults(); - - inline bool isException(); - inline bool hasException(); - inline ::capnp::rpc::Exception::Builder getException(); - inline void setException( ::capnp::rpc::Exception::Reader value); - inline ::capnp::rpc::Exception::Builder initException(); - inline void adoptException(::capnp::Orphan< ::capnp::rpc::Exception>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Exception> disownException(); - - inline bool isCanceled(); - inline ::capnp::Void getCanceled(); - inline void setCanceled( ::capnp::Void value = ::capnp::VOID); - - inline bool isResultsSentElsewhere(); - inline ::capnp::Void getResultsSentElsewhere(); - inline void setResultsSentElsewhere( ::capnp::Void value = ::capnp::VOID); - - inline bool isTakeFromOtherQuestion(); - inline ::uint32_t getTakeFromOtherQuestion(); - inline void setTakeFromOtherQuestion( ::uint32_t value); - - inline bool isAcceptFromThirdParty(); - inline bool hasAcceptFromThirdParty(); - inline ::capnp::AnyPointer::Builder getAcceptFromThirdParty(); - inline ::capnp::AnyPointer::Builder initAcceptFromThirdParty(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Return::Pipeline { -public: - typedef Return Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Finish::Reader { -public: - typedef Finish Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool getReleaseResultCaps() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Finish::Builder { -public: - typedef Finish Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool getReleaseResultCaps(); - inline void setReleaseResultCaps(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Finish::Pipeline { -public: - typedef Finish Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Resolve::Reader { -public: - typedef Resolve Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline ::uint32_t getPromiseId() const; - - inline bool isCap() const; - inline bool hasCap() const; - inline ::capnp::rpc::CapDescriptor::Reader getCap() const; - - inline bool isException() const; - inline bool hasException() const; - inline ::capnp::rpc::Exception::Reader getException() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Resolve::Builder { -public: - typedef Resolve Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline ::uint32_t getPromiseId(); - inline void setPromiseId( ::uint32_t value); - - inline bool isCap(); - inline bool hasCap(); - inline ::capnp::rpc::CapDescriptor::Builder getCap(); - inline void setCap( ::capnp::rpc::CapDescriptor::Reader value); - inline ::capnp::rpc::CapDescriptor::Builder initCap(); - inline void adoptCap(::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value); - inline ::capnp::Orphan< ::capnp::rpc::CapDescriptor> disownCap(); - - inline bool isException(); - inline bool hasException(); - inline ::capnp::rpc::Exception::Builder getException(); - inline void setException( ::capnp::rpc::Exception::Reader value); - inline ::capnp::rpc::Exception::Builder initException(); - inline void adoptException(::capnp::Orphan< ::capnp::rpc::Exception>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Exception> disownException(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Resolve::Pipeline { -public: - typedef Resolve Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Release::Reader { -public: - typedef Release Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getId() const; - - inline ::uint32_t getReferenceCount() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Release::Builder { -public: - typedef Release Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getId(); - inline void setId( ::uint32_t value); - - inline ::uint32_t getReferenceCount(); - inline void setReferenceCount( ::uint32_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Release::Pipeline { -public: - typedef Release Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Disembargo::Reader { -public: - typedef Disembargo Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasTarget() const; - inline ::capnp::rpc::MessageTarget::Reader getTarget() const; - - inline typename Context::Reader getContext() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Disembargo::Builder { -public: - typedef Disembargo Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasTarget(); - inline ::capnp::rpc::MessageTarget::Builder getTarget(); - inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); - inline ::capnp::rpc::MessageTarget::Builder initTarget(); - inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); - inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); - - inline typename Context::Builder getContext(); - inline typename Context::Builder initContext(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Disembargo::Pipeline { -public: - typedef Disembargo Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); - inline typename Context::Pipeline getContext(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Disembargo::Context::Reader { -public: - typedef Context Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isSenderLoopback() const; - inline ::uint32_t getSenderLoopback() const; - - inline bool isReceiverLoopback() const; - inline ::uint32_t getReceiverLoopback() const; - - inline bool isAccept() const; - inline ::capnp::Void getAccept() const; - - inline bool isProvide() const; - inline ::uint32_t getProvide() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Disembargo::Context::Builder { -public: - typedef Context Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isSenderLoopback(); - inline ::uint32_t getSenderLoopback(); - inline void setSenderLoopback( ::uint32_t value); - - inline bool isReceiverLoopback(); - inline ::uint32_t getReceiverLoopback(); - inline void setReceiverLoopback( ::uint32_t value); - - inline bool isAccept(); - inline ::capnp::Void getAccept(); - inline void setAccept( ::capnp::Void value = ::capnp::VOID); - - inline bool isProvide(); - inline ::uint32_t getProvide(); - inline void setProvide( ::uint32_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Disembargo::Context::Pipeline { -public: - typedef Context Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Provide::Reader { -public: - typedef Provide Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasTarget() const; - inline ::capnp::rpc::MessageTarget::Reader getTarget() const; - - inline bool hasRecipient() const; - inline ::capnp::AnyPointer::Reader getRecipient() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Provide::Builder { -public: - typedef Provide Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasTarget(); - inline ::capnp::rpc::MessageTarget::Builder getTarget(); - inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); - inline ::capnp::rpc::MessageTarget::Builder initTarget(); - inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); - inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); - - inline bool hasRecipient(); - inline ::capnp::AnyPointer::Builder getRecipient(); - inline ::capnp::AnyPointer::Builder initRecipient(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Provide::Pipeline { -public: - typedef Provide Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Accept::Reader { -public: - typedef Accept Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasProvision() const; - inline ::capnp::AnyPointer::Reader getProvision() const; - - inline bool getEmbargo() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Accept::Builder { -public: - typedef Accept Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasProvision(); - inline ::capnp::AnyPointer::Builder getProvision(); - inline ::capnp::AnyPointer::Builder initProvision(); - - inline bool getEmbargo(); - inline void setEmbargo(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Accept::Pipeline { -public: - typedef Accept Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Join::Reader { -public: - typedef Join Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasTarget() const; - inline ::capnp::rpc::MessageTarget::Reader getTarget() const; - - inline bool hasKeyPart() const; - inline ::capnp::AnyPointer::Reader getKeyPart() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Join::Builder { -public: - typedef Join Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasTarget(); - inline ::capnp::rpc::MessageTarget::Builder getTarget(); - inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); - inline ::capnp::rpc::MessageTarget::Builder initTarget(); - inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); - inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); - - inline bool hasKeyPart(); - inline ::capnp::AnyPointer::Builder getKeyPart(); - inline ::capnp::AnyPointer::Builder initKeyPart(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Join::Pipeline { -public: - typedef Join Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class MessageTarget::Reader { -public: - typedef MessageTarget Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isImportedCap() const; - inline ::uint32_t getImportedCap() const; - - inline bool isPromisedAnswer() const; - inline bool hasPromisedAnswer() const; - inline ::capnp::rpc::PromisedAnswer::Reader getPromisedAnswer() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class MessageTarget::Builder { -public: - typedef MessageTarget Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isImportedCap(); - inline ::uint32_t getImportedCap(); - inline void setImportedCap( ::uint32_t value); - - inline bool isPromisedAnswer(); - inline bool hasPromisedAnswer(); - inline ::capnp::rpc::PromisedAnswer::Builder getPromisedAnswer(); - inline void setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value); - inline ::capnp::rpc::PromisedAnswer::Builder initPromisedAnswer(); - inline void adoptPromisedAnswer(::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value); - inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> disownPromisedAnswer(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class MessageTarget::Pipeline { -public: - typedef MessageTarget Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Payload::Reader { -public: - typedef Payload Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasContent() const; - inline ::capnp::AnyPointer::Reader getContent() const; - - inline bool hasCapTable() const; - inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader getCapTable() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Payload::Builder { -public: - typedef Payload Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasContent(); - inline ::capnp::AnyPointer::Builder getContent(); - inline ::capnp::AnyPointer::Builder initContent(); - - inline bool hasCapTable(); - inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder getCapTable(); - inline void setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader value); - inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder initCapTable(unsigned int size); - inline void adoptCapTable(::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>> disownCapTable(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Payload::Pipeline { -public: - typedef Payload Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CapDescriptor::Reader { -public: - typedef CapDescriptor Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isNone() const; - inline ::capnp::Void getNone() const; - - inline bool isSenderHosted() const; - inline ::uint32_t getSenderHosted() const; - - inline bool isSenderPromise() const; - inline ::uint32_t getSenderPromise() const; - - inline bool isReceiverHosted() const; - inline ::uint32_t getReceiverHosted() const; - - inline bool isReceiverAnswer() const; - inline bool hasReceiverAnswer() const; - inline ::capnp::rpc::PromisedAnswer::Reader getReceiverAnswer() const; - - inline bool isThirdPartyHosted() const; - inline bool hasThirdPartyHosted() const; - inline ::capnp::rpc::ThirdPartyCapDescriptor::Reader getThirdPartyHosted() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CapDescriptor::Builder { -public: - typedef CapDescriptor Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isNone(); - inline ::capnp::Void getNone(); - inline void setNone( ::capnp::Void value = ::capnp::VOID); - - inline bool isSenderHosted(); - inline ::uint32_t getSenderHosted(); - inline void setSenderHosted( ::uint32_t value); - - inline bool isSenderPromise(); - inline ::uint32_t getSenderPromise(); - inline void setSenderPromise( ::uint32_t value); - - inline bool isReceiverHosted(); - inline ::uint32_t getReceiverHosted(); - inline void setReceiverHosted( ::uint32_t value); - - inline bool isReceiverAnswer(); - inline bool hasReceiverAnswer(); - inline ::capnp::rpc::PromisedAnswer::Builder getReceiverAnswer(); - inline void setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value); - inline ::capnp::rpc::PromisedAnswer::Builder initReceiverAnswer(); - inline void adoptReceiverAnswer(::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value); - inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> disownReceiverAnswer(); - - inline bool isThirdPartyHosted(); - inline bool hasThirdPartyHosted(); - inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder getThirdPartyHosted(); - inline void setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value); - inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder initThirdPartyHosted(); - inline void adoptThirdPartyHosted(::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value); - inline ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor> disownThirdPartyHosted(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CapDescriptor::Pipeline { -public: - typedef CapDescriptor Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class PromisedAnswer::Reader { -public: - typedef PromisedAnswer Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasTransform() const; - inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader getTransform() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class PromisedAnswer::Builder { -public: - typedef PromisedAnswer Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasTransform(); - inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder getTransform(); - inline void setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader value); - inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder initTransform(unsigned int size); - inline void adoptTransform(::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>> disownTransform(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class PromisedAnswer::Pipeline { -public: - typedef PromisedAnswer Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class PromisedAnswer::Op::Reader { -public: - typedef Op Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isNoop() const; - inline ::capnp::Void getNoop() const; - - inline bool isGetPointerField() const; - inline ::uint16_t getGetPointerField() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class PromisedAnswer::Op::Builder { -public: - typedef Op Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isNoop(); - inline ::capnp::Void getNoop(); - inline void setNoop( ::capnp::Void value = ::capnp::VOID); - - inline bool isGetPointerField(); - inline ::uint16_t getGetPointerField(); - inline void setGetPointerField( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class PromisedAnswer::Op::Pipeline { -public: - typedef Op Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class ThirdPartyCapDescriptor::Reader { -public: - typedef ThirdPartyCapDescriptor Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasId() const; - inline ::capnp::AnyPointer::Reader getId() const; - - inline ::uint32_t getVineId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class ThirdPartyCapDescriptor::Builder { -public: - typedef ThirdPartyCapDescriptor Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasId(); - inline ::capnp::AnyPointer::Builder getId(); - inline ::capnp::AnyPointer::Builder initId(); - - inline ::uint32_t getVineId(); - inline void setVineId( ::uint32_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class ThirdPartyCapDescriptor::Pipeline { -public: - typedef ThirdPartyCapDescriptor Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Exception::Reader { -public: - typedef Exception Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasReason() const; - inline ::capnp::Text::Reader getReason() const; - - inline bool getObsoleteIsCallersFault() const; - - inline ::uint16_t getObsoleteDurability() const; - - inline ::capnp::rpc::Exception::Type getType() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Exception::Builder { -public: - typedef Exception Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasReason(); - inline ::capnp::Text::Builder getReason(); - inline void setReason( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initReason(unsigned int size); - inline void adoptReason(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownReason(); - - inline bool getObsoleteIsCallersFault(); - inline void setObsoleteIsCallersFault(bool value); - - inline ::uint16_t getObsoleteDurability(); - inline void setObsoleteDurability( ::uint16_t value); - - inline ::capnp::rpc::Exception::Type getType(); - inline void setType( ::capnp::rpc::Exception::Type value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Exception::Pipeline { -public: - typedef Exception Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -inline ::capnp::rpc::Message::Which Message::Reader::which() const { - return _reader.getDataField(0 * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Message::Which Message::Builder::which() { - return _builder.getDataField(0 * ::capnp::ELEMENTS); -} - -inline bool Message::Reader::isUnimplemented() const { - return which() == Message::UNIMPLEMENTED; -} -inline bool Message::Builder::isUnimplemented() { - return which() == Message::UNIMPLEMENTED; -} -inline bool Message::Reader::hasUnimplemented() const { - if (which() != Message::UNIMPLEMENTED) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasUnimplemented() { - if (which() != Message::UNIMPLEMENTED) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Message::Reader Message::Reader::getUnimplemented() const { - KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Message::Builder Message::Builder::getUnimplemented() { - KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setUnimplemented( ::capnp::rpc::Message::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); - ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Message::Builder Message::Builder::initUnimplemented() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptUnimplemented( - ::capnp::Orphan< ::capnp::rpc::Message>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); - ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Message> Message::Builder::disownUnimplemented() { - KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isAbort() const { - return which() == Message::ABORT; -} -inline bool Message::Builder::isAbort() { - return which() == Message::ABORT; -} -inline bool Message::Reader::hasAbort() const { - if (which() != Message::ABORT) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasAbort() { - if (which() != Message::ABORT) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Exception::Reader Message::Reader::getAbort() const { - KJ_IREQUIRE((which() == Message::ABORT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Exception::Builder Message::Builder::getAbort() { - KJ_IREQUIRE((which() == Message::ABORT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setAbort( ::capnp::rpc::Exception::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::ABORT); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Exception::Builder Message::Builder::initAbort() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::ABORT); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptAbort( - ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::ABORT); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Exception> Message::Builder::disownAbort() { - KJ_IREQUIRE((which() == Message::ABORT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isCall() const { - return which() == Message::CALL; -} -inline bool Message::Builder::isCall() { - return which() == Message::CALL; -} -inline bool Message::Reader::hasCall() const { - if (which() != Message::CALL) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasCall() { - if (which() != Message::CALL) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Call::Reader Message::Reader::getCall() const { - KJ_IREQUIRE((which() == Message::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Call::Builder Message::Builder::getCall() { - KJ_IREQUIRE((which() == Message::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setCall( ::capnp::rpc::Call::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::CALL); - ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Call::Builder Message::Builder::initCall() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::CALL); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptCall( - ::capnp::Orphan< ::capnp::rpc::Call>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::CALL); - ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Call> Message::Builder::disownCall() { - KJ_IREQUIRE((which() == Message::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isReturn() const { - return which() == Message::RETURN; -} -inline bool Message::Builder::isReturn() { - return which() == Message::RETURN; -} -inline bool Message::Reader::hasReturn() const { - if (which() != Message::RETURN) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasReturn() { - if (which() != Message::RETURN) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Return::Reader Message::Reader::getReturn() const { - KJ_IREQUIRE((which() == Message::RETURN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Return::Builder Message::Builder::getReturn() { - KJ_IREQUIRE((which() == Message::RETURN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setReturn( ::capnp::rpc::Return::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RETURN); - ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Return::Builder Message::Builder::initReturn() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RETURN); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptReturn( - ::capnp::Orphan< ::capnp::rpc::Return>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RETURN); - ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Return> Message::Builder::disownReturn() { - KJ_IREQUIRE((which() == Message::RETURN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isFinish() const { - return which() == Message::FINISH; -} -inline bool Message::Builder::isFinish() { - return which() == Message::FINISH; -} -inline bool Message::Reader::hasFinish() const { - if (which() != Message::FINISH) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasFinish() { - if (which() != Message::FINISH) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Finish::Reader Message::Reader::getFinish() const { - KJ_IREQUIRE((which() == Message::FINISH), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Finish::Builder Message::Builder::getFinish() { - KJ_IREQUIRE((which() == Message::FINISH), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setFinish( ::capnp::rpc::Finish::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::FINISH); - ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Finish::Builder Message::Builder::initFinish() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::FINISH); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptFinish( - ::capnp::Orphan< ::capnp::rpc::Finish>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::FINISH); - ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Finish> Message::Builder::disownFinish() { - KJ_IREQUIRE((which() == Message::FINISH), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isResolve() const { - return which() == Message::RESOLVE; -} -inline bool Message::Builder::isResolve() { - return which() == Message::RESOLVE; -} -inline bool Message::Reader::hasResolve() const { - if (which() != Message::RESOLVE) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasResolve() { - if (which() != Message::RESOLVE) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Resolve::Reader Message::Reader::getResolve() const { - KJ_IREQUIRE((which() == Message::RESOLVE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Resolve::Builder Message::Builder::getResolve() { - KJ_IREQUIRE((which() == Message::RESOLVE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setResolve( ::capnp::rpc::Resolve::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RESOLVE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Resolve::Builder Message::Builder::initResolve() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RESOLVE); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptResolve( - ::capnp::Orphan< ::capnp::rpc::Resolve>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RESOLVE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Resolve> Message::Builder::disownResolve() { - KJ_IREQUIRE((which() == Message::RESOLVE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isRelease() const { - return which() == Message::RELEASE; -} -inline bool Message::Builder::isRelease() { - return which() == Message::RELEASE; -} -inline bool Message::Reader::hasRelease() const { - if (which() != Message::RELEASE) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasRelease() { - if (which() != Message::RELEASE) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Release::Reader Message::Reader::getRelease() const { - KJ_IREQUIRE((which() == Message::RELEASE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Release::Builder Message::Builder::getRelease() { - KJ_IREQUIRE((which() == Message::RELEASE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setRelease( ::capnp::rpc::Release::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RELEASE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Release::Builder Message::Builder::initRelease() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RELEASE); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptRelease( - ::capnp::Orphan< ::capnp::rpc::Release>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::RELEASE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Release> Message::Builder::disownRelease() { - KJ_IREQUIRE((which() == Message::RELEASE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isObsoleteSave() const { - return which() == Message::OBSOLETE_SAVE; -} -inline bool Message::Builder::isObsoleteSave() { - return which() == Message::OBSOLETE_SAVE; -} -inline bool Message::Reader::hasObsoleteSave() const { - if (which() != Message::OBSOLETE_SAVE) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasObsoleteSave() { - if (which() != Message::OBSOLETE_SAVE) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Message::Reader::getObsoleteSave() const { - KJ_IREQUIRE((which() == Message::OBSOLETE_SAVE), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Message::Builder::getObsoleteSave() { - KJ_IREQUIRE((which() == Message::OBSOLETE_SAVE), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteSave() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::OBSOLETE_SAVE); - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Message::Reader::isBootstrap() const { - return which() == Message::BOOTSTRAP; -} -inline bool Message::Builder::isBootstrap() { - return which() == Message::BOOTSTRAP; -} -inline bool Message::Reader::hasBootstrap() const { - if (which() != Message::BOOTSTRAP) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasBootstrap() { - if (which() != Message::BOOTSTRAP) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Bootstrap::Reader Message::Reader::getBootstrap() const { - KJ_IREQUIRE((which() == Message::BOOTSTRAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Bootstrap::Builder Message::Builder::getBootstrap() { - KJ_IREQUIRE((which() == Message::BOOTSTRAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setBootstrap( ::capnp::rpc::Bootstrap::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::BOOTSTRAP); - ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Bootstrap::Builder Message::Builder::initBootstrap() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::BOOTSTRAP); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptBootstrap( - ::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::BOOTSTRAP); - ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Bootstrap> Message::Builder::disownBootstrap() { - KJ_IREQUIRE((which() == Message::BOOTSTRAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isObsoleteDelete() const { - return which() == Message::OBSOLETE_DELETE; -} -inline bool Message::Builder::isObsoleteDelete() { - return which() == Message::OBSOLETE_DELETE; -} -inline bool Message::Reader::hasObsoleteDelete() const { - if (which() != Message::OBSOLETE_DELETE) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasObsoleteDelete() { - if (which() != Message::OBSOLETE_DELETE) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Message::Reader::getObsoleteDelete() const { - KJ_IREQUIRE((which() == Message::OBSOLETE_DELETE), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Message::Builder::getObsoleteDelete() { - KJ_IREQUIRE((which() == Message::OBSOLETE_DELETE), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteDelete() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::OBSOLETE_DELETE); - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Message::Reader::isProvide() const { - return which() == Message::PROVIDE; -} -inline bool Message::Builder::isProvide() { - return which() == Message::PROVIDE; -} -inline bool Message::Reader::hasProvide() const { - if (which() != Message::PROVIDE) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasProvide() { - if (which() != Message::PROVIDE) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Provide::Reader Message::Reader::getProvide() const { - KJ_IREQUIRE((which() == Message::PROVIDE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Provide::Builder Message::Builder::getProvide() { - KJ_IREQUIRE((which() == Message::PROVIDE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setProvide( ::capnp::rpc::Provide::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::PROVIDE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Provide::Builder Message::Builder::initProvide() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::PROVIDE); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptProvide( - ::capnp::Orphan< ::capnp::rpc::Provide>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::PROVIDE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Provide> Message::Builder::disownProvide() { - KJ_IREQUIRE((which() == Message::PROVIDE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isAccept() const { - return which() == Message::ACCEPT; -} -inline bool Message::Builder::isAccept() { - return which() == Message::ACCEPT; -} -inline bool Message::Reader::hasAccept() const { - if (which() != Message::ACCEPT) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasAccept() { - if (which() != Message::ACCEPT) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Accept::Reader Message::Reader::getAccept() const { - KJ_IREQUIRE((which() == Message::ACCEPT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Accept::Builder Message::Builder::getAccept() { - KJ_IREQUIRE((which() == Message::ACCEPT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setAccept( ::capnp::rpc::Accept::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::ACCEPT); - ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Accept::Builder Message::Builder::initAccept() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::ACCEPT); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptAccept( - ::capnp::Orphan< ::capnp::rpc::Accept>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::ACCEPT); - ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Accept> Message::Builder::disownAccept() { - KJ_IREQUIRE((which() == Message::ACCEPT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isJoin() const { - return which() == Message::JOIN; -} -inline bool Message::Builder::isJoin() { - return which() == Message::JOIN; -} -inline bool Message::Reader::hasJoin() const { - if (which() != Message::JOIN) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasJoin() { - if (which() != Message::JOIN) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Join::Reader Message::Reader::getJoin() const { - KJ_IREQUIRE((which() == Message::JOIN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Join::Builder Message::Builder::getJoin() { - KJ_IREQUIRE((which() == Message::JOIN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setJoin( ::capnp::rpc::Join::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::JOIN); - ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Join::Builder Message::Builder::initJoin() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::JOIN); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptJoin( - ::capnp::Orphan< ::capnp::rpc::Join>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::JOIN); - ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Join> Message::Builder::disownJoin() { - KJ_IREQUIRE((which() == Message::JOIN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isDisembargo() const { - return which() == Message::DISEMBARGO; -} -inline bool Message::Builder::isDisembargo() { - return which() == Message::DISEMBARGO; -} -inline bool Message::Reader::hasDisembargo() const { - if (which() != Message::DISEMBARGO) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasDisembargo() { - if (which() != Message::DISEMBARGO) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Disembargo::Reader Message::Reader::getDisembargo() const { - KJ_IREQUIRE((which() == Message::DISEMBARGO), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Disembargo::Builder Message::Builder::getDisembargo() { - KJ_IREQUIRE((which() == Message::DISEMBARGO), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::setDisembargo( ::capnp::rpc::Disembargo::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::DISEMBARGO); - ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Disembargo::Builder Message::Builder::initDisembargo() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::DISEMBARGO); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptDisembargo( - ::capnp::Orphan< ::capnp::rpc::Disembargo>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Message::DISEMBARGO); - ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Disembargo> Message::Builder::disownDisembargo() { - KJ_IREQUIRE((which() == Message::DISEMBARGO), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint32_t Bootstrap::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Bootstrap::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Bootstrap::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Bootstrap::Reader::hasDeprecatedObjectId() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Bootstrap::Builder::hasDeprecatedObjectId() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Bootstrap::Reader::getDeprecatedObjectId() const { - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Bootstrap::Builder::getDeprecatedObjectId() { - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Bootstrap::Builder::initDeprecatedObjectId() { - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint32_t Call::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Call::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Call::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Call::Reader::hasTarget() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Call::Builder::hasTarget() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::MessageTarget::Reader Call::Reader::getTarget() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::MessageTarget::Builder Call::Builder::getTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::MessageTarget::Pipeline Call::Pipeline::getTarget() { - return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Call::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::MessageTarget::Builder Call::Builder::initTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Call::Builder::adoptTarget( - ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Call::Builder::disownTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint64_t Call::Reader::getInterfaceId() const { - return _reader.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Call::Builder::getInterfaceId() { - return _builder.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Call::Builder::setInterfaceId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Call::Reader::getMethodId() const { - return _reader.getDataField< ::uint16_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Call::Builder::getMethodId() { - return _builder.getDataField< ::uint16_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Call::Builder::setMethodId( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline bool Call::Reader::hasParams() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Call::Builder::hasParams() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Payload::Reader Call::Reader::getParams() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Payload::Builder Call::Builder::getParams() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::Payload::Pipeline Call::Pipeline::getParams() { - return ::capnp::rpc::Payload::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -inline void Call::Builder::setParams( ::capnp::rpc::Payload::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Payload::Builder Call::Builder::initParams() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void Call::Builder::adoptParams( - ::capnp::Orphan< ::capnp::rpc::Payload>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Payload> Call::Builder::disownParams() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline typename Call::SendResultsTo::Reader Call::Reader::getSendResultsTo() const { - return typename Call::SendResultsTo::Reader(_reader); -} -inline typename Call::SendResultsTo::Builder Call::Builder::getSendResultsTo() { - return typename Call::SendResultsTo::Builder(_builder); -} -#if !CAPNP_LITE -inline typename Call::SendResultsTo::Pipeline Call::Pipeline::getSendResultsTo() { - return typename Call::SendResultsTo::Pipeline(_typeless.noop()); -} -#endif // !CAPNP_LITE -inline typename Call::SendResultsTo::Builder Call::Builder::initSendResultsTo() { - _builder.setDataField< ::uint16_t>(3 * ::capnp::ELEMENTS, 0); - _builder.getPointerField(2 * ::capnp::POINTERS).clear(); - return typename Call::SendResultsTo::Builder(_builder); -} -inline bool Call::Reader::getAllowThirdPartyTailCall() const { - return _reader.getDataField( - 128 * ::capnp::ELEMENTS); -} - -inline bool Call::Builder::getAllowThirdPartyTailCall() { - return _builder.getDataField( - 128 * ::capnp::ELEMENTS); -} -inline void Call::Builder::setAllowThirdPartyTailCall(bool value) { - _builder.setDataField( - 128 * ::capnp::ELEMENTS, value); -} - -inline ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Reader::which() const { - return _reader.getDataField(3 * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Builder::which() { - return _builder.getDataField(3 * ::capnp::ELEMENTS); -} - -inline bool Call::SendResultsTo::Reader::isCaller() const { - return which() == Call::SendResultsTo::CALLER; -} -inline bool Call::SendResultsTo::Builder::isCaller() { - return which() == Call::SendResultsTo::CALLER; -} -inline ::capnp::Void Call::SendResultsTo::Reader::getCaller() const { - KJ_IREQUIRE((which() == Call::SendResultsTo::CALLER), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Call::SendResultsTo::Builder::getCaller() { - KJ_IREQUIRE((which() == Call::SendResultsTo::CALLER), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Call::SendResultsTo::Builder::setCaller( ::capnp::Void value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Call::SendResultsTo::CALLER); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Call::SendResultsTo::Reader::isYourself() const { - return which() == Call::SendResultsTo::YOURSELF; -} -inline bool Call::SendResultsTo::Builder::isYourself() { - return which() == Call::SendResultsTo::YOURSELF; -} -inline ::capnp::Void Call::SendResultsTo::Reader::getYourself() const { - KJ_IREQUIRE((which() == Call::SendResultsTo::YOURSELF), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Call::SendResultsTo::Builder::getYourself() { - KJ_IREQUIRE((which() == Call::SendResultsTo::YOURSELF), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Call::SendResultsTo::Builder::setYourself( ::capnp::Void value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Call::SendResultsTo::YOURSELF); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Call::SendResultsTo::Reader::isThirdParty() const { - return which() == Call::SendResultsTo::THIRD_PARTY; -} -inline bool Call::SendResultsTo::Builder::isThirdParty() { - return which() == Call::SendResultsTo::THIRD_PARTY; -} -inline bool Call::SendResultsTo::Reader::hasThirdParty() const { - if (which() != Call::SendResultsTo::THIRD_PARTY) return false; - return !_reader.getPointerField(2 * ::capnp::POINTERS).isNull(); -} -inline bool Call::SendResultsTo::Builder::hasThirdParty() { - if (which() != Call::SendResultsTo::THIRD_PARTY) return false; - return !_builder.getPointerField(2 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Call::SendResultsTo::Reader::getThirdParty() const { - KJ_IREQUIRE((which() == Call::SendResultsTo::THIRD_PARTY), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(2 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::getThirdParty() { - KJ_IREQUIRE((which() == Call::SendResultsTo::THIRD_PARTY), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::initThirdParty() { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Call::SendResultsTo::THIRD_PARTY); - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(2 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::capnp::rpc::Return::Which Return::Reader::which() const { - return _reader.getDataField(3 * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Return::Which Return::Builder::which() { - return _builder.getDataField(3 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Return::Reader::getAnswerId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Return::Builder::getAnswerId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Return::Builder::setAnswerId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Return::Reader::getReleaseParamCaps() const { - return _reader.getDataField( - 32 * ::capnp::ELEMENTS, true); -} - -inline bool Return::Builder::getReleaseParamCaps() { - return _builder.getDataField( - 32 * ::capnp::ELEMENTS, true); -} -inline void Return::Builder::setReleaseParamCaps(bool value) { - _builder.setDataField( - 32 * ::capnp::ELEMENTS, value, true); -} - -inline bool Return::Reader::isResults() const { - return which() == Return::RESULTS; -} -inline bool Return::Builder::isResults() { - return which() == Return::RESULTS; -} -inline bool Return::Reader::hasResults() const { - if (which() != Return::RESULTS) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Return::Builder::hasResults() { - if (which() != Return::RESULTS) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Payload::Reader Return::Reader::getResults() const { - KJ_IREQUIRE((which() == Return::RESULTS), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Payload::Builder Return::Builder::getResults() { - KJ_IREQUIRE((which() == Return::RESULTS), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Return::Builder::setResults( ::capnp::rpc::Payload::Reader value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::RESULTS); - ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Payload::Builder Return::Builder::initResults() { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::RESULTS); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Return::Builder::adoptResults( - ::capnp::Orphan< ::capnp::rpc::Payload>&& value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::RESULTS); - ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Payload> Return::Builder::disownResults() { - KJ_IREQUIRE((which() == Return::RESULTS), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Return::Reader::isException() const { - return which() == Return::EXCEPTION; -} -inline bool Return::Builder::isException() { - return which() == Return::EXCEPTION; -} -inline bool Return::Reader::hasException() const { - if (which() != Return::EXCEPTION) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Return::Builder::hasException() { - if (which() != Return::EXCEPTION) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Exception::Reader Return::Reader::getException() const { - KJ_IREQUIRE((which() == Return::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Exception::Builder Return::Builder::getException() { - KJ_IREQUIRE((which() == Return::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Return::Builder::setException( ::capnp::rpc::Exception::Reader value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::EXCEPTION); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Exception::Builder Return::Builder::initException() { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::EXCEPTION); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Return::Builder::adoptException( - ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::EXCEPTION); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Exception> Return::Builder::disownException() { - KJ_IREQUIRE((which() == Return::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Return::Reader::isCanceled() const { - return which() == Return::CANCELED; -} -inline bool Return::Builder::isCanceled() { - return which() == Return::CANCELED; -} -inline ::capnp::Void Return::Reader::getCanceled() const { - KJ_IREQUIRE((which() == Return::CANCELED), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Return::Builder::getCanceled() { - KJ_IREQUIRE((which() == Return::CANCELED), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Return::Builder::setCanceled( ::capnp::Void value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::CANCELED); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Return::Reader::isResultsSentElsewhere() const { - return which() == Return::RESULTS_SENT_ELSEWHERE; -} -inline bool Return::Builder::isResultsSentElsewhere() { - return which() == Return::RESULTS_SENT_ELSEWHERE; -} -inline ::capnp::Void Return::Reader::getResultsSentElsewhere() const { - KJ_IREQUIRE((which() == Return::RESULTS_SENT_ELSEWHERE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Return::Builder::getResultsSentElsewhere() { - KJ_IREQUIRE((which() == Return::RESULTS_SENT_ELSEWHERE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Return::Builder::setResultsSentElsewhere( ::capnp::Void value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::RESULTS_SENT_ELSEWHERE); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Return::Reader::isTakeFromOtherQuestion() const { - return which() == Return::TAKE_FROM_OTHER_QUESTION; -} -inline bool Return::Builder::isTakeFromOtherQuestion() { - return which() == Return::TAKE_FROM_OTHER_QUESTION; -} -inline ::uint32_t Return::Reader::getTakeFromOtherQuestion() const { - KJ_IREQUIRE((which() == Return::TAKE_FROM_OTHER_QUESTION), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Return::Builder::getTakeFromOtherQuestion() { - KJ_IREQUIRE((which() == Return::TAKE_FROM_OTHER_QUESTION), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Return::Builder::setTakeFromOtherQuestion( ::uint32_t value) { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::TAKE_FROM_OTHER_QUESTION); - _builder.setDataField< ::uint32_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline bool Return::Reader::isAcceptFromThirdParty() const { - return which() == Return::ACCEPT_FROM_THIRD_PARTY; -} -inline bool Return::Builder::isAcceptFromThirdParty() { - return which() == Return::ACCEPT_FROM_THIRD_PARTY; -} -inline bool Return::Reader::hasAcceptFromThirdParty() const { - if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Return::Builder::hasAcceptFromThirdParty() { - if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Return::Reader::getAcceptFromThirdParty() const { - KJ_IREQUIRE((which() == Return::ACCEPT_FROM_THIRD_PARTY), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Return::Builder::getAcceptFromThirdParty() { - KJ_IREQUIRE((which() == Return::ACCEPT_FROM_THIRD_PARTY), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Return::Builder::initAcceptFromThirdParty() { - _builder.setDataField( - 3 * ::capnp::ELEMENTS, Return::ACCEPT_FROM_THIRD_PARTY); - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint32_t Finish::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Finish::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Finish::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Finish::Reader::getReleaseResultCaps() const { - return _reader.getDataField( - 32 * ::capnp::ELEMENTS, true); -} - -inline bool Finish::Builder::getReleaseResultCaps() { - return _builder.getDataField( - 32 * ::capnp::ELEMENTS, true); -} -inline void Finish::Builder::setReleaseResultCaps(bool value) { - _builder.setDataField( - 32 * ::capnp::ELEMENTS, value, true); -} - -inline ::capnp::rpc::Resolve::Which Resolve::Reader::which() const { - return _reader.getDataField(2 * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Resolve::Which Resolve::Builder::which() { - return _builder.getDataField(2 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Resolve::Reader::getPromiseId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Resolve::Builder::getPromiseId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Resolve::Builder::setPromiseId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Resolve::Reader::isCap() const { - return which() == Resolve::CAP; -} -inline bool Resolve::Builder::isCap() { - return which() == Resolve::CAP; -} -inline bool Resolve::Reader::hasCap() const { - if (which() != Resolve::CAP) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Resolve::Builder::hasCap() { - if (which() != Resolve::CAP) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::CapDescriptor::Reader Resolve::Reader::getCap() const { - KJ_IREQUIRE((which() == Resolve::CAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::getCap() { - KJ_IREQUIRE((which() == Resolve::CAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Resolve::Builder::setCap( ::capnp::rpc::CapDescriptor::Reader value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Resolve::CAP); - ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::initCap() { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Resolve::CAP); - return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Resolve::Builder::adoptCap( - ::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Resolve::CAP); - ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::CapDescriptor> Resolve::Builder::disownCap() { - KJ_IREQUIRE((which() == Resolve::CAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Resolve::Reader::isException() const { - return which() == Resolve::EXCEPTION; -} -inline bool Resolve::Builder::isException() { - return which() == Resolve::EXCEPTION; -} -inline bool Resolve::Reader::hasException() const { - if (which() != Resolve::EXCEPTION) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Resolve::Builder::hasException() { - if (which() != Resolve::EXCEPTION) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Exception::Reader Resolve::Reader::getException() const { - KJ_IREQUIRE((which() == Resolve::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Exception::Builder Resolve::Builder::getException() { - KJ_IREQUIRE((which() == Resolve::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Resolve::Builder::setException( ::capnp::rpc::Exception::Reader value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Resolve::EXCEPTION); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Exception::Builder Resolve::Builder::initException() { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Resolve::EXCEPTION); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Resolve::Builder::adoptException( - ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Resolve::EXCEPTION); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Exception> Resolve::Builder::disownException() { - KJ_IREQUIRE((which() == Resolve::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint32_t Release::Reader::getId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Release::Builder::getId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Release::Builder::setId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t Release::Reader::getReferenceCount() const { - return _reader.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Release::Builder::getReferenceCount() { - return _builder.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Release::Builder::setReferenceCount( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Disembargo::Reader::hasTarget() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Disembargo::Builder::hasTarget() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::MessageTarget::Reader Disembargo::Reader::getTarget() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::getTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::MessageTarget::Pipeline Disembargo::Pipeline::getTarget() { - return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Disembargo::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::initTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Disembargo::Builder::adoptTarget( - ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Disembargo::Builder::disownTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline typename Disembargo::Context::Reader Disembargo::Reader::getContext() const { - return typename Disembargo::Context::Reader(_reader); -} -inline typename Disembargo::Context::Builder Disembargo::Builder::getContext() { - return typename Disembargo::Context::Builder(_builder); -} -#if !CAPNP_LITE -inline typename Disembargo::Context::Pipeline Disembargo::Pipeline::getContext() { - return typename Disembargo::Context::Pipeline(_typeless.noop()); -} -#endif // !CAPNP_LITE -inline typename Disembargo::Context::Builder Disembargo::Builder::initContext() { - _builder.setDataField< ::uint32_t>(0 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(2 * ::capnp::ELEMENTS, 0); - return typename Disembargo::Context::Builder(_builder); -} -inline ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Reader::which() const { - return _reader.getDataField(2 * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Builder::which() { - return _builder.getDataField(2 * ::capnp::ELEMENTS); -} - -inline bool Disembargo::Context::Reader::isSenderLoopback() const { - return which() == Disembargo::Context::SENDER_LOOPBACK; -} -inline bool Disembargo::Context::Builder::isSenderLoopback() { - return which() == Disembargo::Context::SENDER_LOOPBACK; -} -inline ::uint32_t Disembargo::Context::Reader::getSenderLoopback() const { - KJ_IREQUIRE((which() == Disembargo::Context::SENDER_LOOPBACK), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Disembargo::Context::Builder::getSenderLoopback() { - KJ_IREQUIRE((which() == Disembargo::Context::SENDER_LOOPBACK), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Disembargo::Context::Builder::setSenderLoopback( ::uint32_t value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Disembargo::Context::SENDER_LOOPBACK); - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Disembargo::Context::Reader::isReceiverLoopback() const { - return which() == Disembargo::Context::RECEIVER_LOOPBACK; -} -inline bool Disembargo::Context::Builder::isReceiverLoopback() { - return which() == Disembargo::Context::RECEIVER_LOOPBACK; -} -inline ::uint32_t Disembargo::Context::Reader::getReceiverLoopback() const { - KJ_IREQUIRE((which() == Disembargo::Context::RECEIVER_LOOPBACK), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Disembargo::Context::Builder::getReceiverLoopback() { - KJ_IREQUIRE((which() == Disembargo::Context::RECEIVER_LOOPBACK), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Disembargo::Context::Builder::setReceiverLoopback( ::uint32_t value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Disembargo::Context::RECEIVER_LOOPBACK); - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Disembargo::Context::Reader::isAccept() const { - return which() == Disembargo::Context::ACCEPT; -} -inline bool Disembargo::Context::Builder::isAccept() { - return which() == Disembargo::Context::ACCEPT; -} -inline ::capnp::Void Disembargo::Context::Reader::getAccept() const { - KJ_IREQUIRE((which() == Disembargo::Context::ACCEPT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Disembargo::Context::Builder::getAccept() { - KJ_IREQUIRE((which() == Disembargo::Context::ACCEPT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Disembargo::Context::Builder::setAccept( ::capnp::Void value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Disembargo::Context::ACCEPT); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Disembargo::Context::Reader::isProvide() const { - return which() == Disembargo::Context::PROVIDE; -} -inline bool Disembargo::Context::Builder::isProvide() { - return which() == Disembargo::Context::PROVIDE; -} -inline ::uint32_t Disembargo::Context::Reader::getProvide() const { - KJ_IREQUIRE((which() == Disembargo::Context::PROVIDE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Disembargo::Context::Builder::getProvide() { - KJ_IREQUIRE((which() == Disembargo::Context::PROVIDE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Disembargo::Context::Builder::setProvide( ::uint32_t value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, Disembargo::Context::PROVIDE); - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t Provide::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Provide::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Provide::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Provide::Reader::hasTarget() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Provide::Builder::hasTarget() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::MessageTarget::Reader Provide::Reader::getTarget() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::MessageTarget::Builder Provide::Builder::getTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::MessageTarget::Pipeline Provide::Pipeline::getTarget() { - return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Provide::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::MessageTarget::Builder Provide::Builder::initTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Provide::Builder::adoptTarget( - ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Provide::Builder::disownTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Provide::Reader::hasRecipient() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Provide::Builder::hasRecipient() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Provide::Reader::getRecipient() const { - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Provide::Builder::getRecipient() { - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Provide::Builder::initRecipient() { - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(1 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint32_t Accept::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Accept::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Accept::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Accept::Reader::hasProvision() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Accept::Builder::hasProvision() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Accept::Reader::getProvision() const { - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Accept::Builder::getProvision() { - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Accept::Builder::initProvision() { - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Accept::Reader::getEmbargo() const { - return _reader.getDataField( - 32 * ::capnp::ELEMENTS); -} - -inline bool Accept::Builder::getEmbargo() { - return _builder.getDataField( - 32 * ::capnp::ELEMENTS); -} -inline void Accept::Builder::setEmbargo(bool value) { - _builder.setDataField( - 32 * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t Join::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Join::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Join::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Join::Reader::hasTarget() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Join::Builder::hasTarget() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::MessageTarget::Reader Join::Reader::getTarget() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::MessageTarget::Builder Join::Builder::getTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::MessageTarget::Pipeline Join::Pipeline::getTarget() { - return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Join::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::MessageTarget::Builder Join::Builder::initTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Join::Builder::adoptTarget( - ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Join::Builder::disownTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Join::Reader::hasKeyPart() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Join::Builder::hasKeyPart() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Join::Reader::getKeyPart() const { - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Join::Builder::getKeyPart() { - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Join::Builder::initKeyPart() { - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(1 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::capnp::rpc::MessageTarget::Which MessageTarget::Reader::which() const { - return _reader.getDataField(2 * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::MessageTarget::Which MessageTarget::Builder::which() { - return _builder.getDataField(2 * ::capnp::ELEMENTS); -} - -inline bool MessageTarget::Reader::isImportedCap() const { - return which() == MessageTarget::IMPORTED_CAP; -} -inline bool MessageTarget::Builder::isImportedCap() { - return which() == MessageTarget::IMPORTED_CAP; -} -inline ::uint32_t MessageTarget::Reader::getImportedCap() const { - KJ_IREQUIRE((which() == MessageTarget::IMPORTED_CAP), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t MessageTarget::Builder::getImportedCap() { - KJ_IREQUIRE((which() == MessageTarget::IMPORTED_CAP), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void MessageTarget::Builder::setImportedCap( ::uint32_t value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, MessageTarget::IMPORTED_CAP); - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool MessageTarget::Reader::isPromisedAnswer() const { - return which() == MessageTarget::PROMISED_ANSWER; -} -inline bool MessageTarget::Builder::isPromisedAnswer() { - return which() == MessageTarget::PROMISED_ANSWER; -} -inline bool MessageTarget::Reader::hasPromisedAnswer() const { - if (which() != MessageTarget::PROMISED_ANSWER) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool MessageTarget::Builder::hasPromisedAnswer() { - if (which() != MessageTarget::PROMISED_ANSWER) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::PromisedAnswer::Reader MessageTarget::Reader::getPromisedAnswer() const { - KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::getPromisedAnswer() { - KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void MessageTarget::Builder::setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); - ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::initPromisedAnswer() { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void MessageTarget::Builder::adoptPromisedAnswer( - ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) { - _builder.setDataField( - 2 * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); - ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> MessageTarget::Builder::disownPromisedAnswer() { - KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Payload::Reader::hasContent() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Payload::Builder::hasContent() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Payload::Reader::getContent() const { - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Payload::Builder::getContent() { - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Payload::Builder::initContent() { - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Payload::Reader::hasCapTable() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Payload::Builder::hasCapTable() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader Payload::Reader::getCapTable() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder Payload::Builder::getCapTable() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void Payload::Builder::setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder Payload::Builder::initCapTable(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::init( - _builder.getPointerField(1 * ::capnp::POINTERS), size); -} -inline void Payload::Builder::adoptCapTable( - ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>> Payload::Builder::disownCapTable() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline ::capnp::rpc::CapDescriptor::Which CapDescriptor::Reader::which() const { - return _reader.getDataField(0 * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::CapDescriptor::Which CapDescriptor::Builder::which() { - return _builder.getDataField(0 * ::capnp::ELEMENTS); -} - -inline bool CapDescriptor::Reader::isNone() const { - return which() == CapDescriptor::NONE; -} -inline bool CapDescriptor::Builder::isNone() { - return which() == CapDescriptor::NONE; -} -inline ::capnp::Void CapDescriptor::Reader::getNone() const { - KJ_IREQUIRE((which() == CapDescriptor::NONE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void CapDescriptor::Builder::getNone() { - KJ_IREQUIRE((which() == CapDescriptor::NONE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void CapDescriptor::Builder::setNone( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::NONE); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool CapDescriptor::Reader::isSenderHosted() const { - return which() == CapDescriptor::SENDER_HOSTED; -} -inline bool CapDescriptor::Builder::isSenderHosted() { - return which() == CapDescriptor::SENDER_HOSTED; -} -inline ::uint32_t CapDescriptor::Reader::getSenderHosted() const { - KJ_IREQUIRE((which() == CapDescriptor::SENDER_HOSTED), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint32_t CapDescriptor::Builder::getSenderHosted() { - KJ_IREQUIRE((which() == CapDescriptor::SENDER_HOSTED), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} -inline void CapDescriptor::Builder::setSenderHosted( ::uint32_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::SENDER_HOSTED); - _builder.setDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool CapDescriptor::Reader::isSenderPromise() const { - return which() == CapDescriptor::SENDER_PROMISE; -} -inline bool CapDescriptor::Builder::isSenderPromise() { - return which() == CapDescriptor::SENDER_PROMISE; -} -inline ::uint32_t CapDescriptor::Reader::getSenderPromise() const { - KJ_IREQUIRE((which() == CapDescriptor::SENDER_PROMISE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint32_t CapDescriptor::Builder::getSenderPromise() { - KJ_IREQUIRE((which() == CapDescriptor::SENDER_PROMISE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} -inline void CapDescriptor::Builder::setSenderPromise( ::uint32_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::SENDER_PROMISE); - _builder.setDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool CapDescriptor::Reader::isReceiverHosted() const { - return which() == CapDescriptor::RECEIVER_HOSTED; -} -inline bool CapDescriptor::Builder::isReceiverHosted() { - return which() == CapDescriptor::RECEIVER_HOSTED; -} -inline ::uint32_t CapDescriptor::Reader::getReceiverHosted() const { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_HOSTED), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint32_t CapDescriptor::Builder::getReceiverHosted() { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_HOSTED), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} -inline void CapDescriptor::Builder::setReceiverHosted( ::uint32_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_HOSTED); - _builder.setDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool CapDescriptor::Reader::isReceiverAnswer() const { - return which() == CapDescriptor::RECEIVER_ANSWER; -} -inline bool CapDescriptor::Builder::isReceiverAnswer() { - return which() == CapDescriptor::RECEIVER_ANSWER; -} -inline bool CapDescriptor::Reader::hasReceiverAnswer() const { - if (which() != CapDescriptor::RECEIVER_ANSWER) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool CapDescriptor::Builder::hasReceiverAnswer() { - if (which() != CapDescriptor::RECEIVER_ANSWER) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::PromisedAnswer::Reader CapDescriptor::Reader::getReceiverAnswer() const { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::getReceiverAnswer() { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void CapDescriptor::Builder::setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); - ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::initReceiverAnswer() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void CapDescriptor::Builder::adoptReceiverAnswer( - ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); - ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> CapDescriptor::Builder::disownReceiverAnswer() { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool CapDescriptor::Reader::isThirdPartyHosted() const { - return which() == CapDescriptor::THIRD_PARTY_HOSTED; -} -inline bool CapDescriptor::Builder::isThirdPartyHosted() { - return which() == CapDescriptor::THIRD_PARTY_HOSTED; -} -inline bool CapDescriptor::Reader::hasThirdPartyHosted() const { - if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool CapDescriptor::Builder::hasThirdPartyHosted() { - if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::ThirdPartyCapDescriptor::Reader CapDescriptor::Reader::getThirdPartyHosted() const { - KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::getThirdPartyHosted() { - KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void CapDescriptor::Builder::setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); - ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::initThirdPartyHosted() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); - return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void CapDescriptor::Builder::adoptThirdPartyHosted( - ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); - ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor> CapDescriptor::Builder::disownThirdPartyHosted() { - KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint32_t PromisedAnswer::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t PromisedAnswer::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void PromisedAnswer::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool PromisedAnswer::Reader::hasTransform() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool PromisedAnswer::Builder::hasTransform() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader PromisedAnswer::Reader::getTransform() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder PromisedAnswer::Builder::getTransform() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void PromisedAnswer::Builder::setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder PromisedAnswer::Builder::initTransform(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void PromisedAnswer::Builder::adoptTransform( - ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>> PromisedAnswer::Builder::disownTransform() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Reader::which() const { - return _reader.getDataField(0 * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Builder::which() { - return _builder.getDataField(0 * ::capnp::ELEMENTS); -} - -inline bool PromisedAnswer::Op::Reader::isNoop() const { - return which() == PromisedAnswer::Op::NOOP; -} -inline bool PromisedAnswer::Op::Builder::isNoop() { - return which() == PromisedAnswer::Op::NOOP; -} -inline ::capnp::Void PromisedAnswer::Op::Reader::getNoop() const { - KJ_IREQUIRE((which() == PromisedAnswer::Op::NOOP), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void PromisedAnswer::Op::Builder::getNoop() { - KJ_IREQUIRE((which() == PromisedAnswer::Op::NOOP), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void PromisedAnswer::Op::Builder::setNoop( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, PromisedAnswer::Op::NOOP); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool PromisedAnswer::Op::Reader::isGetPointerField() const { - return which() == PromisedAnswer::Op::GET_POINTER_FIELD; -} -inline bool PromisedAnswer::Op::Builder::isGetPointerField() { - return which() == PromisedAnswer::Op::GET_POINTER_FIELD; -} -inline ::uint16_t PromisedAnswer::Op::Reader::getGetPointerField() const { - KJ_IREQUIRE((which() == PromisedAnswer::Op::GET_POINTER_FIELD), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint16_t PromisedAnswer::Op::Builder::getGetPointerField() { - KJ_IREQUIRE((which() == PromisedAnswer::Op::GET_POINTER_FIELD), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS); -} -inline void PromisedAnswer::Op::Builder::setGetPointerField( ::uint16_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, PromisedAnswer::Op::GET_POINTER_FIELD); - _builder.setDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool ThirdPartyCapDescriptor::Reader::hasId() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool ThirdPartyCapDescriptor::Builder::hasId() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader ThirdPartyCapDescriptor::Reader::getId() const { - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::getId() { - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::initId() { - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint32_t ThirdPartyCapDescriptor::Reader::getVineId() const { - return _reader.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint32_t ThirdPartyCapDescriptor::Builder::getVineId() { - return _builder.getDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS); -} -inline void ThirdPartyCapDescriptor::Builder::setVineId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Exception::Reader::hasReason() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Exception::Builder::hasReason() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Exception::Reader::getReason() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Exception::Builder::getReason() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Exception::Builder::setReason( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Exception::Builder::initReason(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Exception::Builder::adoptReason( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Exception::Builder::disownReason() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Exception::Reader::getObsoleteIsCallersFault() const { - return _reader.getDataField( - 0 * ::capnp::ELEMENTS); -} - -inline bool Exception::Builder::getObsoleteIsCallersFault() { - return _builder.getDataField( - 0 * ::capnp::ELEMENTS); -} -inline void Exception::Builder::setObsoleteIsCallersFault(bool value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Exception::Reader::getObsoleteDurability() const { - return _reader.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Exception::Builder::getObsoleteDurability() { - return _builder.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Exception::Builder::setObsoleteDurability( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline ::capnp::rpc::Exception::Type Exception::Reader::getType() const { - return _reader.getDataField< ::capnp::rpc::Exception::Type>( - 2 * ::capnp::ELEMENTS); -} - -inline ::capnp::rpc::Exception::Type Exception::Builder::getType() { - return _builder.getDataField< ::capnp::rpc::Exception::Type>( - 2 * ::capnp::ELEMENTS); -} -inline void Exception::Builder::setType( ::capnp::rpc::Exception::Type value) { - _builder.setDataField< ::capnp::rpc::Exception::Type>( - 2 * ::capnp::ELEMENTS, value); -} - -} // namespace -} // namespace - -#endif // CAPNP_INCLUDED_b312981b2552a250_ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: rpc.capnp + +#ifndef CAPNP_INCLUDED_b312981b2552a250_ +#define CAPNP_INCLUDED_b312981b2552a250_ + +#include + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(91b79f1f808db032); +CAPNP_DECLARE_SCHEMA(e94ccf8031176ec4); +CAPNP_DECLARE_SCHEMA(836a53ce789d4cd4); +CAPNP_DECLARE_SCHEMA(dae8b0f61aab5f99); +CAPNP_DECLARE_SCHEMA(9e19b28d3db3573a); +CAPNP_DECLARE_SCHEMA(d37d2eb2c2f80e63); +CAPNP_DECLARE_SCHEMA(bbc29655fa89086e); +CAPNP_DECLARE_SCHEMA(ad1a6c0d7dd07497); +CAPNP_DECLARE_SCHEMA(f964368b0fbd3711); +CAPNP_DECLARE_SCHEMA(d562b4df655bdd4d); +CAPNP_DECLARE_SCHEMA(9c6a046bfbc1ac5a); +CAPNP_DECLARE_SCHEMA(d4c9b56290554016); +CAPNP_DECLARE_SCHEMA(fbe1980490e001af); +CAPNP_DECLARE_SCHEMA(95bc14545813fbc1); +CAPNP_DECLARE_SCHEMA(9a0e61223d96743b); +CAPNP_DECLARE_SCHEMA(8523ddc40b86b8b0); +CAPNP_DECLARE_SCHEMA(d800b1d6cd6f1ca0); +CAPNP_DECLARE_SCHEMA(f316944415569081); +CAPNP_DECLARE_SCHEMA(d37007fde1f0027d); +CAPNP_DECLARE_SCHEMA(d625b7063acf691a); +CAPNP_DECLARE_SCHEMA(b28c96e23f4cbd58); +enum class Type_b28c96e23f4cbd58: uint16_t { + FAILED, + OVERLOADED, + DISCONNECTED, + UNIMPLEMENTED, +}; +CAPNP_DECLARE_ENUM(Type, b28c96e23f4cbd58); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace rpc { + +struct Message { + Message() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + UNIMPLEMENTED, + ABORT, + CALL, + RETURN, + FINISH, + RESOLVE, + RELEASE, + OBSOLETE_SAVE, + BOOTSTRAP, + OBSOLETE_DELETE, + PROVIDE, + ACCEPT, + JOIN, + DISEMBARGO, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(91b79f1f808db032, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Bootstrap { + Bootstrap() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(e94ccf8031176ec4, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Call { + Call() = delete; + + class Reader; + class Builder; + class Pipeline; + struct SendResultsTo; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(836a53ce789d4cd4, 3, 3) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Call::SendResultsTo { + SendResultsTo() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + CALLER, + YOURSELF, + THIRD_PARTY, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(dae8b0f61aab5f99, 3, 3) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Return { + Return() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + RESULTS, + EXCEPTION, + CANCELED, + RESULTS_SENT_ELSEWHERE, + TAKE_FROM_OTHER_QUESTION, + ACCEPT_FROM_THIRD_PARTY, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9e19b28d3db3573a, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Finish { + Finish() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d37d2eb2c2f80e63, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Resolve { + Resolve() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + CAP, + EXCEPTION, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bbc29655fa89086e, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Release { + Release() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ad1a6c0d7dd07497, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Disembargo { + Disembargo() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Context; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f964368b0fbd3711, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Disembargo::Context { + Context() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + SENDER_LOOPBACK, + RECEIVER_LOOPBACK, + ACCEPT, + PROVIDE, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d562b4df655bdd4d, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Provide { + Provide() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9c6a046bfbc1ac5a, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Accept { + Accept() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d4c9b56290554016, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Join { + Join() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(fbe1980490e001af, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct MessageTarget { + MessageTarget() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + IMPORTED_CAP, + PROMISED_ANSWER, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(95bc14545813fbc1, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Payload { + Payload() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9a0e61223d96743b, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CapDescriptor { + CapDescriptor() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + NONE, + SENDER_HOSTED, + SENDER_PROMISE, + RECEIVER_HOSTED, + RECEIVER_ANSWER, + THIRD_PARTY_HOSTED, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(8523ddc40b86b8b0, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct PromisedAnswer { + PromisedAnswer() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Op; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d800b1d6cd6f1ca0, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct PromisedAnswer::Op { + Op() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + NOOP, + GET_POINTER_FIELD, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f316944415569081, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct ThirdPartyCapDescriptor { + ThirdPartyCapDescriptor() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d37007fde1f0027d, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Exception { + Exception() = delete; + + class Reader; + class Builder; + class Pipeline; + typedef ::capnp::schemas::Type_b28c96e23f4cbd58 Type; + + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d625b7063acf691a, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class Message::Reader { +public: + typedef Message Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isUnimplemented() const; + inline bool hasUnimplemented() const; + inline ::capnp::rpc::Message::Reader getUnimplemented() const; + + inline bool isAbort() const; + inline bool hasAbort() const; + inline ::capnp::rpc::Exception::Reader getAbort() const; + + inline bool isCall() const; + inline bool hasCall() const; + inline ::capnp::rpc::Call::Reader getCall() const; + + inline bool isReturn() const; + inline bool hasReturn() const; + inline ::capnp::rpc::Return::Reader getReturn() const; + + inline bool isFinish() const; + inline bool hasFinish() const; + inline ::capnp::rpc::Finish::Reader getFinish() const; + + inline bool isResolve() const; + inline bool hasResolve() const; + inline ::capnp::rpc::Resolve::Reader getResolve() const; + + inline bool isRelease() const; + inline bool hasRelease() const; + inline ::capnp::rpc::Release::Reader getRelease() const; + + inline bool isObsoleteSave() const; + inline bool hasObsoleteSave() const; + inline ::capnp::AnyPointer::Reader getObsoleteSave() const; + + inline bool isBootstrap() const; + inline bool hasBootstrap() const; + inline ::capnp::rpc::Bootstrap::Reader getBootstrap() const; + + inline bool isObsoleteDelete() const; + inline bool hasObsoleteDelete() const; + inline ::capnp::AnyPointer::Reader getObsoleteDelete() const; + + inline bool isProvide() const; + inline bool hasProvide() const; + inline ::capnp::rpc::Provide::Reader getProvide() const; + + inline bool isAccept() const; + inline bool hasAccept() const; + inline ::capnp::rpc::Accept::Reader getAccept() const; + + inline bool isJoin() const; + inline bool hasJoin() const; + inline ::capnp::rpc::Join::Reader getJoin() const; + + inline bool isDisembargo() const; + inline bool hasDisembargo() const; + inline ::capnp::rpc::Disembargo::Reader getDisembargo() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Message::Builder { +public: + typedef Message Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isUnimplemented(); + inline bool hasUnimplemented(); + inline ::capnp::rpc::Message::Builder getUnimplemented(); + inline void setUnimplemented( ::capnp::rpc::Message::Reader value); + inline ::capnp::rpc::Message::Builder initUnimplemented(); + inline void adoptUnimplemented(::capnp::Orphan< ::capnp::rpc::Message>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Message> disownUnimplemented(); + + inline bool isAbort(); + inline bool hasAbort(); + inline ::capnp::rpc::Exception::Builder getAbort(); + inline void setAbort( ::capnp::rpc::Exception::Reader value); + inline ::capnp::rpc::Exception::Builder initAbort(); + inline void adoptAbort(::capnp::Orphan< ::capnp::rpc::Exception>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Exception> disownAbort(); + + inline bool isCall(); + inline bool hasCall(); + inline ::capnp::rpc::Call::Builder getCall(); + inline void setCall( ::capnp::rpc::Call::Reader value); + inline ::capnp::rpc::Call::Builder initCall(); + inline void adoptCall(::capnp::Orphan< ::capnp::rpc::Call>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Call> disownCall(); + + inline bool isReturn(); + inline bool hasReturn(); + inline ::capnp::rpc::Return::Builder getReturn(); + inline void setReturn( ::capnp::rpc::Return::Reader value); + inline ::capnp::rpc::Return::Builder initReturn(); + inline void adoptReturn(::capnp::Orphan< ::capnp::rpc::Return>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Return> disownReturn(); + + inline bool isFinish(); + inline bool hasFinish(); + inline ::capnp::rpc::Finish::Builder getFinish(); + inline void setFinish( ::capnp::rpc::Finish::Reader value); + inline ::capnp::rpc::Finish::Builder initFinish(); + inline void adoptFinish(::capnp::Orphan< ::capnp::rpc::Finish>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Finish> disownFinish(); + + inline bool isResolve(); + inline bool hasResolve(); + inline ::capnp::rpc::Resolve::Builder getResolve(); + inline void setResolve( ::capnp::rpc::Resolve::Reader value); + inline ::capnp::rpc::Resolve::Builder initResolve(); + inline void adoptResolve(::capnp::Orphan< ::capnp::rpc::Resolve>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Resolve> disownResolve(); + + inline bool isRelease(); + inline bool hasRelease(); + inline ::capnp::rpc::Release::Builder getRelease(); + inline void setRelease( ::capnp::rpc::Release::Reader value); + inline ::capnp::rpc::Release::Builder initRelease(); + inline void adoptRelease(::capnp::Orphan< ::capnp::rpc::Release>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Release> disownRelease(); + + inline bool isObsoleteSave(); + inline bool hasObsoleteSave(); + inline ::capnp::AnyPointer::Builder getObsoleteSave(); + inline ::capnp::AnyPointer::Builder initObsoleteSave(); + + inline bool isBootstrap(); + inline bool hasBootstrap(); + inline ::capnp::rpc::Bootstrap::Builder getBootstrap(); + inline void setBootstrap( ::capnp::rpc::Bootstrap::Reader value); + inline ::capnp::rpc::Bootstrap::Builder initBootstrap(); + inline void adoptBootstrap(::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Bootstrap> disownBootstrap(); + + inline bool isObsoleteDelete(); + inline bool hasObsoleteDelete(); + inline ::capnp::AnyPointer::Builder getObsoleteDelete(); + inline ::capnp::AnyPointer::Builder initObsoleteDelete(); + + inline bool isProvide(); + inline bool hasProvide(); + inline ::capnp::rpc::Provide::Builder getProvide(); + inline void setProvide( ::capnp::rpc::Provide::Reader value); + inline ::capnp::rpc::Provide::Builder initProvide(); + inline void adoptProvide(::capnp::Orphan< ::capnp::rpc::Provide>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Provide> disownProvide(); + + inline bool isAccept(); + inline bool hasAccept(); + inline ::capnp::rpc::Accept::Builder getAccept(); + inline void setAccept( ::capnp::rpc::Accept::Reader value); + inline ::capnp::rpc::Accept::Builder initAccept(); + inline void adoptAccept(::capnp::Orphan< ::capnp::rpc::Accept>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Accept> disownAccept(); + + inline bool isJoin(); + inline bool hasJoin(); + inline ::capnp::rpc::Join::Builder getJoin(); + inline void setJoin( ::capnp::rpc::Join::Reader value); + inline ::capnp::rpc::Join::Builder initJoin(); + inline void adoptJoin(::capnp::Orphan< ::capnp::rpc::Join>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Join> disownJoin(); + + inline bool isDisembargo(); + inline bool hasDisembargo(); + inline ::capnp::rpc::Disembargo::Builder getDisembargo(); + inline void setDisembargo( ::capnp::rpc::Disembargo::Reader value); + inline ::capnp::rpc::Disembargo::Builder initDisembargo(); + inline void adoptDisembargo(::capnp::Orphan< ::capnp::rpc::Disembargo>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Disembargo> disownDisembargo(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Message::Pipeline { +public: + typedef Message Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Bootstrap::Reader { +public: + typedef Bootstrap Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId() const; + + inline bool hasDeprecatedObjectId() const; + inline ::capnp::AnyPointer::Reader getDeprecatedObjectId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Bootstrap::Builder { +public: + typedef Bootstrap Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId(); + inline void setQuestionId( ::uint32_t value); + + inline bool hasDeprecatedObjectId(); + inline ::capnp::AnyPointer::Builder getDeprecatedObjectId(); + inline ::capnp::AnyPointer::Builder initDeprecatedObjectId(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Bootstrap::Pipeline { +public: + typedef Bootstrap Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Call::Reader { +public: + typedef Call Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId() const; + + inline bool hasTarget() const; + inline ::capnp::rpc::MessageTarget::Reader getTarget() const; + + inline ::uint64_t getInterfaceId() const; + + inline ::uint16_t getMethodId() const; + + inline bool hasParams() const; + inline ::capnp::rpc::Payload::Reader getParams() const; + + inline typename SendResultsTo::Reader getSendResultsTo() const; + + inline bool getAllowThirdPartyTailCall() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Call::Builder { +public: + typedef Call Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId(); + inline void setQuestionId( ::uint32_t value); + + inline bool hasTarget(); + inline ::capnp::rpc::MessageTarget::Builder getTarget(); + inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); + inline ::capnp::rpc::MessageTarget::Builder initTarget(); + inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); + inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); + + inline ::uint64_t getInterfaceId(); + inline void setInterfaceId( ::uint64_t value); + + inline ::uint16_t getMethodId(); + inline void setMethodId( ::uint16_t value); + + inline bool hasParams(); + inline ::capnp::rpc::Payload::Builder getParams(); + inline void setParams( ::capnp::rpc::Payload::Reader value); + inline ::capnp::rpc::Payload::Builder initParams(); + inline void adoptParams(::capnp::Orphan< ::capnp::rpc::Payload>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Payload> disownParams(); + + inline typename SendResultsTo::Builder getSendResultsTo(); + inline typename SendResultsTo::Builder initSendResultsTo(); + + inline bool getAllowThirdPartyTailCall(); + inline void setAllowThirdPartyTailCall(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Call::Pipeline { +public: + typedef Call Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); + inline ::capnp::rpc::Payload::Pipeline getParams(); + inline typename SendResultsTo::Pipeline getSendResultsTo(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Call::SendResultsTo::Reader { +public: + typedef SendResultsTo Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isCaller() const; + inline ::capnp::Void getCaller() const; + + inline bool isYourself() const; + inline ::capnp::Void getYourself() const; + + inline bool isThirdParty() const; + inline bool hasThirdParty() const; + inline ::capnp::AnyPointer::Reader getThirdParty() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Call::SendResultsTo::Builder { +public: + typedef SendResultsTo Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isCaller(); + inline ::capnp::Void getCaller(); + inline void setCaller( ::capnp::Void value = ::capnp::VOID); + + inline bool isYourself(); + inline ::capnp::Void getYourself(); + inline void setYourself( ::capnp::Void value = ::capnp::VOID); + + inline bool isThirdParty(); + inline bool hasThirdParty(); + inline ::capnp::AnyPointer::Builder getThirdParty(); + inline ::capnp::AnyPointer::Builder initThirdParty(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Call::SendResultsTo::Pipeline { +public: + typedef SendResultsTo Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Return::Reader { +public: + typedef Return Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline ::uint32_t getAnswerId() const; + + inline bool getReleaseParamCaps() const; + + inline bool isResults() const; + inline bool hasResults() const; + inline ::capnp::rpc::Payload::Reader getResults() const; + + inline bool isException() const; + inline bool hasException() const; + inline ::capnp::rpc::Exception::Reader getException() const; + + inline bool isCanceled() const; + inline ::capnp::Void getCanceled() const; + + inline bool isResultsSentElsewhere() const; + inline ::capnp::Void getResultsSentElsewhere() const; + + inline bool isTakeFromOtherQuestion() const; + inline ::uint32_t getTakeFromOtherQuestion() const; + + inline bool isAcceptFromThirdParty() const; + inline bool hasAcceptFromThirdParty() const; + inline ::capnp::AnyPointer::Reader getAcceptFromThirdParty() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Return::Builder { +public: + typedef Return Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline ::uint32_t getAnswerId(); + inline void setAnswerId( ::uint32_t value); + + inline bool getReleaseParamCaps(); + inline void setReleaseParamCaps(bool value); + + inline bool isResults(); + inline bool hasResults(); + inline ::capnp::rpc::Payload::Builder getResults(); + inline void setResults( ::capnp::rpc::Payload::Reader value); + inline ::capnp::rpc::Payload::Builder initResults(); + inline void adoptResults(::capnp::Orphan< ::capnp::rpc::Payload>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Payload> disownResults(); + + inline bool isException(); + inline bool hasException(); + inline ::capnp::rpc::Exception::Builder getException(); + inline void setException( ::capnp::rpc::Exception::Reader value); + inline ::capnp::rpc::Exception::Builder initException(); + inline void adoptException(::capnp::Orphan< ::capnp::rpc::Exception>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Exception> disownException(); + + inline bool isCanceled(); + inline ::capnp::Void getCanceled(); + inline void setCanceled( ::capnp::Void value = ::capnp::VOID); + + inline bool isResultsSentElsewhere(); + inline ::capnp::Void getResultsSentElsewhere(); + inline void setResultsSentElsewhere( ::capnp::Void value = ::capnp::VOID); + + inline bool isTakeFromOtherQuestion(); + inline ::uint32_t getTakeFromOtherQuestion(); + inline void setTakeFromOtherQuestion( ::uint32_t value); + + inline bool isAcceptFromThirdParty(); + inline bool hasAcceptFromThirdParty(); + inline ::capnp::AnyPointer::Builder getAcceptFromThirdParty(); + inline ::capnp::AnyPointer::Builder initAcceptFromThirdParty(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Return::Pipeline { +public: + typedef Return Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Finish::Reader { +public: + typedef Finish Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId() const; + + inline bool getReleaseResultCaps() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Finish::Builder { +public: + typedef Finish Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId(); + inline void setQuestionId( ::uint32_t value); + + inline bool getReleaseResultCaps(); + inline void setReleaseResultCaps(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Finish::Pipeline { +public: + typedef Finish Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Resolve::Reader { +public: + typedef Resolve Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline ::uint32_t getPromiseId() const; + + inline bool isCap() const; + inline bool hasCap() const; + inline ::capnp::rpc::CapDescriptor::Reader getCap() const; + + inline bool isException() const; + inline bool hasException() const; + inline ::capnp::rpc::Exception::Reader getException() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Resolve::Builder { +public: + typedef Resolve Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline ::uint32_t getPromiseId(); + inline void setPromiseId( ::uint32_t value); + + inline bool isCap(); + inline bool hasCap(); + inline ::capnp::rpc::CapDescriptor::Builder getCap(); + inline void setCap( ::capnp::rpc::CapDescriptor::Reader value); + inline ::capnp::rpc::CapDescriptor::Builder initCap(); + inline void adoptCap(::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value); + inline ::capnp::Orphan< ::capnp::rpc::CapDescriptor> disownCap(); + + inline bool isException(); + inline bool hasException(); + inline ::capnp::rpc::Exception::Builder getException(); + inline void setException( ::capnp::rpc::Exception::Reader value); + inline ::capnp::rpc::Exception::Builder initException(); + inline void adoptException(::capnp::Orphan< ::capnp::rpc::Exception>&& value); + inline ::capnp::Orphan< ::capnp::rpc::Exception> disownException(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Resolve::Pipeline { +public: + typedef Resolve Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Release::Reader { +public: + typedef Release Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getId() const; + + inline ::uint32_t getReferenceCount() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Release::Builder { +public: + typedef Release Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getId(); + inline void setId( ::uint32_t value); + + inline ::uint32_t getReferenceCount(); + inline void setReferenceCount( ::uint32_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Release::Pipeline { +public: + typedef Release Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Disembargo::Reader { +public: + typedef Disembargo Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasTarget() const; + inline ::capnp::rpc::MessageTarget::Reader getTarget() const; + + inline typename Context::Reader getContext() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Disembargo::Builder { +public: + typedef Disembargo Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasTarget(); + inline ::capnp::rpc::MessageTarget::Builder getTarget(); + inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); + inline ::capnp::rpc::MessageTarget::Builder initTarget(); + inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); + inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); + + inline typename Context::Builder getContext(); + inline typename Context::Builder initContext(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Disembargo::Pipeline { +public: + typedef Disembargo Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); + inline typename Context::Pipeline getContext(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Disembargo::Context::Reader { +public: + typedef Context Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isSenderLoopback() const; + inline ::uint32_t getSenderLoopback() const; + + inline bool isReceiverLoopback() const; + inline ::uint32_t getReceiverLoopback() const; + + inline bool isAccept() const; + inline ::capnp::Void getAccept() const; + + inline bool isProvide() const; + inline ::uint32_t getProvide() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Disembargo::Context::Builder { +public: + typedef Context Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isSenderLoopback(); + inline ::uint32_t getSenderLoopback(); + inline void setSenderLoopback( ::uint32_t value); + + inline bool isReceiverLoopback(); + inline ::uint32_t getReceiverLoopback(); + inline void setReceiverLoopback( ::uint32_t value); + + inline bool isAccept(); + inline ::capnp::Void getAccept(); + inline void setAccept( ::capnp::Void value = ::capnp::VOID); + + inline bool isProvide(); + inline ::uint32_t getProvide(); + inline void setProvide( ::uint32_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Disembargo::Context::Pipeline { +public: + typedef Context Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Provide::Reader { +public: + typedef Provide Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId() const; + + inline bool hasTarget() const; + inline ::capnp::rpc::MessageTarget::Reader getTarget() const; + + inline bool hasRecipient() const; + inline ::capnp::AnyPointer::Reader getRecipient() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Provide::Builder { +public: + typedef Provide Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId(); + inline void setQuestionId( ::uint32_t value); + + inline bool hasTarget(); + inline ::capnp::rpc::MessageTarget::Builder getTarget(); + inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); + inline ::capnp::rpc::MessageTarget::Builder initTarget(); + inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); + inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); + + inline bool hasRecipient(); + inline ::capnp::AnyPointer::Builder getRecipient(); + inline ::capnp::AnyPointer::Builder initRecipient(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Provide::Pipeline { +public: + typedef Provide Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Accept::Reader { +public: + typedef Accept Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId() const; + + inline bool hasProvision() const; + inline ::capnp::AnyPointer::Reader getProvision() const; + + inline bool getEmbargo() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Accept::Builder { +public: + typedef Accept Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId(); + inline void setQuestionId( ::uint32_t value); + + inline bool hasProvision(); + inline ::capnp::AnyPointer::Builder getProvision(); + inline ::capnp::AnyPointer::Builder initProvision(); + + inline bool getEmbargo(); + inline void setEmbargo(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Accept::Pipeline { +public: + typedef Accept Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Join::Reader { +public: + typedef Join Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId() const; + + inline bool hasTarget() const; + inline ::capnp::rpc::MessageTarget::Reader getTarget() const; + + inline bool hasKeyPart() const; + inline ::capnp::AnyPointer::Reader getKeyPart() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Join::Builder { +public: + typedef Join Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId(); + inline void setQuestionId( ::uint32_t value); + + inline bool hasTarget(); + inline ::capnp::rpc::MessageTarget::Builder getTarget(); + inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); + inline ::capnp::rpc::MessageTarget::Builder initTarget(); + inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); + inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); + + inline bool hasKeyPart(); + inline ::capnp::AnyPointer::Builder getKeyPart(); + inline ::capnp::AnyPointer::Builder initKeyPart(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Join::Pipeline { +public: + typedef Join Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class MessageTarget::Reader { +public: + typedef MessageTarget Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isImportedCap() const; + inline ::uint32_t getImportedCap() const; + + inline bool isPromisedAnswer() const; + inline bool hasPromisedAnswer() const; + inline ::capnp::rpc::PromisedAnswer::Reader getPromisedAnswer() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class MessageTarget::Builder { +public: + typedef MessageTarget Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isImportedCap(); + inline ::uint32_t getImportedCap(); + inline void setImportedCap( ::uint32_t value); + + inline bool isPromisedAnswer(); + inline bool hasPromisedAnswer(); + inline ::capnp::rpc::PromisedAnswer::Builder getPromisedAnswer(); + inline void setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value); + inline ::capnp::rpc::PromisedAnswer::Builder initPromisedAnswer(); + inline void adoptPromisedAnswer(::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value); + inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> disownPromisedAnswer(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class MessageTarget::Pipeline { +public: + typedef MessageTarget Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Payload::Reader { +public: + typedef Payload Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasContent() const; + inline ::capnp::AnyPointer::Reader getContent() const; + + inline bool hasCapTable() const; + inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader getCapTable() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Payload::Builder { +public: + typedef Payload Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasContent(); + inline ::capnp::AnyPointer::Builder getContent(); + inline ::capnp::AnyPointer::Builder initContent(); + + inline bool hasCapTable(); + inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder getCapTable(); + inline void setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader value); + inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder initCapTable(unsigned int size); + inline void adoptCapTable(::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>> disownCapTable(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Payload::Pipeline { +public: + typedef Payload Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CapDescriptor::Reader { +public: + typedef CapDescriptor Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isNone() const; + inline ::capnp::Void getNone() const; + + inline bool isSenderHosted() const; + inline ::uint32_t getSenderHosted() const; + + inline bool isSenderPromise() const; + inline ::uint32_t getSenderPromise() const; + + inline bool isReceiverHosted() const; + inline ::uint32_t getReceiverHosted() const; + + inline bool isReceiverAnswer() const; + inline bool hasReceiverAnswer() const; + inline ::capnp::rpc::PromisedAnswer::Reader getReceiverAnswer() const; + + inline bool isThirdPartyHosted() const; + inline bool hasThirdPartyHosted() const; + inline ::capnp::rpc::ThirdPartyCapDescriptor::Reader getThirdPartyHosted() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CapDescriptor::Builder { +public: + typedef CapDescriptor Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isNone(); + inline ::capnp::Void getNone(); + inline void setNone( ::capnp::Void value = ::capnp::VOID); + + inline bool isSenderHosted(); + inline ::uint32_t getSenderHosted(); + inline void setSenderHosted( ::uint32_t value); + + inline bool isSenderPromise(); + inline ::uint32_t getSenderPromise(); + inline void setSenderPromise( ::uint32_t value); + + inline bool isReceiverHosted(); + inline ::uint32_t getReceiverHosted(); + inline void setReceiverHosted( ::uint32_t value); + + inline bool isReceiverAnswer(); + inline bool hasReceiverAnswer(); + inline ::capnp::rpc::PromisedAnswer::Builder getReceiverAnswer(); + inline void setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value); + inline ::capnp::rpc::PromisedAnswer::Builder initReceiverAnswer(); + inline void adoptReceiverAnswer(::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value); + inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> disownReceiverAnswer(); + + inline bool isThirdPartyHosted(); + inline bool hasThirdPartyHosted(); + inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder getThirdPartyHosted(); + inline void setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value); + inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder initThirdPartyHosted(); + inline void adoptThirdPartyHosted(::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value); + inline ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor> disownThirdPartyHosted(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CapDescriptor::Pipeline { +public: + typedef CapDescriptor Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class PromisedAnswer::Reader { +public: + typedef PromisedAnswer Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId() const; + + inline bool hasTransform() const; + inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader getTransform() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class PromisedAnswer::Builder { +public: + typedef PromisedAnswer Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getQuestionId(); + inline void setQuestionId( ::uint32_t value); + + inline bool hasTransform(); + inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder getTransform(); + inline void setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader value); + inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder initTransform(unsigned int size); + inline void adoptTransform(::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>> disownTransform(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class PromisedAnswer::Pipeline { +public: + typedef PromisedAnswer Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class PromisedAnswer::Op::Reader { +public: + typedef Op Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isNoop() const; + inline ::capnp::Void getNoop() const; + + inline bool isGetPointerField() const; + inline ::uint16_t getGetPointerField() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class PromisedAnswer::Op::Builder { +public: + typedef Op Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isNoop(); + inline ::capnp::Void getNoop(); + inline void setNoop( ::capnp::Void value = ::capnp::VOID); + + inline bool isGetPointerField(); + inline ::uint16_t getGetPointerField(); + inline void setGetPointerField( ::uint16_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class PromisedAnswer::Op::Pipeline { +public: + typedef Op Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class ThirdPartyCapDescriptor::Reader { +public: + typedef ThirdPartyCapDescriptor Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasId() const; + inline ::capnp::AnyPointer::Reader getId() const; + + inline ::uint32_t getVineId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class ThirdPartyCapDescriptor::Builder { +public: + typedef ThirdPartyCapDescriptor Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasId(); + inline ::capnp::AnyPointer::Builder getId(); + inline ::capnp::AnyPointer::Builder initId(); + + inline ::uint32_t getVineId(); + inline void setVineId( ::uint32_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class ThirdPartyCapDescriptor::Pipeline { +public: + typedef ThirdPartyCapDescriptor Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Exception::Reader { +public: + typedef Exception Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasReason() const; + inline ::capnp::Text::Reader getReason() const; + + inline bool getObsoleteIsCallersFault() const; + + inline ::uint16_t getObsoleteDurability() const; + + inline ::capnp::rpc::Exception::Type getType() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Exception::Builder { +public: + typedef Exception Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasReason(); + inline ::capnp::Text::Builder getReason(); + inline void setReason( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initReason(unsigned int size); + inline void adoptReason(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownReason(); + + inline bool getObsoleteIsCallersFault(); + inline void setObsoleteIsCallersFault(bool value); + + inline ::uint16_t getObsoleteDurability(); + inline void setObsoleteDurability( ::uint16_t value); + + inline ::capnp::rpc::Exception::Type getType(); + inline void setType( ::capnp::rpc::Exception::Type value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Exception::Pipeline { +public: + typedef Exception Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline ::capnp::rpc::Message::Which Message::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Message::Which Message::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Message::Reader::isUnimplemented() const { + return which() == Message::UNIMPLEMENTED; +} +inline bool Message::Builder::isUnimplemented() { + return which() == Message::UNIMPLEMENTED; +} +inline bool Message::Reader::hasUnimplemented() const { + if (which() != Message::UNIMPLEMENTED) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasUnimplemented() { + if (which() != Message::UNIMPLEMENTED) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Message::Reader Message::Reader::getUnimplemented() const { + KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Message::Builder Message::Builder::getUnimplemented() { + KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setUnimplemented( ::capnp::rpc::Message::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); + ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Message::Builder Message::Builder::initUnimplemented() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptUnimplemented( + ::capnp::Orphan< ::capnp::rpc::Message>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); + ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Message> Message::Builder::disownUnimplemented() { + KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isAbort() const { + return which() == Message::ABORT; +} +inline bool Message::Builder::isAbort() { + return which() == Message::ABORT; +} +inline bool Message::Reader::hasAbort() const { + if (which() != Message::ABORT) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasAbort() { + if (which() != Message::ABORT) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Exception::Reader Message::Reader::getAbort() const { + KJ_IREQUIRE((which() == Message::ABORT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Exception::Builder Message::Builder::getAbort() { + KJ_IREQUIRE((which() == Message::ABORT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setAbort( ::capnp::rpc::Exception::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Exception::Builder Message::Builder::initAbort() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptAbort( + ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Exception> Message::Builder::disownAbort() { + KJ_IREQUIRE((which() == Message::ABORT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isCall() const { + return which() == Message::CALL; +} +inline bool Message::Builder::isCall() { + return which() == Message::CALL; +} +inline bool Message::Reader::hasCall() const { + if (which() != Message::CALL) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasCall() { + if (which() != Message::CALL) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Call::Reader Message::Reader::getCall() const { + KJ_IREQUIRE((which() == Message::CALL), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Call::Builder Message::Builder::getCall() { + KJ_IREQUIRE((which() == Message::CALL), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setCall( ::capnp::rpc::Call::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL); + ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Call::Builder Message::Builder::initCall() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptCall( + ::capnp::Orphan< ::capnp::rpc::Call>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL); + ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Call> Message::Builder::disownCall() { + KJ_IREQUIRE((which() == Message::CALL), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isReturn() const { + return which() == Message::RETURN; +} +inline bool Message::Builder::isReturn() { + return which() == Message::RETURN; +} +inline bool Message::Reader::hasReturn() const { + if (which() != Message::RETURN) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasReturn() { + if (which() != Message::RETURN) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Return::Reader Message::Reader::getReturn() const { + KJ_IREQUIRE((which() == Message::RETURN), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Return::Builder Message::Builder::getReturn() { + KJ_IREQUIRE((which() == Message::RETURN), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setReturn( ::capnp::rpc::Return::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN); + ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Return::Builder Message::Builder::initReturn() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptReturn( + ::capnp::Orphan< ::capnp::rpc::Return>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN); + ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Return> Message::Builder::disownReturn() { + KJ_IREQUIRE((which() == Message::RETURN), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isFinish() const { + return which() == Message::FINISH; +} +inline bool Message::Builder::isFinish() { + return which() == Message::FINISH; +} +inline bool Message::Reader::hasFinish() const { + if (which() != Message::FINISH) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasFinish() { + if (which() != Message::FINISH) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Finish::Reader Message::Reader::getFinish() const { + KJ_IREQUIRE((which() == Message::FINISH), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Finish::Builder Message::Builder::getFinish() { + KJ_IREQUIRE((which() == Message::FINISH), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setFinish( ::capnp::rpc::Finish::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH); + ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Finish::Builder Message::Builder::initFinish() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptFinish( + ::capnp::Orphan< ::capnp::rpc::Finish>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH); + ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Finish> Message::Builder::disownFinish() { + KJ_IREQUIRE((which() == Message::FINISH), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isResolve() const { + return which() == Message::RESOLVE; +} +inline bool Message::Builder::isResolve() { + return which() == Message::RESOLVE; +} +inline bool Message::Reader::hasResolve() const { + if (which() != Message::RESOLVE) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasResolve() { + if (which() != Message::RESOLVE) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Resolve::Reader Message::Reader::getResolve() const { + KJ_IREQUIRE((which() == Message::RESOLVE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Resolve::Builder Message::Builder::getResolve() { + KJ_IREQUIRE((which() == Message::RESOLVE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setResolve( ::capnp::rpc::Resolve::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Resolve::Builder Message::Builder::initResolve() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptResolve( + ::capnp::Orphan< ::capnp::rpc::Resolve>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Resolve> Message::Builder::disownResolve() { + KJ_IREQUIRE((which() == Message::RESOLVE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isRelease() const { + return which() == Message::RELEASE; +} +inline bool Message::Builder::isRelease() { + return which() == Message::RELEASE; +} +inline bool Message::Reader::hasRelease() const { + if (which() != Message::RELEASE) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasRelease() { + if (which() != Message::RELEASE) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Release::Reader Message::Reader::getRelease() const { + KJ_IREQUIRE((which() == Message::RELEASE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Release::Builder Message::Builder::getRelease() { + KJ_IREQUIRE((which() == Message::RELEASE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setRelease( ::capnp::rpc::Release::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Release::Builder Message::Builder::initRelease() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptRelease( + ::capnp::Orphan< ::capnp::rpc::Release>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Release> Message::Builder::disownRelease() { + KJ_IREQUIRE((which() == Message::RELEASE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isObsoleteSave() const { + return which() == Message::OBSOLETE_SAVE; +} +inline bool Message::Builder::isObsoleteSave() { + return which() == Message::OBSOLETE_SAVE; +} +inline bool Message::Reader::hasObsoleteSave() const { + if (which() != Message::OBSOLETE_SAVE) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasObsoleteSave() { + if (which() != Message::OBSOLETE_SAVE) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Message::Reader::getObsoleteSave() const { + KJ_IREQUIRE((which() == Message::OBSOLETE_SAVE), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Message::Builder::getObsoleteSave() { + KJ_IREQUIRE((which() == Message::OBSOLETE_SAVE), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteSave() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::OBSOLETE_SAVE); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Message::Reader::isBootstrap() const { + return which() == Message::BOOTSTRAP; +} +inline bool Message::Builder::isBootstrap() { + return which() == Message::BOOTSTRAP; +} +inline bool Message::Reader::hasBootstrap() const { + if (which() != Message::BOOTSTRAP) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasBootstrap() { + if (which() != Message::BOOTSTRAP) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Bootstrap::Reader Message::Reader::getBootstrap() const { + KJ_IREQUIRE((which() == Message::BOOTSTRAP), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Bootstrap::Builder Message::Builder::getBootstrap() { + KJ_IREQUIRE((which() == Message::BOOTSTRAP), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setBootstrap( ::capnp::rpc::Bootstrap::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP); + ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Bootstrap::Builder Message::Builder::initBootstrap() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptBootstrap( + ::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP); + ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Bootstrap> Message::Builder::disownBootstrap() { + KJ_IREQUIRE((which() == Message::BOOTSTRAP), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isObsoleteDelete() const { + return which() == Message::OBSOLETE_DELETE; +} +inline bool Message::Builder::isObsoleteDelete() { + return which() == Message::OBSOLETE_DELETE; +} +inline bool Message::Reader::hasObsoleteDelete() const { + if (which() != Message::OBSOLETE_DELETE) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasObsoleteDelete() { + if (which() != Message::OBSOLETE_DELETE) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Message::Reader::getObsoleteDelete() const { + KJ_IREQUIRE((which() == Message::OBSOLETE_DELETE), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Message::Builder::getObsoleteDelete() { + KJ_IREQUIRE((which() == Message::OBSOLETE_DELETE), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteDelete() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::OBSOLETE_DELETE); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Message::Reader::isProvide() const { + return which() == Message::PROVIDE; +} +inline bool Message::Builder::isProvide() { + return which() == Message::PROVIDE; +} +inline bool Message::Reader::hasProvide() const { + if (which() != Message::PROVIDE) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasProvide() { + if (which() != Message::PROVIDE) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Provide::Reader Message::Reader::getProvide() const { + KJ_IREQUIRE((which() == Message::PROVIDE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Provide::Builder Message::Builder::getProvide() { + KJ_IREQUIRE((which() == Message::PROVIDE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setProvide( ::capnp::rpc::Provide::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Provide::Builder Message::Builder::initProvide() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptProvide( + ::capnp::Orphan< ::capnp::rpc::Provide>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Provide> Message::Builder::disownProvide() { + KJ_IREQUIRE((which() == Message::PROVIDE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isAccept() const { + return which() == Message::ACCEPT; +} +inline bool Message::Builder::isAccept() { + return which() == Message::ACCEPT; +} +inline bool Message::Reader::hasAccept() const { + if (which() != Message::ACCEPT) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasAccept() { + if (which() != Message::ACCEPT) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Accept::Reader Message::Reader::getAccept() const { + KJ_IREQUIRE((which() == Message::ACCEPT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Accept::Builder Message::Builder::getAccept() { + KJ_IREQUIRE((which() == Message::ACCEPT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setAccept( ::capnp::rpc::Accept::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT); + ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Accept::Builder Message::Builder::initAccept() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptAccept( + ::capnp::Orphan< ::capnp::rpc::Accept>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT); + ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Accept> Message::Builder::disownAccept() { + KJ_IREQUIRE((which() == Message::ACCEPT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isJoin() const { + return which() == Message::JOIN; +} +inline bool Message::Builder::isJoin() { + return which() == Message::JOIN; +} +inline bool Message::Reader::hasJoin() const { + if (which() != Message::JOIN) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasJoin() { + if (which() != Message::JOIN) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Join::Reader Message::Reader::getJoin() const { + KJ_IREQUIRE((which() == Message::JOIN), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Join::Builder Message::Builder::getJoin() { + KJ_IREQUIRE((which() == Message::JOIN), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setJoin( ::capnp::rpc::Join::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN); + ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Join::Builder Message::Builder::initJoin() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptJoin( + ::capnp::Orphan< ::capnp::rpc::Join>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN); + ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Join> Message::Builder::disownJoin() { + KJ_IREQUIRE((which() == Message::JOIN), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Message::Reader::isDisembargo() const { + return which() == Message::DISEMBARGO; +} +inline bool Message::Builder::isDisembargo() { + return which() == Message::DISEMBARGO; +} +inline bool Message::Reader::hasDisembargo() const { + if (which() != Message::DISEMBARGO) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasDisembargo() { + if (which() != Message::DISEMBARGO) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Disembargo::Reader Message::Reader::getDisembargo() const { + KJ_IREQUIRE((which() == Message::DISEMBARGO), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Disembargo::Builder Message::Builder::getDisembargo() { + KJ_IREQUIRE((which() == Message::DISEMBARGO), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::setDisembargo( ::capnp::rpc::Disembargo::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO); + ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Disembargo::Builder Message::Builder::initDisembargo() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptDisembargo( + ::capnp::Orphan< ::capnp::rpc::Disembargo>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO); + ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Disembargo> Message::Builder::disownDisembargo() { + KJ_IREQUIRE((which() == Message::DISEMBARGO), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint32_t Bootstrap::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Bootstrap::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Bootstrap::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Bootstrap::Reader::hasDeprecatedObjectId() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Bootstrap::Builder::hasDeprecatedObjectId() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Bootstrap::Reader::getDeprecatedObjectId() const { + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Bootstrap::Builder::getDeprecatedObjectId() { + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Bootstrap::Builder::initDeprecatedObjectId() { + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint32_t Call::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Call::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Call::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Call::Reader::hasTarget() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Call::Builder::hasTarget() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::MessageTarget::Reader Call::Reader::getTarget() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::MessageTarget::Builder Call::Builder::getTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::rpc::MessageTarget::Pipeline Call::Pipeline::getTarget() { + return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Call::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::MessageTarget::Builder Call::Builder::initTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Call::Builder::adoptTarget( + ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Call::Builder::disownTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Call::Reader::getInterfaceId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Call::Builder::getInterfaceId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Call::Builder::setInterfaceId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Call::Reader::getMethodId() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Call::Builder::getMethodId() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Call::Builder::setMethodId( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Call::Reader::hasParams() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Call::Builder::hasParams() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Payload::Reader Call::Reader::getParams() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Payload::Builder Call::Builder::getParams() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::rpc::Payload::Pipeline Call::Pipeline::getParams() { + return ::capnp::rpc::Payload::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Call::Builder::setParams( ::capnp::rpc::Payload::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Payload::Builder Call::Builder::initParams() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Call::Builder::adoptParams( + ::capnp::Orphan< ::capnp::rpc::Payload>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Payload> Call::Builder::disownParams() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline typename Call::SendResultsTo::Reader Call::Reader::getSendResultsTo() const { + return typename Call::SendResultsTo::Reader(_reader); +} +inline typename Call::SendResultsTo::Builder Call::Builder::getSendResultsTo() { + return typename Call::SendResultsTo::Builder(_builder); +} +#if !CAPNP_LITE +inline typename Call::SendResultsTo::Pipeline Call::Pipeline::getSendResultsTo() { + return typename Call::SendResultsTo::Pipeline(_typeless.noop()); +} +#endif // !CAPNP_LITE +inline typename Call::SendResultsTo::Builder Call::Builder::initSendResultsTo() { + _builder.setDataField< ::uint16_t>(::capnp::bounded<3>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<2>() * ::capnp::POINTERS).clear(); + return typename Call::SendResultsTo::Builder(_builder); +} +inline bool Call::Reader::getAllowThirdPartyTailCall() const { + return _reader.getDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS); +} + +inline bool Call::Builder::getAllowThirdPartyTailCall() { + return _builder.getDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS); +} +inline void Call::Builder::setAllowThirdPartyTailCall(bool value) { + _builder.setDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} + +inline bool Call::SendResultsTo::Reader::isCaller() const { + return which() == Call::SendResultsTo::CALLER; +} +inline bool Call::SendResultsTo::Builder::isCaller() { + return which() == Call::SendResultsTo::CALLER; +} +inline ::capnp::Void Call::SendResultsTo::Reader::getCaller() const { + KJ_IREQUIRE((which() == Call::SendResultsTo::CALLER), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Call::SendResultsTo::Builder::getCaller() { + KJ_IREQUIRE((which() == Call::SendResultsTo::CALLER), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Call::SendResultsTo::Builder::setCaller( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::CALLER); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Call::SendResultsTo::Reader::isYourself() const { + return which() == Call::SendResultsTo::YOURSELF; +} +inline bool Call::SendResultsTo::Builder::isYourself() { + return which() == Call::SendResultsTo::YOURSELF; +} +inline ::capnp::Void Call::SendResultsTo::Reader::getYourself() const { + KJ_IREQUIRE((which() == Call::SendResultsTo::YOURSELF), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Call::SendResultsTo::Builder::getYourself() { + KJ_IREQUIRE((which() == Call::SendResultsTo::YOURSELF), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Call::SendResultsTo::Builder::setYourself( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::YOURSELF); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Call::SendResultsTo::Reader::isThirdParty() const { + return which() == Call::SendResultsTo::THIRD_PARTY; +} +inline bool Call::SendResultsTo::Builder::isThirdParty() { + return which() == Call::SendResultsTo::THIRD_PARTY; +} +inline bool Call::SendResultsTo::Reader::hasThirdParty() const { + if (which() != Call::SendResultsTo::THIRD_PARTY) return false; + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Call::SendResultsTo::Builder::hasThirdParty() { + if (which() != Call::SendResultsTo::THIRD_PARTY) return false; + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Call::SendResultsTo::Reader::getThirdParty() const { + KJ_IREQUIRE((which() == Call::SendResultsTo::THIRD_PARTY), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::getThirdParty() { + KJ_IREQUIRE((which() == Call::SendResultsTo::THIRD_PARTY), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::initThirdParty() { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::THIRD_PARTY); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::capnp::rpc::Return::Which Return::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Return::Which Return::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Return::Reader::getAnswerId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Return::Builder::getAnswerId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Return::Builder::setAnswerId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Return::Reader::getReleaseParamCaps() const { + return _reader.getDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS, true); +} + +inline bool Return::Builder::getReleaseParamCaps() { + return _builder.getDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS, true); +} +inline void Return::Builder::setReleaseParamCaps(bool value) { + _builder.setDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS, value, true); +} + +inline bool Return::Reader::isResults() const { + return which() == Return::RESULTS; +} +inline bool Return::Builder::isResults() { + return which() == Return::RESULTS; +} +inline bool Return::Reader::hasResults() const { + if (which() != Return::RESULTS) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Return::Builder::hasResults() { + if (which() != Return::RESULTS) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Payload::Reader Return::Reader::getResults() const { + KJ_IREQUIRE((which() == Return::RESULTS), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Payload::Builder Return::Builder::getResults() { + KJ_IREQUIRE((which() == Return::RESULTS), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Return::Builder::setResults( ::capnp::rpc::Payload::Reader value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS); + ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Payload::Builder Return::Builder::initResults() { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Return::Builder::adoptResults( + ::capnp::Orphan< ::capnp::rpc::Payload>&& value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS); + ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Payload> Return::Builder::disownResults() { + KJ_IREQUIRE((which() == Return::RESULTS), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Return::Reader::isException() const { + return which() == Return::EXCEPTION; +} +inline bool Return::Builder::isException() { + return which() == Return::EXCEPTION; +} +inline bool Return::Reader::hasException() const { + if (which() != Return::EXCEPTION) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Return::Builder::hasException() { + if (which() != Return::EXCEPTION) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Exception::Reader Return::Reader::getException() const { + KJ_IREQUIRE((which() == Return::EXCEPTION), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Exception::Builder Return::Builder::getException() { + KJ_IREQUIRE((which() == Return::EXCEPTION), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Return::Builder::setException( ::capnp::rpc::Exception::Reader value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Exception::Builder Return::Builder::initException() { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Return::Builder::adoptException( + ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Exception> Return::Builder::disownException() { + KJ_IREQUIRE((which() == Return::EXCEPTION), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Return::Reader::isCanceled() const { + return which() == Return::CANCELED; +} +inline bool Return::Builder::isCanceled() { + return which() == Return::CANCELED; +} +inline ::capnp::Void Return::Reader::getCanceled() const { + KJ_IREQUIRE((which() == Return::CANCELED), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Return::Builder::getCanceled() { + KJ_IREQUIRE((which() == Return::CANCELED), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Return::Builder::setCanceled( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::CANCELED); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Return::Reader::isResultsSentElsewhere() const { + return which() == Return::RESULTS_SENT_ELSEWHERE; +} +inline bool Return::Builder::isResultsSentElsewhere() { + return which() == Return::RESULTS_SENT_ELSEWHERE; +} +inline ::capnp::Void Return::Reader::getResultsSentElsewhere() const { + KJ_IREQUIRE((which() == Return::RESULTS_SENT_ELSEWHERE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Return::Builder::getResultsSentElsewhere() { + KJ_IREQUIRE((which() == Return::RESULTS_SENT_ELSEWHERE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Return::Builder::setResultsSentElsewhere( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS_SENT_ELSEWHERE); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Return::Reader::isTakeFromOtherQuestion() const { + return which() == Return::TAKE_FROM_OTHER_QUESTION; +} +inline bool Return::Builder::isTakeFromOtherQuestion() { + return which() == Return::TAKE_FROM_OTHER_QUESTION; +} +inline ::uint32_t Return::Reader::getTakeFromOtherQuestion() const { + KJ_IREQUIRE((which() == Return::TAKE_FROM_OTHER_QUESTION), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Return::Builder::getTakeFromOtherQuestion() { + KJ_IREQUIRE((which() == Return::TAKE_FROM_OTHER_QUESTION), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Return::Builder::setTakeFromOtherQuestion( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::TAKE_FROM_OTHER_QUESTION); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Return::Reader::isAcceptFromThirdParty() const { + return which() == Return::ACCEPT_FROM_THIRD_PARTY; +} +inline bool Return::Builder::isAcceptFromThirdParty() { + return which() == Return::ACCEPT_FROM_THIRD_PARTY; +} +inline bool Return::Reader::hasAcceptFromThirdParty() const { + if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Return::Builder::hasAcceptFromThirdParty() { + if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Return::Reader::getAcceptFromThirdParty() const { + KJ_IREQUIRE((which() == Return::ACCEPT_FROM_THIRD_PARTY), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Return::Builder::getAcceptFromThirdParty() { + KJ_IREQUIRE((which() == Return::ACCEPT_FROM_THIRD_PARTY), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Return::Builder::initAcceptFromThirdParty() { + _builder.setDataField( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::ACCEPT_FROM_THIRD_PARTY); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint32_t Finish::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Finish::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Finish::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Finish::Reader::getReleaseResultCaps() const { + return _reader.getDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS, true); +} + +inline bool Finish::Builder::getReleaseResultCaps() { + return _builder.getDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS, true); +} +inline void Finish::Builder::setReleaseResultCaps(bool value) { + _builder.setDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS, value, true); +} + +inline ::capnp::rpc::Resolve::Which Resolve::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Resolve::Which Resolve::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Resolve::Reader::getPromiseId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Resolve::Builder::getPromiseId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Resolve::Builder::setPromiseId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Resolve::Reader::isCap() const { + return which() == Resolve::CAP; +} +inline bool Resolve::Builder::isCap() { + return which() == Resolve::CAP; +} +inline bool Resolve::Reader::hasCap() const { + if (which() != Resolve::CAP) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Resolve::Builder::hasCap() { + if (which() != Resolve::CAP) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::CapDescriptor::Reader Resolve::Reader::getCap() const { + KJ_IREQUIRE((which() == Resolve::CAP), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::getCap() { + KJ_IREQUIRE((which() == Resolve::CAP), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Resolve::Builder::setCap( ::capnp::rpc::CapDescriptor::Reader value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP); + ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::initCap() { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP); + return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Resolve::Builder::adoptCap( + ::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP); + ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::CapDescriptor> Resolve::Builder::disownCap() { + KJ_IREQUIRE((which() == Resolve::CAP), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Resolve::Reader::isException() const { + return which() == Resolve::EXCEPTION; +} +inline bool Resolve::Builder::isException() { + return which() == Resolve::EXCEPTION; +} +inline bool Resolve::Reader::hasException() const { + if (which() != Resolve::EXCEPTION) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Resolve::Builder::hasException() { + if (which() != Resolve::EXCEPTION) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Exception::Reader Resolve::Reader::getException() const { + KJ_IREQUIRE((which() == Resolve::EXCEPTION), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Exception::Builder Resolve::Builder::getException() { + KJ_IREQUIRE((which() == Resolve::EXCEPTION), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Resolve::Builder::setException( ::capnp::rpc::Exception::Reader value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Exception::Builder Resolve::Builder::initException() { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Resolve::Builder::adoptException( + ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Exception> Resolve::Builder::disownException() { + KJ_IREQUIRE((which() == Resolve::EXCEPTION), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint32_t Release::Reader::getId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Release::Builder::getId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Release::Builder::setId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Release::Reader::getReferenceCount() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Release::Builder::getReferenceCount() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Release::Builder::setReferenceCount( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Disembargo::Reader::hasTarget() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Disembargo::Builder::hasTarget() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::MessageTarget::Reader Disembargo::Reader::getTarget() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::getTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::rpc::MessageTarget::Pipeline Disembargo::Pipeline::getTarget() { + return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Disembargo::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::initTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Disembargo::Builder::adoptTarget( + ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Disembargo::Builder::disownTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline typename Disembargo::Context::Reader Disembargo::Reader::getContext() const { + return typename Disembargo::Context::Reader(_reader); +} +inline typename Disembargo::Context::Builder Disembargo::Builder::getContext() { + return typename Disembargo::Context::Builder(_builder); +} +#if !CAPNP_LITE +inline typename Disembargo::Context::Pipeline Disembargo::Pipeline::getContext() { + return typename Disembargo::Context::Pipeline(_typeless.noop()); +} +#endif // !CAPNP_LITE +inline typename Disembargo::Context::Builder Disembargo::Builder::initContext() { + _builder.setDataField< ::uint32_t>(::capnp::bounded<0>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename Disembargo::Context::Builder(_builder); +} +inline ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline bool Disembargo::Context::Reader::isSenderLoopback() const { + return which() == Disembargo::Context::SENDER_LOOPBACK; +} +inline bool Disembargo::Context::Builder::isSenderLoopback() { + return which() == Disembargo::Context::SENDER_LOOPBACK; +} +inline ::uint32_t Disembargo::Context::Reader::getSenderLoopback() const { + KJ_IREQUIRE((which() == Disembargo::Context::SENDER_LOOPBACK), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Disembargo::Context::Builder::getSenderLoopback() { + KJ_IREQUIRE((which() == Disembargo::Context::SENDER_LOOPBACK), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Disembargo::Context::Builder::setSenderLoopback( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::SENDER_LOOPBACK); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Disembargo::Context::Reader::isReceiverLoopback() const { + return which() == Disembargo::Context::RECEIVER_LOOPBACK; +} +inline bool Disembargo::Context::Builder::isReceiverLoopback() { + return which() == Disembargo::Context::RECEIVER_LOOPBACK; +} +inline ::uint32_t Disembargo::Context::Reader::getReceiverLoopback() const { + KJ_IREQUIRE((which() == Disembargo::Context::RECEIVER_LOOPBACK), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Disembargo::Context::Builder::getReceiverLoopback() { + KJ_IREQUIRE((which() == Disembargo::Context::RECEIVER_LOOPBACK), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Disembargo::Context::Builder::setReceiverLoopback( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::RECEIVER_LOOPBACK); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Disembargo::Context::Reader::isAccept() const { + return which() == Disembargo::Context::ACCEPT; +} +inline bool Disembargo::Context::Builder::isAccept() { + return which() == Disembargo::Context::ACCEPT; +} +inline ::capnp::Void Disembargo::Context::Reader::getAccept() const { + KJ_IREQUIRE((which() == Disembargo::Context::ACCEPT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Disembargo::Context::Builder::getAccept() { + KJ_IREQUIRE((which() == Disembargo::Context::ACCEPT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Disembargo::Context::Builder::setAccept( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::ACCEPT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Disembargo::Context::Reader::isProvide() const { + return which() == Disembargo::Context::PROVIDE; +} +inline bool Disembargo::Context::Builder::isProvide() { + return which() == Disembargo::Context::PROVIDE; +} +inline ::uint32_t Disembargo::Context::Reader::getProvide() const { + KJ_IREQUIRE((which() == Disembargo::Context::PROVIDE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Disembargo::Context::Builder::getProvide() { + KJ_IREQUIRE((which() == Disembargo::Context::PROVIDE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Disembargo::Context::Builder::setProvide( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::PROVIDE); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Provide::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Provide::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Provide::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Provide::Reader::hasTarget() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Provide::Builder::hasTarget() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::MessageTarget::Reader Provide::Reader::getTarget() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::MessageTarget::Builder Provide::Builder::getTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::rpc::MessageTarget::Pipeline Provide::Pipeline::getTarget() { + return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Provide::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::MessageTarget::Builder Provide::Builder::initTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Provide::Builder::adoptTarget( + ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Provide::Builder::disownTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Provide::Reader::hasRecipient() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Provide::Builder::hasRecipient() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Provide::Reader::getRecipient() const { + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Provide::Builder::getRecipient() { + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Provide::Builder::initRecipient() { + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint32_t Accept::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Accept::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Accept::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Accept::Reader::hasProvision() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Accept::Builder::hasProvision() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Accept::Reader::getProvision() const { + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Accept::Builder::getProvision() { + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Accept::Builder::initProvision() { + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Accept::Reader::getEmbargo() const { + return _reader.getDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS); +} + +inline bool Accept::Builder::getEmbargo() { + return _builder.getDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS); +} +inline void Accept::Builder::setEmbargo(bool value) { + _builder.setDataField( + ::capnp::bounded<32>() * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Join::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Join::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Join::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Join::Reader::hasTarget() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Join::Builder::hasTarget() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::MessageTarget::Reader Join::Reader::getTarget() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::MessageTarget::Builder Join::Builder::getTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::rpc::MessageTarget::Pipeline Join::Pipeline::getTarget() { + return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Join::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::MessageTarget::Builder Join::Builder::initTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Join::Builder::adoptTarget( + ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Join::Builder::disownTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Join::Reader::hasKeyPart() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Join::Builder::hasKeyPart() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Join::Reader::getKeyPart() const { + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Join::Builder::getKeyPart() { + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Join::Builder::initKeyPart() { + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::capnp::rpc::MessageTarget::Which MessageTarget::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::MessageTarget::Which MessageTarget::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline bool MessageTarget::Reader::isImportedCap() const { + return which() == MessageTarget::IMPORTED_CAP; +} +inline bool MessageTarget::Builder::isImportedCap() { + return which() == MessageTarget::IMPORTED_CAP; +} +inline ::uint32_t MessageTarget::Reader::getImportedCap() const { + KJ_IREQUIRE((which() == MessageTarget::IMPORTED_CAP), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t MessageTarget::Builder::getImportedCap() { + KJ_IREQUIRE((which() == MessageTarget::IMPORTED_CAP), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void MessageTarget::Builder::setImportedCap( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::IMPORTED_CAP); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool MessageTarget::Reader::isPromisedAnswer() const { + return which() == MessageTarget::PROMISED_ANSWER; +} +inline bool MessageTarget::Builder::isPromisedAnswer() { + return which() == MessageTarget::PROMISED_ANSWER; +} +inline bool MessageTarget::Reader::hasPromisedAnswer() const { + if (which() != MessageTarget::PROMISED_ANSWER) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool MessageTarget::Builder::hasPromisedAnswer() { + if (which() != MessageTarget::PROMISED_ANSWER) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::PromisedAnswer::Reader MessageTarget::Reader::getPromisedAnswer() const { + KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::getPromisedAnswer() { + KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void MessageTarget::Builder::setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); + ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::initPromisedAnswer() { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void MessageTarget::Builder::adoptPromisedAnswer( + ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); + ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> MessageTarget::Builder::disownPromisedAnswer() { + KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Payload::Reader::hasContent() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Payload::Builder::hasContent() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Payload::Reader::getContent() const { + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Payload::Builder::getContent() { + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Payload::Builder::initContent() { + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Payload::Reader::hasCapTable() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Payload::Builder::hasCapTable() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader Payload::Reader::getCapTable() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder Payload::Builder::getCapTable() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Payload::Builder::setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder Payload::Builder::initCapTable(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Payload::Builder::adoptCapTable( + ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>> Payload::Builder::disownCapTable() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::capnp::rpc::CapDescriptor::Which CapDescriptor::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::CapDescriptor::Which CapDescriptor::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool CapDescriptor::Reader::isNone() const { + return which() == CapDescriptor::NONE; +} +inline bool CapDescriptor::Builder::isNone() { + return which() == CapDescriptor::NONE; +} +inline ::capnp::Void CapDescriptor::Reader::getNone() const { + KJ_IREQUIRE((which() == CapDescriptor::NONE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void CapDescriptor::Builder::getNone() { + KJ_IREQUIRE((which() == CapDescriptor::NONE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CapDescriptor::Builder::setNone( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::NONE); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CapDescriptor::Reader::isSenderHosted() const { + return which() == CapDescriptor::SENDER_HOSTED; +} +inline bool CapDescriptor::Builder::isSenderHosted() { + return which() == CapDescriptor::SENDER_HOSTED; +} +inline ::uint32_t CapDescriptor::Reader::getSenderHosted() const { + KJ_IREQUIRE((which() == CapDescriptor::SENDER_HOSTED), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t CapDescriptor::Builder::getSenderHosted() { + KJ_IREQUIRE((which() == CapDescriptor::SENDER_HOSTED), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void CapDescriptor::Builder::setSenderHosted( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::SENDER_HOSTED); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool CapDescriptor::Reader::isSenderPromise() const { + return which() == CapDescriptor::SENDER_PROMISE; +} +inline bool CapDescriptor::Builder::isSenderPromise() { + return which() == CapDescriptor::SENDER_PROMISE; +} +inline ::uint32_t CapDescriptor::Reader::getSenderPromise() const { + KJ_IREQUIRE((which() == CapDescriptor::SENDER_PROMISE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t CapDescriptor::Builder::getSenderPromise() { + KJ_IREQUIRE((which() == CapDescriptor::SENDER_PROMISE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void CapDescriptor::Builder::setSenderPromise( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::SENDER_PROMISE); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool CapDescriptor::Reader::isReceiverHosted() const { + return which() == CapDescriptor::RECEIVER_HOSTED; +} +inline bool CapDescriptor::Builder::isReceiverHosted() { + return which() == CapDescriptor::RECEIVER_HOSTED; +} +inline ::uint32_t CapDescriptor::Reader::getReceiverHosted() const { + KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_HOSTED), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t CapDescriptor::Builder::getReceiverHosted() { + KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_HOSTED), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void CapDescriptor::Builder::setReceiverHosted( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_HOSTED); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool CapDescriptor::Reader::isReceiverAnswer() const { + return which() == CapDescriptor::RECEIVER_ANSWER; +} +inline bool CapDescriptor::Builder::isReceiverAnswer() { + return which() == CapDescriptor::RECEIVER_ANSWER; +} +inline bool CapDescriptor::Reader::hasReceiverAnswer() const { + if (which() != CapDescriptor::RECEIVER_ANSWER) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CapDescriptor::Builder::hasReceiverAnswer() { + if (which() != CapDescriptor::RECEIVER_ANSWER) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::PromisedAnswer::Reader CapDescriptor::Reader::getReceiverAnswer() const { + KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::getReceiverAnswer() { + KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CapDescriptor::Builder::setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); + ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::initReceiverAnswer() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CapDescriptor::Builder::adoptReceiverAnswer( + ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); + ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> CapDescriptor::Builder::disownReceiverAnswer() { + KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool CapDescriptor::Reader::isThirdPartyHosted() const { + return which() == CapDescriptor::THIRD_PARTY_HOSTED; +} +inline bool CapDescriptor::Builder::isThirdPartyHosted() { + return which() == CapDescriptor::THIRD_PARTY_HOSTED; +} +inline bool CapDescriptor::Reader::hasThirdPartyHosted() const { + if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CapDescriptor::Builder::hasThirdPartyHosted() { + if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::ThirdPartyCapDescriptor::Reader CapDescriptor::Reader::getThirdPartyHosted() const { + KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::getThirdPartyHosted() { + KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CapDescriptor::Builder::setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); + ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::initThirdPartyHosted() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); + return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CapDescriptor::Builder::adoptThirdPartyHosted( + ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); + ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor> CapDescriptor::Builder::disownThirdPartyHosted() { + KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint32_t PromisedAnswer::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t PromisedAnswer::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void PromisedAnswer::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool PromisedAnswer::Reader::hasTransform() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool PromisedAnswer::Builder::hasTransform() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader PromisedAnswer::Reader::getTransform() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder PromisedAnswer::Builder::getTransform() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void PromisedAnswer::Builder::setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder PromisedAnswer::Builder::initTransform(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void PromisedAnswer::Builder::adoptTransform( + ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>> PromisedAnswer::Builder::disownTransform() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool PromisedAnswer::Op::Reader::isNoop() const { + return which() == PromisedAnswer::Op::NOOP; +} +inline bool PromisedAnswer::Op::Builder::isNoop() { + return which() == PromisedAnswer::Op::NOOP; +} +inline ::capnp::Void PromisedAnswer::Op::Reader::getNoop() const { + KJ_IREQUIRE((which() == PromisedAnswer::Op::NOOP), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void PromisedAnswer::Op::Builder::getNoop() { + KJ_IREQUIRE((which() == PromisedAnswer::Op::NOOP), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void PromisedAnswer::Op::Builder::setNoop( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, PromisedAnswer::Op::NOOP); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool PromisedAnswer::Op::Reader::isGetPointerField() const { + return which() == PromisedAnswer::Op::GET_POINTER_FIELD; +} +inline bool PromisedAnswer::Op::Builder::isGetPointerField() { + return which() == PromisedAnswer::Op::GET_POINTER_FIELD; +} +inline ::uint16_t PromisedAnswer::Op::Reader::getGetPointerField() const { + KJ_IREQUIRE((which() == PromisedAnswer::Op::GET_POINTER_FIELD), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t PromisedAnswer::Op::Builder::getGetPointerField() { + KJ_IREQUIRE((which() == PromisedAnswer::Op::GET_POINTER_FIELD), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void PromisedAnswer::Op::Builder::setGetPointerField( ::uint16_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, PromisedAnswer::Op::GET_POINTER_FIELD); + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool ThirdPartyCapDescriptor::Reader::hasId() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool ThirdPartyCapDescriptor::Builder::hasId() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader ThirdPartyCapDescriptor::Reader::getId() const { + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::getId() { + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::initId() { + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint32_t ThirdPartyCapDescriptor::Reader::getVineId() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t ThirdPartyCapDescriptor::Builder::getVineId() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void ThirdPartyCapDescriptor::Builder::setVineId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Exception::Reader::hasReason() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Exception::Builder::hasReason() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Exception::Reader::getReason() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Exception::Builder::getReason() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Exception::Builder::setReason( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Exception::Builder::initReason(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Exception::Builder::adoptReason( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Exception::Builder::disownReason() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Exception::Reader::getObsoleteIsCallersFault() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Exception::Builder::getObsoleteIsCallersFault() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Exception::Builder::setObsoleteIsCallersFault(bool value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Exception::Reader::getObsoleteDurability() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Exception::Builder::getObsoleteDurability() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Exception::Builder::setObsoleteDurability( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::rpc::Exception::Type Exception::Reader::getType() const { + return _reader.getDataField< ::capnp::rpc::Exception::Type>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::capnp::rpc::Exception::Type Exception::Builder::getType() { + return _builder.getDataField< ::capnp::rpc::Exception::Type>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Exception::Builder::setType( ::capnp::rpc::Exception::Type value) { + _builder.setDataField< ::capnp::rpc::Exception::Type>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +} // namespace +} // namespace + +#endif // CAPNP_INCLUDED_b312981b2552a250_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/rpc.h --- a/win32-mingw/include/capnp/rpc.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/rpc.h Tue May 23 09:16:54 2017 +0100 @@ -1,537 +1,537 @@ -// 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. - -#ifndef CAPNP_RPC_H_ -#define CAPNP_RPC_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "capability.h" -#include "rpc-prelude.h" - -namespace capnp { - -template -class VatNetwork; -template -class SturdyRefRestorer; - -template -class BootstrapFactory: public _::BootstrapFactoryBase { - // Interface that constructs per-client bootstrap interfaces. Use this if you want each client - // who connects to see a different bootstrap interface based on their (authenticated) VatId. - // This allows an application to bootstrap off of the authentication performed at the VatNetwork - // level. (Typically VatId is some sort of public key.) - // - // This is only useful for multi-party networks. For TwoPartyVatNetwork, there's no reason to - // use a BootstrapFactory; just specify a single bootstrap capability in this case. - -public: - virtual Capability::Client createFor(typename VatId::Reader clientId) = 0; - // Create a bootstrap capability appropriate for exposing to the given client. VatNetwork will - // have authenticated the client VatId before this is called. - -private: - Capability::Client baseCreateFor(AnyStruct::Reader clientId) override; -}; - -template -class RpcSystem: public _::RpcSystemBase { - // Represents the RPC system, which is the portal to objects available on the network. - // - // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork` - // determines how to form connections between vats -- specifically, two-way, private, reliable, - // sequenced datagram connections. The RPC implementation determines how to use such connections - // to manage object references and make method calls. - // - // See `makeRpcServer()` and `makeRpcClient()` below for convenient syntax for setting up an - // `RpcSystem` given a `VatNetwork`. - // - // See `ez-rpc.h` for an even simpler interface for setting up RPC in a typical two-party - // client/server scenario. - -public: - template - RpcSystem( - VatNetwork& network, - kj::Maybe bootstrapInterface, - kj::Maybe::Client> gateway = nullptr); - - template - RpcSystem( - VatNetwork& network, - BootstrapFactory& bootstrapFactory, - kj::Maybe::Client> gateway = nullptr); - - template - RpcSystem( - VatNetwork& network, - SturdyRefRestorer& restorer); - - RpcSystem(RpcSystem&& other) = default; - - Capability::Client bootstrap(typename VatId::Reader vatId); - // Connect to the given vat and return its bootstrap interface. - - Capability::Client restore(typename VatId::Reader hostId, AnyPointer::Reader objectId) - KJ_DEPRECATED("Please transition to using a bootstrap interface instead."); - // ** DEPRECATED ** - // - // Restores the given SturdyRef from the network and return the capability representing it. - // - // `hostId` identifies the host from which to request the ref, in the format specified by the - // `VatNetwork` in use. `objectId` is the object ID in whatever format is expected by said host. - // - // This method will be removed in a future version of Cap'n Proto. Instead, please transition - // to using bootstrap(), which is equivalent to calling restore() with a null `objectId`. - // You may emulate the old concept of object IDs by exporting a bootstrap interface which has - // methods that can be used to obtain other capabilities by ID. - - void setFlowLimit(size_t words); - // Sets the incoming call flow limit. If more than `words` worth of call messages have not yet - // received responses, the RpcSystem will not read further messages from the stream. This can be - // used as a crude way to prevent a resource exhaustion attack (or bug) in which a peer makes an - // excessive number of simultaneous calls that consume the receiver's RAM. - // - // There are some caveats. When over the flow limit, all messages are blocked, including returns. - // If the outstanding calls are themselves waiting on calls going in the opposite direction, the - // flow limit may prevent those calls from completing, leading to deadlock. However, a - // sufficiently high limit should make this unlikely. - // - // Note that a call's parameter size counts against the flow limit until the call returns, even - // if the recipient calls releaseParams() to free the parameter memory early. This is because - // releaseParams() may simply indicate that the parameters have been forwarded to another - // machine, but are still in-memory there. For illustration, say that Alice made a call to Bob - // who forwarded the call to Carol. Bob has imposed a flow limit on Alice. Alice's calls are - // being forwarded to Carol, so Bob never keeps the parameters in-memory for more than a brief - // period. However, the flow limit counts all calls that haven't returned, even if Bob has - // already freed the memory they consumed. You might argue that the right solution here is - // instead for Carol to impose her own flow limit on Bob. This has a serious problem, though: - // Bob might be forwarding requests to Carol on behalf of many different parties, not just Alice. - // If Alice can pump enough data to hit the Bob -> Carol flow limit, then those other parties - // will be disrupted. Thus, we can only really impose the limit on the Alice -> Bob link, which - // only affects Alice. We need that one flow limit to limit Alice's impact on the whole system, - // so it has to count all in-flight calls. - // - // In Sandstorm, flow limits are imposed by the supervisor on calls coming out of a grain, in - // order to prevent a grain from inundating the system with in-flight calls. In practice, the - // main time this happens is when a grain is pushing a large file download and doesn't implement - // proper cooperative flow control. -}; - -template -RpcSystem makeRpcServer( - VatNetwork& network, - Capability::Client bootstrapInterface); -// Make an RPC server. Typical usage (e.g. in a main() function): -// -// MyEventLoop eventLoop; -// kj::WaitScope waitScope(eventLoop); -// MyNetwork network; -// MyMainInterface::Client bootstrap = makeMain(); -// auto server = makeRpcServer(network, bootstrap); -// kj::NEVER_DONE.wait(waitScope); // run forever -// -// See also ez-rpc.h, which has simpler instructions for the common case of a two-party -// client-server RPC connection. - -template , - typename ExternalRef = _::ExternalRefFromRealmGatewayClient> -RpcSystem makeRpcServer( - VatNetwork& network, - Capability::Client bootstrapInterface, RealmGatewayClient gateway); -// Make an RPC server for a VatNetwork that resides in a different realm from the application. -// The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format -// and the network's ("external") format. - -template -RpcSystem makeRpcServer( - VatNetwork& network, - BootstrapFactory& bootstrapFactory); -// Make an RPC server that can serve different bootstrap interfaces to different clients via a -// BootstrapInterface. - -template , - typename ExternalRef = _::ExternalRefFromRealmGatewayClient> -RpcSystem makeRpcServer( - VatNetwork& network, - BootstrapFactory& bootstrapFactory, RealmGatewayClient gateway); -// Make an RPC server that can serve different bootstrap interfaces to different clients via a -// BootstrapInterface and communicates with a different realm than the application is in via a -// RealmGateway. - -template -RpcSystem makeRpcServer( - VatNetwork& network, - SturdyRefRestorer& restorer) - KJ_DEPRECATED("Please transition to using a bootstrap interface instead."); -// ** DEPRECATED ** -// -// Create an RPC server which exports multiple main interfaces by object ID. The `restorer` object -// can be used to look up objects by ID. -// -// Please transition to exporting only one interface, which is known as the "bootstrap" interface. -// For backwards-compatibility with old clients, continue to implement SturdyRefRestorer, but -// return the new bootstrap interface when the request object ID is null. When new clients connect -// and request the bootstrap interface, they will get that interface. Eventually, once all clients -// are updated to request only the bootstrap interface, stop implementing SturdyRefRestorer and -// switch to passing the bootstrap capability itself as the second parameter to `makeRpcServer()`. - -template -RpcSystem makeRpcClient( - VatNetwork& network); -// Make an RPC client. Typical usage (e.g. in a main() function): -// -// MyEventLoop eventLoop; -// kj::WaitScope waitScope(eventLoop); -// MyNetwork network; -// auto client = makeRpcClient(network); -// MyCapability::Client cap = client.restore(hostId, objId).castAs(); -// auto response = cap.fooRequest().send().wait(waitScope); -// handleMyResponse(response); -// -// See also ez-rpc.h, which has simpler instructions for the common case of a two-party -// client-server RPC connection. - -template , - typename ExternalRef = _::ExternalRefFromRealmGatewayClient> -RpcSystem makeRpcClient( - VatNetwork& network, - RealmGatewayClient gateway); -// Make an RPC client for a VatNetwork that resides in a different realm from the application. -// The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format -// and the network's ("external") format. - -template -class SturdyRefRestorer: public _::SturdyRefRestorerBase { - // ** DEPRECATED ** - // - // In Cap'n Proto 0.4.x, applications could export multiple main interfaces identified by - // object IDs. The callback used to map object IDs to objects was `SturdyRefRestorer`, as we - // imagined this would eventually be used for restoring SturdyRefs as well. In practice, it was - // never used for real SturdyRefs, only for exporting singleton objects under well-known names. - // - // The new preferred strategy is to export only a _single_ such interface, called the - // "bootstrap interface". That interface can itself have methods for obtaining other objects, of - // course, but that is up to the app. `SturdyRefRestorer` exists for backwards-compatibility. - // - // Hint: Use SturdyRefRestorer to define a server that exports services under - // string names. - -public: - virtual Capability::Client restore(typename SturdyRefObjectId::Reader ref) - KJ_DEPRECATED( - "Please transition to using bootstrap interfaces instead of SturdyRefRestorer.") = 0; - // Restore the given object, returning a capability representing it. - -private: - Capability::Client baseRestore(AnyPointer::Reader ref) override final; -}; - -// ======================================================================================= -// VatNetwork - -class OutgoingRpcMessage { - // A message to be sent by a `VatNetwork`. - -public: - virtual AnyPointer::Builder getBody() = 0; - // Get the message body, which the caller may fill in any way it wants. (The standard RPC - // implementation initializes it as a Message as defined in rpc.capnp.) - - virtual void send() = 0; - // Send the message, or at least put it in a queue to be sent later. Note that the builder - // returned by `getBody()` remains valid at least until the `OutgoingRpcMessage` is destroyed. -}; - -class IncomingRpcMessage { - // A message received from a `VatNetwork`. - -public: - virtual AnyPointer::Reader getBody() = 0; - // Get the message body, to be interpreted by the caller. (The standard RPC implementation - // interprets it as a Message as defined in rpc.capnp.) -}; - -template -class VatNetwork: public _::VatNetworkBase { - // Cap'n Proto RPC operates between vats, where a "vat" is some sort of host of objects. - // Typically one Cap'n Proto process (in the Unix sense) is one vat. The RPC system is what - // allows calls between objects hosted in different vats. - // - // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork` - // determines how to form connections between vats -- specifically, two-way, private, reliable, - // sequenced datagram connections. The RPC implementation determines how to use such connections - // to manage object references and make method calls. - // - // The most common implementation of VatNetwork is TwoPartyVatNetwork (rpc-twoparty.h). Most - // simple client-server apps will want to use it. (You may even want to use the EZ RPC - // interfaces in `ez-rpc.h` and avoid all of this.) - // - // TODO(someday): Provide a standard implementation for the public internet. - -public: - class Connection; - - struct ConnectionAndProvisionId { - // Result of connecting to a vat introduced by another vat. - - kj::Own connection; - // Connection to the new vat. - - kj::Own firstMessage; - // An already-allocated `OutgoingRpcMessage` associated with `connection`. The RPC system will - // construct this as an `Accept` message and send it. - - Orphan provisionId; - // A `ProvisionId` already allocated inside `firstMessage`, which the RPC system will use to - // build the `Accept` message. - }; - - class Connection: public _::VatNetworkBase::Connection { - // A two-way RPC connection. - // - // This object may represent a connection that doesn't exist yet, but is expected to exist - // in the future. In this case, sent messages will automatically be queued and sent once the - // connection is ready, so that the caller doesn't need to know the difference. - - public: - // Level 0 features ---------------------------------------------- - - virtual typename VatId::Reader getPeerVatId() = 0; - // Returns the connected vat's authenticated VatId. It is the VatNetwork's responsibility to - // authenticate this, so that the caller can be assured that they are really talking to the - // identified vat and not an imposter. - - virtual kj::Own newOutgoingMessage(uint firstSegmentWordSize) override = 0; - // Allocate a new message to be sent on this connection. - // - // If `firstSegmentWordSize` is non-zero, it should be treated as a hint suggesting how large - // to make the first segment. This is entirely a hint and the connection may adjust it up or - // down. If it is zero, the connection should choose the size itself. - - virtual kj::Promise>> receiveIncomingMessage() override = 0; - // Wait for a message to be received and return it. If the read stream cleanly terminates, - // return null. If any other problem occurs, throw an exception. - - virtual kj::Promise shutdown() override KJ_WARN_UNUSED_RESULT = 0; - // Waits until all outgoing messages have been sent, then shuts down the outgoing stream. The - // returned promise resolves after shutdown is complete. - - private: - AnyStruct::Reader baseGetPeerVatId() override; - }; - - // Level 0 features ------------------------------------------------ - - virtual kj::Maybe> connect(typename VatId::Reader hostId) = 0; - // Connect to a VatId. Note that this method immediately returns a `Connection`, even - // if the network connection has not yet been established. Messages can be queued to this - // connection and will be delivered once it is open. The caller must attempt to read from the - // connection to verify that it actually succeeded; the read will fail if the connection - // couldn't be opened. Some network implementations may actually start sending messages before - // hearing back from the server at all, to avoid a round trip. - // - // Returns nullptr if `hostId` refers to the local host. - - virtual kj::Promise> accept() = 0; - // Wait for the next incoming connection and return it. - - // Level 4 features ------------------------------------------------ - // TODO(someday) - -private: - kj::Maybe> - baseConnect(AnyStruct::Reader hostId) override final; - kj::Promise> baseAccept() override final; -}; - -// ======================================================================================= -// *************************************************************************************** -// Inline implementation details start here -// *************************************************************************************** -// ======================================================================================= - -template -Capability::Client BootstrapFactory::baseCreateFor(AnyStruct::Reader clientId) { - return createFor(clientId.as()); -} - -template -kj::Maybe> - VatNetwork:: - baseConnect(AnyStruct::Reader ref) { - auto maybe = connect(ref.as()); - return maybe.map([](kj::Own& conn) -> kj::Own<_::VatNetworkBase::Connection> { - return kj::mv(conn); - }); -} - -template -kj::Promise> - VatNetwork::baseAccept() { - return accept().then( - [](kj::Own&& connection) -> kj::Own<_::VatNetworkBase::Connection> { - return kj::mv(connection); - }); -} - -template -AnyStruct::Reader VatNetwork< - SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>:: - Connection::baseGetPeerVatId() { - return getPeerVatId(); -} - -template -Capability::Client SturdyRefRestorer::baseRestore(AnyPointer::Reader ref) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - return restore(ref.getAs()); -#pragma GCC diagnostic pop -} - -template -template -RpcSystem::RpcSystem( - VatNetwork& network, - kj::Maybe bootstrap, - kj::Maybe::Client> gateway) - : _::RpcSystemBase(network, kj::mv(bootstrap), kj::mv(gateway)) {} - -template -template -RpcSystem::RpcSystem( - VatNetwork& network, - BootstrapFactory& bootstrapFactory, - kj::Maybe::Client> gateway) - : _::RpcSystemBase(network, bootstrapFactory, kj::mv(gateway)) {} - -template -template -RpcSystem::RpcSystem( - VatNetwork& network, - SturdyRefRestorer& restorer) - : _::RpcSystemBase(network, restorer) {} - -template -Capability::Client RpcSystem::bootstrap(typename VatId::Reader vatId) { - return baseBootstrap(_::PointerHelpers::getInternalReader(vatId)); -} - -template -Capability::Client RpcSystem::restore( - typename VatId::Reader hostId, AnyPointer::Reader objectId) { - return baseRestore(_::PointerHelpers::getInternalReader(hostId), objectId); -} - -template -inline void RpcSystem::setFlowLimit(size_t words) { - baseSetFlowLimit(words); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - Capability::Client bootstrapInterface) { - return RpcSystem(network, kj::mv(bootstrapInterface)); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - Capability::Client bootstrapInterface, RealmGatewayClient gateway) { - return RpcSystem(network, kj::mv(bootstrapInterface), - gateway.template castAs>()); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - BootstrapFactory& bootstrapFactory) { - return RpcSystem(network, bootstrapFactory); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - BootstrapFactory& bootstrapFactory, RealmGatewayClient gateway) { - return RpcSystem(network, bootstrapFactory, gateway.template castAs>()); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - SturdyRefRestorer& restorer) { - return RpcSystem(network, restorer); -} - -template -RpcSystem makeRpcClient( - VatNetwork& network) { - return RpcSystem(network, nullptr); -} - -template -RpcSystem makeRpcClient( - VatNetwork& network, - RealmGatewayClient gateway) { - return RpcSystem(network, nullptr, gateway.template castAs>()); -} - -} // namespace capnp - -#endif // CAPNP_RPC_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. + +#ifndef CAPNP_RPC_H_ +#define CAPNP_RPC_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "capability.h" +#include "rpc-prelude.h" + +namespace capnp { + +template +class VatNetwork; +template +class SturdyRefRestorer; + +template +class BootstrapFactory: public _::BootstrapFactoryBase { + // Interface that constructs per-client bootstrap interfaces. Use this if you want each client + // who connects to see a different bootstrap interface based on their (authenticated) VatId. + // This allows an application to bootstrap off of the authentication performed at the VatNetwork + // level. (Typically VatId is some sort of public key.) + // + // This is only useful for multi-party networks. For TwoPartyVatNetwork, there's no reason to + // use a BootstrapFactory; just specify a single bootstrap capability in this case. + +public: + virtual Capability::Client createFor(typename VatId::Reader clientId) = 0; + // Create a bootstrap capability appropriate for exposing to the given client. VatNetwork will + // have authenticated the client VatId before this is called. + +private: + Capability::Client baseCreateFor(AnyStruct::Reader clientId) override; +}; + +template +class RpcSystem: public _::RpcSystemBase { + // Represents the RPC system, which is the portal to objects available on the network. + // + // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork` + // determines how to form connections between vats -- specifically, two-way, private, reliable, + // sequenced datagram connections. The RPC implementation determines how to use such connections + // to manage object references and make method calls. + // + // See `makeRpcServer()` and `makeRpcClient()` below for convenient syntax for setting up an + // `RpcSystem` given a `VatNetwork`. + // + // See `ez-rpc.h` for an even simpler interface for setting up RPC in a typical two-party + // client/server scenario. + +public: + template + RpcSystem( + VatNetwork& network, + kj::Maybe bootstrapInterface, + kj::Maybe::Client> gateway = nullptr); + + template + RpcSystem( + VatNetwork& network, + BootstrapFactory& bootstrapFactory, + kj::Maybe::Client> gateway = nullptr); + + template + RpcSystem( + VatNetwork& network, + SturdyRefRestorer& restorer); + + RpcSystem(RpcSystem&& other) = default; + + Capability::Client bootstrap(typename VatId::Reader vatId); + // Connect to the given vat and return its bootstrap interface. + + Capability::Client restore(typename VatId::Reader hostId, AnyPointer::Reader objectId) + KJ_DEPRECATED("Please transition to using a bootstrap interface instead."); + // ** DEPRECATED ** + // + // Restores the given SturdyRef from the network and return the capability representing it. + // + // `hostId` identifies the host from which to request the ref, in the format specified by the + // `VatNetwork` in use. `objectId` is the object ID in whatever format is expected by said host. + // + // This method will be removed in a future version of Cap'n Proto. Instead, please transition + // to using bootstrap(), which is equivalent to calling restore() with a null `objectId`. + // You may emulate the old concept of object IDs by exporting a bootstrap interface which has + // methods that can be used to obtain other capabilities by ID. + + void setFlowLimit(size_t words); + // Sets the incoming call flow limit. If more than `words` worth of call messages have not yet + // received responses, the RpcSystem will not read further messages from the stream. This can be + // used as a crude way to prevent a resource exhaustion attack (or bug) in which a peer makes an + // excessive number of simultaneous calls that consume the receiver's RAM. + // + // There are some caveats. When over the flow limit, all messages are blocked, including returns. + // If the outstanding calls are themselves waiting on calls going in the opposite direction, the + // flow limit may prevent those calls from completing, leading to deadlock. However, a + // sufficiently high limit should make this unlikely. + // + // Note that a call's parameter size counts against the flow limit until the call returns, even + // if the recipient calls releaseParams() to free the parameter memory early. This is because + // releaseParams() may simply indicate that the parameters have been forwarded to another + // machine, but are still in-memory there. For illustration, say that Alice made a call to Bob + // who forwarded the call to Carol. Bob has imposed a flow limit on Alice. Alice's calls are + // being forwarded to Carol, so Bob never keeps the parameters in-memory for more than a brief + // period. However, the flow limit counts all calls that haven't returned, even if Bob has + // already freed the memory they consumed. You might argue that the right solution here is + // instead for Carol to impose her own flow limit on Bob. This has a serious problem, though: + // Bob might be forwarding requests to Carol on behalf of many different parties, not just Alice. + // If Alice can pump enough data to hit the Bob -> Carol flow limit, then those other parties + // will be disrupted. Thus, we can only really impose the limit on the Alice -> Bob link, which + // only affects Alice. We need that one flow limit to limit Alice's impact on the whole system, + // so it has to count all in-flight calls. + // + // In Sandstorm, flow limits are imposed by the supervisor on calls coming out of a grain, in + // order to prevent a grain from inundating the system with in-flight calls. In practice, the + // main time this happens is when a grain is pushing a large file download and doesn't implement + // proper cooperative flow control. +}; + +template +RpcSystem makeRpcServer( + VatNetwork& network, + Capability::Client bootstrapInterface); +// Make an RPC server. Typical usage (e.g. in a main() function): +// +// MyEventLoop eventLoop; +// kj::WaitScope waitScope(eventLoop); +// MyNetwork network; +// MyMainInterface::Client bootstrap = makeMain(); +// auto server = makeRpcServer(network, bootstrap); +// kj::NEVER_DONE.wait(waitScope); // run forever +// +// See also ez-rpc.h, which has simpler instructions for the common case of a two-party +// client-server RPC connection. + +template , + typename ExternalRef = _::ExternalRefFromRealmGatewayClient> +RpcSystem makeRpcServer( + VatNetwork& network, + Capability::Client bootstrapInterface, RealmGatewayClient gateway); +// Make an RPC server for a VatNetwork that resides in a different realm from the application. +// The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format +// and the network's ("external") format. + +template +RpcSystem makeRpcServer( + VatNetwork& network, + BootstrapFactory& bootstrapFactory); +// Make an RPC server that can serve different bootstrap interfaces to different clients via a +// BootstrapInterface. + +template , + typename ExternalRef = _::ExternalRefFromRealmGatewayClient> +RpcSystem makeRpcServer( + VatNetwork& network, + BootstrapFactory& bootstrapFactory, RealmGatewayClient gateway); +// Make an RPC server that can serve different bootstrap interfaces to different clients via a +// BootstrapInterface and communicates with a different realm than the application is in via a +// RealmGateway. + +template +RpcSystem makeRpcServer( + VatNetwork& network, + SturdyRefRestorer& restorer) + KJ_DEPRECATED("Please transition to using a bootstrap interface instead."); +// ** DEPRECATED ** +// +// Create an RPC server which exports multiple main interfaces by object ID. The `restorer` object +// can be used to look up objects by ID. +// +// Please transition to exporting only one interface, which is known as the "bootstrap" interface. +// For backwards-compatibility with old clients, continue to implement SturdyRefRestorer, but +// return the new bootstrap interface when the request object ID is null. When new clients connect +// and request the bootstrap interface, they will get that interface. Eventually, once all clients +// are updated to request only the bootstrap interface, stop implementing SturdyRefRestorer and +// switch to passing the bootstrap capability itself as the second parameter to `makeRpcServer()`. + +template +RpcSystem makeRpcClient( + VatNetwork& network); +// Make an RPC client. Typical usage (e.g. in a main() function): +// +// MyEventLoop eventLoop; +// kj::WaitScope waitScope(eventLoop); +// MyNetwork network; +// auto client = makeRpcClient(network); +// MyCapability::Client cap = client.restore(hostId, objId).castAs(); +// auto response = cap.fooRequest().send().wait(waitScope); +// handleMyResponse(response); +// +// See also ez-rpc.h, which has simpler instructions for the common case of a two-party +// client-server RPC connection. + +template , + typename ExternalRef = _::ExternalRefFromRealmGatewayClient> +RpcSystem makeRpcClient( + VatNetwork& network, + RealmGatewayClient gateway); +// Make an RPC client for a VatNetwork that resides in a different realm from the application. +// The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format +// and the network's ("external") format. + +template +class SturdyRefRestorer: public _::SturdyRefRestorerBase { + // ** DEPRECATED ** + // + // In Cap'n Proto 0.4.x, applications could export multiple main interfaces identified by + // object IDs. The callback used to map object IDs to objects was `SturdyRefRestorer`, as we + // imagined this would eventually be used for restoring SturdyRefs as well. In practice, it was + // never used for real SturdyRefs, only for exporting singleton objects under well-known names. + // + // The new preferred strategy is to export only a _single_ such interface, called the + // "bootstrap interface". That interface can itself have methods for obtaining other objects, of + // course, but that is up to the app. `SturdyRefRestorer` exists for backwards-compatibility. + // + // Hint: Use SturdyRefRestorer to define a server that exports services under + // string names. + +public: + virtual Capability::Client restore(typename SturdyRefObjectId::Reader ref) + KJ_DEPRECATED( + "Please transition to using bootstrap interfaces instead of SturdyRefRestorer.") = 0; + // Restore the given object, returning a capability representing it. + +private: + Capability::Client baseRestore(AnyPointer::Reader ref) override final; +}; + +// ======================================================================================= +// VatNetwork + +class OutgoingRpcMessage { + // A message to be sent by a `VatNetwork`. + +public: + virtual AnyPointer::Builder getBody() = 0; + // Get the message body, which the caller may fill in any way it wants. (The standard RPC + // implementation initializes it as a Message as defined in rpc.capnp.) + + virtual void send() = 0; + // Send the message, or at least put it in a queue to be sent later. Note that the builder + // returned by `getBody()` remains valid at least until the `OutgoingRpcMessage` is destroyed. +}; + +class IncomingRpcMessage { + // A message received from a `VatNetwork`. + +public: + virtual AnyPointer::Reader getBody() = 0; + // Get the message body, to be interpreted by the caller. (The standard RPC implementation + // interprets it as a Message as defined in rpc.capnp.) +}; + +template +class VatNetwork: public _::VatNetworkBase { + // Cap'n Proto RPC operates between vats, where a "vat" is some sort of host of objects. + // Typically one Cap'n Proto process (in the Unix sense) is one vat. The RPC system is what + // allows calls between objects hosted in different vats. + // + // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork` + // determines how to form connections between vats -- specifically, two-way, private, reliable, + // sequenced datagram connections. The RPC implementation determines how to use such connections + // to manage object references and make method calls. + // + // The most common implementation of VatNetwork is TwoPartyVatNetwork (rpc-twoparty.h). Most + // simple client-server apps will want to use it. (You may even want to use the EZ RPC + // interfaces in `ez-rpc.h` and avoid all of this.) + // + // TODO(someday): Provide a standard implementation for the public internet. + +public: + class Connection; + + struct ConnectionAndProvisionId { + // Result of connecting to a vat introduced by another vat. + + kj::Own connection; + // Connection to the new vat. + + kj::Own firstMessage; + // An already-allocated `OutgoingRpcMessage` associated with `connection`. The RPC system will + // construct this as an `Accept` message and send it. + + Orphan provisionId; + // A `ProvisionId` already allocated inside `firstMessage`, which the RPC system will use to + // build the `Accept` message. + }; + + class Connection: public _::VatNetworkBase::Connection { + // A two-way RPC connection. + // + // This object may represent a connection that doesn't exist yet, but is expected to exist + // in the future. In this case, sent messages will automatically be queued and sent once the + // connection is ready, so that the caller doesn't need to know the difference. + + public: + // Level 0 features ---------------------------------------------- + + virtual typename VatId::Reader getPeerVatId() = 0; + // Returns the connected vat's authenticated VatId. It is the VatNetwork's responsibility to + // authenticate this, so that the caller can be assured that they are really talking to the + // identified vat and not an imposter. + + virtual kj::Own newOutgoingMessage(uint firstSegmentWordSize) override = 0; + // Allocate a new message to be sent on this connection. + // + // If `firstSegmentWordSize` is non-zero, it should be treated as a hint suggesting how large + // to make the first segment. This is entirely a hint and the connection may adjust it up or + // down. If it is zero, the connection should choose the size itself. + + virtual kj::Promise>> receiveIncomingMessage() override = 0; + // Wait for a message to be received and return it. If the read stream cleanly terminates, + // return null. If any other problem occurs, throw an exception. + + virtual kj::Promise shutdown() override KJ_WARN_UNUSED_RESULT = 0; + // Waits until all outgoing messages have been sent, then shuts down the outgoing stream. The + // returned promise resolves after shutdown is complete. + + private: + AnyStruct::Reader baseGetPeerVatId() override; + }; + + // Level 0 features ------------------------------------------------ + + virtual kj::Maybe> connect(typename VatId::Reader hostId) = 0; + // Connect to a VatId. Note that this method immediately returns a `Connection`, even + // if the network connection has not yet been established. Messages can be queued to this + // connection and will be delivered once it is open. The caller must attempt to read from the + // connection to verify that it actually succeeded; the read will fail if the connection + // couldn't be opened. Some network implementations may actually start sending messages before + // hearing back from the server at all, to avoid a round trip. + // + // Returns nullptr if `hostId` refers to the local host. + + virtual kj::Promise> accept() = 0; + // Wait for the next incoming connection and return it. + + // Level 4 features ------------------------------------------------ + // TODO(someday) + +private: + kj::Maybe> + baseConnect(AnyStruct::Reader hostId) override final; + kj::Promise> baseAccept() override final; +}; + +// ======================================================================================= +// *************************************************************************************** +// Inline implementation details start here +// *************************************************************************************** +// ======================================================================================= + +template +Capability::Client BootstrapFactory::baseCreateFor(AnyStruct::Reader clientId) { + return createFor(clientId.as()); +} + +template +kj::Maybe> + VatNetwork:: + baseConnect(AnyStruct::Reader ref) { + auto maybe = connect(ref.as()); + return maybe.map([](kj::Own& conn) -> kj::Own<_::VatNetworkBase::Connection> { + return kj::mv(conn); + }); +} + +template +kj::Promise> + VatNetwork::baseAccept() { + return accept().then( + [](kj::Own&& connection) -> kj::Own<_::VatNetworkBase::Connection> { + return kj::mv(connection); + }); +} + +template +AnyStruct::Reader VatNetwork< + SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>:: + Connection::baseGetPeerVatId() { + return getPeerVatId(); +} + +template +Capability::Client SturdyRefRestorer::baseRestore(AnyPointer::Reader ref) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + return restore(ref.getAs()); +#pragma GCC diagnostic pop +} + +template +template +RpcSystem::RpcSystem( + VatNetwork& network, + kj::Maybe bootstrap, + kj::Maybe::Client> gateway) + : _::RpcSystemBase(network, kj::mv(bootstrap), kj::mv(gateway)) {} + +template +template +RpcSystem::RpcSystem( + VatNetwork& network, + BootstrapFactory& bootstrapFactory, + kj::Maybe::Client> gateway) + : _::RpcSystemBase(network, bootstrapFactory, kj::mv(gateway)) {} + +template +template +RpcSystem::RpcSystem( + VatNetwork& network, + SturdyRefRestorer& restorer) + : _::RpcSystemBase(network, restorer) {} + +template +Capability::Client RpcSystem::bootstrap(typename VatId::Reader vatId) { + return baseBootstrap(_::PointerHelpers::getInternalReader(vatId)); +} + +template +Capability::Client RpcSystem::restore( + typename VatId::Reader hostId, AnyPointer::Reader objectId) { + return baseRestore(_::PointerHelpers::getInternalReader(hostId), objectId); +} + +template +inline void RpcSystem::setFlowLimit(size_t words) { + baseSetFlowLimit(words); +} + +template +RpcSystem makeRpcServer( + VatNetwork& network, + Capability::Client bootstrapInterface) { + return RpcSystem(network, kj::mv(bootstrapInterface)); +} + +template +RpcSystem makeRpcServer( + VatNetwork& network, + Capability::Client bootstrapInterface, RealmGatewayClient gateway) { + return RpcSystem(network, kj::mv(bootstrapInterface), + gateway.template castAs>()); +} + +template +RpcSystem makeRpcServer( + VatNetwork& network, + BootstrapFactory& bootstrapFactory) { + return RpcSystem(network, bootstrapFactory); +} + +template +RpcSystem makeRpcServer( + VatNetwork& network, + BootstrapFactory& bootstrapFactory, RealmGatewayClient gateway) { + return RpcSystem(network, bootstrapFactory, gateway.template castAs>()); +} + +template +RpcSystem makeRpcServer( + VatNetwork& network, + SturdyRefRestorer& restorer) { + return RpcSystem(network, restorer); +} + +template +RpcSystem makeRpcClient( + VatNetwork& network) { + return RpcSystem(network, nullptr); +} + +template +RpcSystem makeRpcClient( + VatNetwork& network, + RealmGatewayClient gateway) { + return RpcSystem(network, nullptr, gateway.template castAs>()); +} + +} // namespace capnp + +#endif // CAPNP_RPC_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/schema-lite.h --- a/win32-mingw/include/capnp/schema-lite.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/schema-lite.h Tue May 23 09:16:54 2017 +0100 @@ -1,48 +1,48 @@ -// 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. - -#ifndef CAPNP_SCHEMA_LITE_H_ -#define CAPNP_SCHEMA_LITE_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include "message.h" - -namespace capnp { - -template -inline schema::Node::Reader schemaProto() { - // Get the schema::Node for this type's schema. This function works even in lite mode. - return readMessageUnchecked(CapnpPrivate::encodedSchema()); -} - -template ::typeId> -inline schema::Node::Reader schemaProto() { - // Get the schema::Node for this type's schema. This function works even in lite mode. - return readMessageUnchecked(schemas::EnumInfo::encodedSchema()); -} - -} // namespace capnp - -#endif // CAPNP_SCHEMA_LITE_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. + +#ifndef CAPNP_SCHEMA_LITE_H_ +#define CAPNP_SCHEMA_LITE_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include +#include "message.h" + +namespace capnp { + +template +inline schema::Node::Reader schemaProto() { + // Get the schema::Node for this type's schema. This function works even in lite mode. + return readMessageUnchecked(CapnpPrivate::encodedSchema()); +} + +template ::typeId> +inline schema::Node::Reader schemaProto() { + // Get the schema::Node for this type's schema. This function works even in lite mode. + return readMessageUnchecked(schemas::EnumInfo::encodedSchema()); +} + +} // namespace capnp + +#endif // CAPNP_SCHEMA_LITE_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/schema-loader.h --- a/win32-mingw/include/capnp/schema-loader.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/schema-loader.h Tue May 23 09:16:54 2017 +0100 @@ -1,173 +1,173 @@ -// 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. - -#ifndef CAPNP_SCHEMA_LOADER_H_ -#define CAPNP_SCHEMA_LOADER_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "schema.h" -#include -#include - -namespace capnp { - -class SchemaLoader { - // Class which can be used to construct Schema objects from schema::Nodes as defined in - // schema.capnp. - // - // It is a bad idea to use this class on untrusted input with exceptions disabled -- you may - // be exposing yourself to denial-of-service attacks, as attackers can easily construct schemas - // that are subtly inconsistent in a way that causes exceptions to be thrown either by - // SchemaLoader or by the dynamic API when the schemas are subsequently used. If you enable and - // properly catch exceptions, you should be OK -- assuming no bugs in the Cap'n Proto - // implementation, of course. - -public: - class LazyLoadCallback { - public: - virtual void load(const SchemaLoader& loader, uint64_t id) const = 0; - // Request that the schema node with the given ID be loaded into the given SchemaLoader. If - // the callback is able to find a schema for this ID, it should invoke `loadOnce()` on - // `loader` to load it. If no such node exists, it should simply do nothing and return. - // - // The callback is allowed to load schema nodes other than the one requested, e.g. because it - // expects they will be needed soon. - // - // If the `SchemaLoader` is used from multiple threads, the callback must be thread-safe. - // In particular, it's possible for multiple threads to invoke `load()` with the same ID. - // If the callback performs a large amount of work to look up IDs, it should be sure to - // de-dup these requests. - }; - - SchemaLoader(); - - SchemaLoader(const LazyLoadCallback& callback); - // Construct a SchemaLoader which will invoke the given callback when a schema node is requested - // that isn't already loaded. - - ~SchemaLoader() noexcept(false); - KJ_DISALLOW_COPY(SchemaLoader); - - Schema get(uint64_t id, schema::Brand::Reader brand = schema::Brand::Reader(), - Schema scope = Schema()) const; - // Gets the schema for the given ID, throwing an exception if it isn't present. - // - // The returned schema may be invalidated if load() is called with a new schema for the same ID. - // In general, you should not call load() while a schema from this loader is in-use. - // - // `brand` and `scope` are used to determine brand bindings where relevant. `brand` gives - // parameter bindings for the target type's brand parameters that were specified at the reference - // site. `scope` specifies the scope in which the type ID appeared -- if `brand` itself contains - // parameter references or indicates that some parameters will be inherited, these will be - // interpreted within / inherited from `scope`. - - kj::Maybe tryGet(uint64_t id, schema::Brand::Reader bindings = schema::Brand::Reader(), - Schema scope = Schema()) const; - // Like get() but doesn't throw. - - Schema getUnbound(uint64_t id) const; - // Gets a special version of the schema in which all brand parameters are "unbound". This means - // that if you look up a type via the Schema API, and it resolves to a brand parameter, the - // returned Type's getBrandParameter() method will return info about that parameter. Otherwise, - // normally, all brand parameters that aren't otherwise bound are assumed to simply be - // "AnyPointer". - - Type getType(schema::Type::Reader type, Schema scope = Schema()) const; - // Convenience method which interprets a schema::Type to produce a Type object. Implemented in - // terms of get(). - - Schema load(const schema::Node::Reader& reader); - // Loads the given schema node. Validates the node and throws an exception if invalid. This - // makes a copy of the schema, so the object passed in can be destroyed after this returns. - // - // If the node has any dependencies which are not already loaded, they will be initialized as - // stubs -- empty schemas of whichever kind is expected. - // - // If another schema for the given reader has already been seen, the loader will inspect both - // schemas to determine which one is newer, and use that that one. If the two versions are - // found to be incompatible, an exception is thrown. If the two versions differ but are - // compatible and the loader cannot determine which is newer (e.g., the only changes are renames), - // the existing schema will be preferred. Note that in any case, the loader will end up keeping - // around copies of both schemas, so you shouldn't repeatedly reload schemas into the same loader. - // - // The following properties of the schema node are validated: - // - Struct size and preferred list encoding are valid and consistent. - // - Struct members are fields or unions. - // - Union members are fields. - // - Field offsets are in-bounds. - // - Ordinals and codeOrders are sequential starting from zero. - // - Values are of the right union case to match their types. - // - // You should assume anything not listed above is NOT validated. In particular, things that are - // not validated now, but could be in the future, include but are not limited to: - // - Names. - // - Annotation values. (This is hard because the annotation declaration is not always - // available.) - // - Content of default/constant values of pointer type. (Validating these would require knowing - // their schema, but even if the schemas are available at validation time, they could be - // updated by a subsequent load(), invalidating existing values. Instead, these values are - // validated at the time they are used, as usual for Cap'n Proto objects.) - // - // Also note that unknown types are not considered invalid. Instead, the dynamic API returns - // a DynamicValue with type UNKNOWN for these. - - Schema loadOnce(const schema::Node::Reader& reader) const; - // Like `load()` but does nothing if a schema with the same ID is already loaded. In contrast, - // `load()` would attempt to compare the schemas and take the newer one. `loadOnce()` is safe - // to call even while concurrently using schemas from this loader. It should be considered an - // error to call `loadOnce()` with two non-identical schemas that share the same ID, although - // this error may or may not actually be detected by the implementation. - - template - void loadCompiledTypeAndDependencies(); - // Load the schema for the given compiled-in type and all of its dependencies. - // - // If you want to be able to cast a DynamicValue built from this SchemaLoader to the compiled-in - // type using as(), you must call this method before constructing the DynamicValue. Otherwise, - // as() will throw an exception complaining about type mismatch. - - kj::Array getAllLoaded() const; - // Get a complete list of all loaded schema nodes. It is particularly useful to call this after - // loadCompiledTypeAndDependencies() in order to get a flat list of all of T's transitive - // dependencies. - -private: - class Validator; - class CompatibilityChecker; - class Impl; - class InitializerImpl; - class BrandedInitializerImpl; - kj::MutexGuarded> impl; - - void loadNative(const _::RawSchema* nativeSchema); -}; - -template -inline void SchemaLoader::loadCompiledTypeAndDependencies() { - loadNative(&_::rawSchema()); -} - -} // namespace capnp - -#endif // CAPNP_SCHEMA_LOADER_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. + +#ifndef CAPNP_SCHEMA_LOADER_H_ +#define CAPNP_SCHEMA_LOADER_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "schema.h" +#include +#include + +namespace capnp { + +class SchemaLoader { + // Class which can be used to construct Schema objects from schema::Nodes as defined in + // schema.capnp. + // + // It is a bad idea to use this class on untrusted input with exceptions disabled -- you may + // be exposing yourself to denial-of-service attacks, as attackers can easily construct schemas + // that are subtly inconsistent in a way that causes exceptions to be thrown either by + // SchemaLoader or by the dynamic API when the schemas are subsequently used. If you enable and + // properly catch exceptions, you should be OK -- assuming no bugs in the Cap'n Proto + // implementation, of course. + +public: + class LazyLoadCallback { + public: + virtual void load(const SchemaLoader& loader, uint64_t id) const = 0; + // Request that the schema node with the given ID be loaded into the given SchemaLoader. If + // the callback is able to find a schema for this ID, it should invoke `loadOnce()` on + // `loader` to load it. If no such node exists, it should simply do nothing and return. + // + // The callback is allowed to load schema nodes other than the one requested, e.g. because it + // expects they will be needed soon. + // + // If the `SchemaLoader` is used from multiple threads, the callback must be thread-safe. + // In particular, it's possible for multiple threads to invoke `load()` with the same ID. + // If the callback performs a large amount of work to look up IDs, it should be sure to + // de-dup these requests. + }; + + SchemaLoader(); + + SchemaLoader(const LazyLoadCallback& callback); + // Construct a SchemaLoader which will invoke the given callback when a schema node is requested + // that isn't already loaded. + + ~SchemaLoader() noexcept(false); + KJ_DISALLOW_COPY(SchemaLoader); + + Schema get(uint64_t id, schema::Brand::Reader brand = schema::Brand::Reader(), + Schema scope = Schema()) const; + // Gets the schema for the given ID, throwing an exception if it isn't present. + // + // The returned schema may be invalidated if load() is called with a new schema for the same ID. + // In general, you should not call load() while a schema from this loader is in-use. + // + // `brand` and `scope` are used to determine brand bindings where relevant. `brand` gives + // parameter bindings for the target type's brand parameters that were specified at the reference + // site. `scope` specifies the scope in which the type ID appeared -- if `brand` itself contains + // parameter references or indicates that some parameters will be inherited, these will be + // interpreted within / inherited from `scope`. + + kj::Maybe tryGet(uint64_t id, schema::Brand::Reader bindings = schema::Brand::Reader(), + Schema scope = Schema()) const; + // Like get() but doesn't throw. + + Schema getUnbound(uint64_t id) const; + // Gets a special version of the schema in which all brand parameters are "unbound". This means + // that if you look up a type via the Schema API, and it resolves to a brand parameter, the + // returned Type's getBrandParameter() method will return info about that parameter. Otherwise, + // normally, all brand parameters that aren't otherwise bound are assumed to simply be + // "AnyPointer". + + Type getType(schema::Type::Reader type, Schema scope = Schema()) const; + // Convenience method which interprets a schema::Type to produce a Type object. Implemented in + // terms of get(). + + Schema load(const schema::Node::Reader& reader); + // Loads the given schema node. Validates the node and throws an exception if invalid. This + // makes a copy of the schema, so the object passed in can be destroyed after this returns. + // + // If the node has any dependencies which are not already loaded, they will be initialized as + // stubs -- empty schemas of whichever kind is expected. + // + // If another schema for the given reader has already been seen, the loader will inspect both + // schemas to determine which one is newer, and use that that one. If the two versions are + // found to be incompatible, an exception is thrown. If the two versions differ but are + // compatible and the loader cannot determine which is newer (e.g., the only changes are renames), + // the existing schema will be preferred. Note that in any case, the loader will end up keeping + // around copies of both schemas, so you shouldn't repeatedly reload schemas into the same loader. + // + // The following properties of the schema node are validated: + // - Struct size and preferred list encoding are valid and consistent. + // - Struct members are fields or unions. + // - Union members are fields. + // - Field offsets are in-bounds. + // - Ordinals and codeOrders are sequential starting from zero. + // - Values are of the right union case to match their types. + // + // You should assume anything not listed above is NOT validated. In particular, things that are + // not validated now, but could be in the future, include but are not limited to: + // - Names. + // - Annotation values. (This is hard because the annotation declaration is not always + // available.) + // - Content of default/constant values of pointer type. (Validating these would require knowing + // their schema, but even if the schemas are available at validation time, they could be + // updated by a subsequent load(), invalidating existing values. Instead, these values are + // validated at the time they are used, as usual for Cap'n Proto objects.) + // + // Also note that unknown types are not considered invalid. Instead, the dynamic API returns + // a DynamicValue with type UNKNOWN for these. + + Schema loadOnce(const schema::Node::Reader& reader) const; + // Like `load()` but does nothing if a schema with the same ID is already loaded. In contrast, + // `load()` would attempt to compare the schemas and take the newer one. `loadOnce()` is safe + // to call even while concurrently using schemas from this loader. It should be considered an + // error to call `loadOnce()` with two non-identical schemas that share the same ID, although + // this error may or may not actually be detected by the implementation. + + template + void loadCompiledTypeAndDependencies(); + // Load the schema for the given compiled-in type and all of its dependencies. + // + // If you want to be able to cast a DynamicValue built from this SchemaLoader to the compiled-in + // type using as(), you must call this method before constructing the DynamicValue. Otherwise, + // as() will throw an exception complaining about type mismatch. + + kj::Array getAllLoaded() const; + // Get a complete list of all loaded schema nodes. It is particularly useful to call this after + // loadCompiledTypeAndDependencies() in order to get a flat list of all of T's transitive + // dependencies. + +private: + class Validator; + class CompatibilityChecker; + class Impl; + class InitializerImpl; + class BrandedInitializerImpl; + kj::MutexGuarded> impl; + + void loadNative(const _::RawSchema* nativeSchema); +}; + +template +inline void SchemaLoader::loadCompiledTypeAndDependencies() { + loadNative(&_::rawSchema()); +} + +} // namespace capnp + +#endif // CAPNP_SCHEMA_LOADER_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/schema-parser.h --- a/win32-mingw/include/capnp/schema-parser.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/schema-parser.h Tue May 23 09:16:54 2017 +0100 @@ -1,207 +1,207 @@ -// 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. - -#ifndef CAPNP_SCHEMA_PARSER_H_ -#define CAPNP_SCHEMA_PARSER_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "schema-loader.h" -#include - -namespace capnp { - -class ParsedSchema; -class SchemaFile; - -class SchemaParser { - // Parses `.capnp` files to produce `Schema` objects. - // - // This class is thread-safe, hence all its methods are const. - -public: - SchemaParser(); - ~SchemaParser() noexcept(false); - - ParsedSchema parseDiskFile(kj::StringPtr displayName, kj::StringPtr diskPath, - kj::ArrayPtr importPath) const; - // Parse a file located on disk. Throws an exception if the file dosen't exist. - // - // Parameters: - // * `displayName`: The name that will appear in the file's schema node. (If the file has - // already been parsed, this will be ignored and the display name from the first time it was - // parsed will be kept.) - // * `diskPath`: The path to the file on disk. - // * `importPath`: Directories to search when resolving absolute imports within this file - // (imports that start with a `/`). Must remain valid until the SchemaParser is destroyed. - // (If the file has already been parsed, this will be ignored and the import path from the - // first time it was parsed will be kept.) - // - // This method is a shortcut, equivalent to: - // parser.parseFile(SchemaFile::newDiskFile(displayName, diskPath, importPath))`; - // - // This method throws an exception if any errors are encountered in the file or in anything the - // file depends on. Note that merely importing another file does not count as a dependency on - // anything in the imported file -- only the imported types which are actually used are - // "dependencies". - - ParsedSchema parseFile(kj::Own&& file) const; - // Advanced interface for parsing a file that may or may not be located in any global namespace. - // Most users will prefer `parseDiskFile()`. - // - // If the file has already been parsed (that is, a SchemaFile that compares equal to this one - // was parsed previously), the existing schema will be returned again. - // - // This method reports errors by calling SchemaFile::reportError() on the file where the error - // is located. If that call does not throw an exception, `parseFile()` may in fact return - // normally. In this case, the result is a best-effort attempt to compile the schema, but it - // may be invalid or corrupt, and using it for anything may cause exceptions to be thrown. - - template - inline void loadCompiledTypeAndDependencies() { - // See SchemaLoader::loadCompiledTypeAndDependencies(). - getLoader().loadCompiledTypeAndDependencies(); - } - -private: - struct Impl; - class ModuleImpl; - kj::Own impl; - mutable bool hadErrors = false; - - ModuleImpl& getModuleImpl(kj::Own&& file) const; - SchemaLoader& getLoader(); - - friend class ParsedSchema; -}; - -class ParsedSchema: public Schema { - // ParsedSchema is an extension of Schema which also has the ability to look up nested nodes - // by name. See `SchemaParser`. - -public: - inline ParsedSchema(): parser(nullptr) {} - - kj::Maybe findNested(kj::StringPtr name) const; - // Gets the nested node with the given name, or returns null if there is no such nested - // declaration. - - ParsedSchema getNested(kj::StringPtr name) const; - // Gets the nested node with the given name, or throws an exception if there is no such nested - // declaration. - -private: - inline ParsedSchema(Schema inner, const SchemaParser& parser): Schema(inner), parser(&parser) {} - - const SchemaParser* parser; - friend class SchemaParser; -}; - -// ======================================================================================= -// Advanced API - -class SchemaFile { - // Abstract interface representing a schema file. You can implement this yourself in order to - // gain more control over how the compiler resolves imports and reads files. For the - // common case of files on disk or other global filesystem-like namespaces, use - // `SchemaFile::newDiskFile()`. - -public: - class FileReader { - public: - virtual bool exists(kj::StringPtr path) const = 0; - virtual kj::Array read(kj::StringPtr path) const = 0; - }; - - class DiskFileReader final: public FileReader { - // Implementation of FileReader that uses the local disk. Files are read using mmap() if - // possible. - - public: - static const DiskFileReader instance; - - bool exists(kj::StringPtr path) const override; - kj::Array read(kj::StringPtr path) const override; - }; - - static kj::Own newDiskFile( - kj::StringPtr displayName, kj::StringPtr diskPath, - kj::ArrayPtr importPath, - const FileReader& fileReader = DiskFileReader::instance); - // Construct a SchemaFile representing a file on disk (or located in the filesystem-like - // namespace represented by `fileReader`). - // - // Parameters: - // * `displayName`: The name that will appear in the file's schema node. - // * `diskPath`: The path to the file on disk. - // * `importPath`: Directories to search when resolving absolute imports within this file - // (imports that start with a `/`). The array content must remain valid as long as the - // SchemaFile exists (which is at least as long as the SchemaParser that parses it exists). - // * `fileReader`: Allows you to use a filesystem other than the actual local disk. Although, - // if you find yourself using this, it may make more sense for you to implement SchemaFile - // yourself. - // - // The SchemaFile compares equal to any other SchemaFile that has exactly the same disk path, - // after canonicalization. - // - // The SchemaFile will throw an exception if any errors are reported. - - // ----------------------------------------------------------------- - // For more control, you can implement this interface. - - virtual kj::StringPtr getDisplayName() const = 0; - // Get the file's name, as it should appear in the schema. - - virtual kj::Array readContent() const = 0; - // Read the file's entire content and return it as a byte array. - - virtual kj::Maybe> import(kj::StringPtr path) const = 0; - // Resolve an import, relative to this file. - // - // `path` is exactly what appears between quotes after the `import` keyword in the source code. - // It is entirely up to the `SchemaFile` to decide how to map this to another file. Typically, - // a leading '/' means that the file is an "absolute" path and is searched for in some list of - // schema file repositories. On the other hand, a path that doesn't start with '/' is relative - // to the importing file. - - virtual bool operator==(const SchemaFile& other) const = 0; - virtual bool operator!=(const SchemaFile& other) const = 0; - virtual size_t hashCode() const = 0; - // Compare two SchemaFiles to see if they refer to the same underlying file. This is an - // optimization used to avoid the need to re-parse a file to check its ID. - - struct SourcePos { - uint byte; - uint line; - uint column; - }; - virtual void reportError(SourcePos start, SourcePos end, kj::StringPtr message) const = 0; - // Report that the file contains an error at the given interval. - -private: - class DiskSchemaFile; -}; - -} // namespace capnp - -#endif // CAPNP_SCHEMA_PARSER_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. + +#ifndef CAPNP_SCHEMA_PARSER_H_ +#define CAPNP_SCHEMA_PARSER_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "schema-loader.h" +#include + +namespace capnp { + +class ParsedSchema; +class SchemaFile; + +class SchemaParser { + // Parses `.capnp` files to produce `Schema` objects. + // + // This class is thread-safe, hence all its methods are const. + +public: + SchemaParser(); + ~SchemaParser() noexcept(false); + + ParsedSchema parseDiskFile(kj::StringPtr displayName, kj::StringPtr diskPath, + kj::ArrayPtr importPath) const; + // Parse a file located on disk. Throws an exception if the file dosen't exist. + // + // Parameters: + // * `displayName`: The name that will appear in the file's schema node. (If the file has + // already been parsed, this will be ignored and the display name from the first time it was + // parsed will be kept.) + // * `diskPath`: The path to the file on disk. + // * `importPath`: Directories to search when resolving absolute imports within this file + // (imports that start with a `/`). Must remain valid until the SchemaParser is destroyed. + // (If the file has already been parsed, this will be ignored and the import path from the + // first time it was parsed will be kept.) + // + // This method is a shortcut, equivalent to: + // parser.parseFile(SchemaFile::newDiskFile(displayName, diskPath, importPath))`; + // + // This method throws an exception if any errors are encountered in the file or in anything the + // file depends on. Note that merely importing another file does not count as a dependency on + // anything in the imported file -- only the imported types which are actually used are + // "dependencies". + + ParsedSchema parseFile(kj::Own&& file) const; + // Advanced interface for parsing a file that may or may not be located in any global namespace. + // Most users will prefer `parseDiskFile()`. + // + // If the file has already been parsed (that is, a SchemaFile that compares equal to this one + // was parsed previously), the existing schema will be returned again. + // + // This method reports errors by calling SchemaFile::reportError() on the file where the error + // is located. If that call does not throw an exception, `parseFile()` may in fact return + // normally. In this case, the result is a best-effort attempt to compile the schema, but it + // may be invalid or corrupt, and using it for anything may cause exceptions to be thrown. + + template + inline void loadCompiledTypeAndDependencies() { + // See SchemaLoader::loadCompiledTypeAndDependencies(). + getLoader().loadCompiledTypeAndDependencies(); + } + +private: + struct Impl; + class ModuleImpl; + kj::Own impl; + mutable bool hadErrors = false; + + ModuleImpl& getModuleImpl(kj::Own&& file) const; + SchemaLoader& getLoader(); + + friend class ParsedSchema; +}; + +class ParsedSchema: public Schema { + // ParsedSchema is an extension of Schema which also has the ability to look up nested nodes + // by name. See `SchemaParser`. + +public: + inline ParsedSchema(): parser(nullptr) {} + + kj::Maybe findNested(kj::StringPtr name) const; + // Gets the nested node with the given name, or returns null if there is no such nested + // declaration. + + ParsedSchema getNested(kj::StringPtr name) const; + // Gets the nested node with the given name, or throws an exception if there is no such nested + // declaration. + +private: + inline ParsedSchema(Schema inner, const SchemaParser& parser): Schema(inner), parser(&parser) {} + + const SchemaParser* parser; + friend class SchemaParser; +}; + +// ======================================================================================= +// Advanced API + +class SchemaFile { + // Abstract interface representing a schema file. You can implement this yourself in order to + // gain more control over how the compiler resolves imports and reads files. For the + // common case of files on disk or other global filesystem-like namespaces, use + // `SchemaFile::newDiskFile()`. + +public: + class FileReader { + public: + virtual bool exists(kj::StringPtr path) const = 0; + virtual kj::Array read(kj::StringPtr path) const = 0; + }; + + class DiskFileReader final: public FileReader { + // Implementation of FileReader that uses the local disk. Files are read using mmap() if + // possible. + + public: + static const DiskFileReader instance; + + bool exists(kj::StringPtr path) const override; + kj::Array read(kj::StringPtr path) const override; + }; + + static kj::Own newDiskFile( + kj::StringPtr displayName, kj::StringPtr diskPath, + kj::ArrayPtr importPath, + const FileReader& fileReader = DiskFileReader::instance); + // Construct a SchemaFile representing a file on disk (or located in the filesystem-like + // namespace represented by `fileReader`). + // + // Parameters: + // * `displayName`: The name that will appear in the file's schema node. + // * `diskPath`: The path to the file on disk. + // * `importPath`: Directories to search when resolving absolute imports within this file + // (imports that start with a `/`). The array content must remain valid as long as the + // SchemaFile exists (which is at least as long as the SchemaParser that parses it exists). + // * `fileReader`: Allows you to use a filesystem other than the actual local disk. Although, + // if you find yourself using this, it may make more sense for you to implement SchemaFile + // yourself. + // + // The SchemaFile compares equal to any other SchemaFile that has exactly the same disk path, + // after canonicalization. + // + // The SchemaFile will throw an exception if any errors are reported. + + // ----------------------------------------------------------------- + // For more control, you can implement this interface. + + virtual kj::StringPtr getDisplayName() const = 0; + // Get the file's name, as it should appear in the schema. + + virtual kj::Array readContent() const = 0; + // Read the file's entire content and return it as a byte array. + + virtual kj::Maybe> import(kj::StringPtr path) const = 0; + // Resolve an import, relative to this file. + // + // `path` is exactly what appears between quotes after the `import` keyword in the source code. + // It is entirely up to the `SchemaFile` to decide how to map this to another file. Typically, + // a leading '/' means that the file is an "absolute" path and is searched for in some list of + // schema file repositories. On the other hand, a path that doesn't start with '/' is relative + // to the importing file. + + virtual bool operator==(const SchemaFile& other) const = 0; + virtual bool operator!=(const SchemaFile& other) const = 0; + virtual size_t hashCode() const = 0; + // Compare two SchemaFiles to see if they refer to the same underlying file. This is an + // optimization used to avoid the need to re-parse a file to check its ID. + + struct SourcePos { + uint byte; + uint line; + uint column; + }; + virtual void reportError(SourcePos start, SourcePos end, kj::StringPtr message) const = 0; + // Report that the file contains an error at the given interval. + +private: + class DiskSchemaFile; +}; + +} // namespace capnp + +#endif // CAPNP_SCHEMA_PARSER_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/schema.capnp.h --- a/win32-mingw/include/capnp/schema.capnp.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/schema.capnp.h Tue May 23 09:16:54 2017 +0100 @@ -1,7561 +1,7861 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: schema.capnp - -#ifndef CAPNP_INCLUDED_a93fc509624c72d9_ -#define CAPNP_INCLUDED_a93fc509624c72d9_ - -#include - -#if CAPNP_VERSION != 6000 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(e682ab4cf923a417); -CAPNP_DECLARE_SCHEMA(b9521bccf10fa3b1); -CAPNP_DECLARE_SCHEMA(debf55bbfa0fc242); -CAPNP_DECLARE_SCHEMA(9ea0b19b37fb4435); -CAPNP_DECLARE_SCHEMA(b54ab3364333f598); -CAPNP_DECLARE_SCHEMA(e82753cff0c2218f); -CAPNP_DECLARE_SCHEMA(b18aa5ac7a0d9420); -CAPNP_DECLARE_SCHEMA(ec1619d4400a0290); -CAPNP_DECLARE_SCHEMA(9aad50a41f4af45f); -CAPNP_DECLARE_SCHEMA(97b14cbe7cfec712); -CAPNP_DECLARE_SCHEMA(c42305476bb4746f); -CAPNP_DECLARE_SCHEMA(cafccddb68db1d11); -CAPNP_DECLARE_SCHEMA(bb90d5c287870be6); -CAPNP_DECLARE_SCHEMA(978a7cebdc549a4d); -CAPNP_DECLARE_SCHEMA(a9962a9ed0a4d7f8); -CAPNP_DECLARE_SCHEMA(9500cce23b334d80); -CAPNP_DECLARE_SCHEMA(d07378ede1f9cc60); -CAPNP_DECLARE_SCHEMA(87e739250a60ea97); -CAPNP_DECLARE_SCHEMA(9e0e78711a7f87a9); -CAPNP_DECLARE_SCHEMA(ac3a6f60ef4cc6d3); -CAPNP_DECLARE_SCHEMA(ed8bca69f7fb0cbf); -CAPNP_DECLARE_SCHEMA(c2573fe8a23e49f1); -CAPNP_DECLARE_SCHEMA(8e3b5f79fe593656); -CAPNP_DECLARE_SCHEMA(9dd1f724f4614a85); -CAPNP_DECLARE_SCHEMA(baefc9120c56e274); -CAPNP_DECLARE_SCHEMA(903455f06065422b); -CAPNP_DECLARE_SCHEMA(abd73485a9636bc9); -CAPNP_DECLARE_SCHEMA(c863cd16969ee7fc); -CAPNP_DECLARE_SCHEMA(ce23dcd2d7b00c9b); -CAPNP_DECLARE_SCHEMA(f1c8950dab257542); -CAPNP_DECLARE_SCHEMA(d1958f7dba521926); -enum class ElementSize_d1958f7dba521926: uint16_t { - EMPTY, - BIT, - BYTE, - TWO_BYTES, - FOUR_BYTES, - EIGHT_BYTES, - POINTER, - INLINE_COMPOSITE, -}; -CAPNP_DECLARE_ENUM(ElementSize, d1958f7dba521926); -CAPNP_DECLARE_SCHEMA(bfc546f6210ad7ce); -CAPNP_DECLARE_SCHEMA(cfea0eb02e810062); -CAPNP_DECLARE_SCHEMA(ae504193122357e5); - -} // namespace schemas -} // namespace capnp - -namespace capnp { -namespace schema { - -struct Node { - Node() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - FILE, - STRUCT, - ENUM, - INTERFACE, - CONST, - ANNOTATION, - }; - struct Parameter; - struct NestedNode; - struct Struct; - struct Enum; - struct Interface; - struct Const; - struct Annotation; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(e682ab4cf923a417, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Node::Parameter { - Parameter() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b9521bccf10fa3b1, 0, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Node::NestedNode { - NestedNode() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(debf55bbfa0fc242, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Node::Struct { - Struct() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9ea0b19b37fb4435, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Node::Enum { - Enum() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b54ab3364333f598, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Node::Interface { - Interface() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(e82753cff0c2218f, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Node::Const { - Const() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b18aa5ac7a0d9420, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Node::Annotation { - Annotation() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ec1619d4400a0290, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Field { - Field() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - SLOT, - GROUP, - }; - static constexpr ::uint16_t NO_DISCRIMINANT = 65535u; - struct Slot; - struct Group; - struct Ordinal; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9aad50a41f4af45f, 3, 4) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Field::Slot { - Slot() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(c42305476bb4746f, 3, 4) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Field::Group { - Group() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(cafccddb68db1d11, 3, 4) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Field::Ordinal { - Ordinal() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - IMPLICIT, - EXPLICIT, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(bb90d5c287870be6, 3, 4) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Enumerant { - Enumerant() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(978a7cebdc549a4d, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Superclass { - Superclass() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(a9962a9ed0a4d7f8, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Method { - Method() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9500cce23b334d80, 3, 5) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type { - Type() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - VOID, - BOOL, - INT8, - INT16, - INT32, - INT64, - UINT8, - UINT16, - UINT32, - UINT64, - FLOAT32, - FLOAT64, - TEXT, - DATA, - LIST, - ENUM, - STRUCT, - INTERFACE, - ANY_POINTER, - }; - struct List; - struct Enum; - struct Struct; - struct Interface; - struct AnyPointer; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d07378ede1f9cc60, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type::List { - List() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(87e739250a60ea97, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type::Enum { - Enum() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9e0e78711a7f87a9, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type::Struct { - Struct() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ac3a6f60ef4cc6d3, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type::Interface { - Interface() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ed8bca69f7fb0cbf, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type::AnyPointer { - AnyPointer() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - UNCONSTRAINED, - PARAMETER, - IMPLICIT_METHOD_PARAMETER, - }; - struct Unconstrained; - struct Parameter; - struct ImplicitMethodParameter; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(c2573fe8a23e49f1, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type::AnyPointer::Unconstrained { - Unconstrained() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - ANY_KIND, - STRUCT, - LIST, - CAPABILITY, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(8e3b5f79fe593656, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type::AnyPointer::Parameter { - Parameter() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9dd1f724f4614a85, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Type::AnyPointer::ImplicitMethodParameter { - ImplicitMethodParameter() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(baefc9120c56e274, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Brand { - Brand() = delete; - - class Reader; - class Builder; - class Pipeline; - struct Scope; - struct Binding; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(903455f06065422b, 0, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Brand::Scope { - Scope() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - BIND, - INHERIT, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(abd73485a9636bc9, 2, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Brand::Binding { - Binding() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - UNBOUND, - TYPE, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(c863cd16969ee7fc, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Value { - Value() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - VOID, - BOOL, - INT8, - INT16, - INT32, - INT64, - UINT8, - UINT16, - UINT32, - UINT64, - FLOAT32, - FLOAT64, - TEXT, - DATA, - LIST, - ENUM, - STRUCT, - INTERFACE, - ANY_POINTER, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ce23dcd2d7b00c9b, 2, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct Annotation { - Annotation() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f1c8950dab257542, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -typedef ::capnp::schemas::ElementSize_d1958f7dba521926 ElementSize; - -struct CodeGeneratorRequest { - CodeGeneratorRequest() = delete; - - class Reader; - class Builder; - class Pipeline; - struct RequestedFile; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(bfc546f6210ad7ce, 0, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct CodeGeneratorRequest::RequestedFile { - RequestedFile() = delete; - - class Reader; - class Builder; - class Pipeline; - struct Import; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(cfea0eb02e810062, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -struct CodeGeneratorRequest::RequestedFile::Import { - Import() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ae504193122357e5, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -class Node::Reader { -public: - typedef Node Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline ::uint64_t getId() const; - - inline bool hasDisplayName() const; - inline ::capnp::Text::Reader getDisplayName() const; - - inline ::uint32_t getDisplayNamePrefixLength() const; - - inline ::uint64_t getScopeId() const; - - inline bool hasNestedNodes() const; - inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader getNestedNodes() const; - - inline bool hasAnnotations() const; - inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; - - inline bool isFile() const; - inline ::capnp::Void getFile() const; - - inline bool isStruct() const; - inline typename Struct::Reader getStruct() const; - - inline bool isEnum() const; - inline typename Enum::Reader getEnum() const; - - inline bool isInterface() const; - inline typename Interface::Reader getInterface() const; - - inline bool isConst() const; - inline typename Const::Reader getConst() const; - - inline bool isAnnotation() const; - inline typename Annotation::Reader getAnnotation() const; - - inline bool hasParameters() const; - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader getParameters() const; - - inline bool getIsGeneric() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Builder { -public: - typedef Node Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasDisplayName(); - inline ::capnp::Text::Builder getDisplayName(); - inline void setDisplayName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initDisplayName(unsigned int size); - inline void adoptDisplayName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownDisplayName(); - - inline ::uint32_t getDisplayNamePrefixLength(); - inline void setDisplayNamePrefixLength( ::uint32_t value); - - inline ::uint64_t getScopeId(); - inline void setScopeId( ::uint64_t value); - - inline bool hasNestedNodes(); - inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder getNestedNodes(); - inline void setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader value); - inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder initNestedNodes(unsigned int size); - inline void adoptNestedNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>> disownNestedNodes(); - - inline bool hasAnnotations(); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); - inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); - inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); - - inline bool isFile(); - inline ::capnp::Void getFile(); - inline void setFile( ::capnp::Void value = ::capnp::VOID); - - inline bool isStruct(); - inline typename Struct::Builder getStruct(); - inline typename Struct::Builder initStruct(); - - inline bool isEnum(); - inline typename Enum::Builder getEnum(); - inline typename Enum::Builder initEnum(); - - inline bool isInterface(); - inline typename Interface::Builder getInterface(); - inline typename Interface::Builder initInterface(); - - inline bool isConst(); - inline typename Const::Builder getConst(); - inline typename Const::Builder initConst(); - - inline bool isAnnotation(); - inline typename Annotation::Builder getAnnotation(); - inline typename Annotation::Builder initAnnotation(); - - inline bool hasParameters(); - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder getParameters(); - inline void setParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value); - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder initParameters(unsigned int size); - inline void adoptParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> disownParameters(); - - inline bool getIsGeneric(); - inline void setIsGeneric(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Pipeline { -public: - typedef Node Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Parameter::Reader { -public: - typedef Parameter Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Parameter::Builder { -public: - typedef Parameter Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Parameter::Pipeline { -public: - typedef Parameter Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::NestedNode::Reader { -public: - typedef NestedNode Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline ::uint64_t getId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::NestedNode::Builder { -public: - typedef NestedNode Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::NestedNode::Pipeline { -public: - typedef NestedNode Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Struct::Reader { -public: - typedef Struct Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint16_t getDataWordCount() const; - - inline ::uint16_t getPointerCount() const; - - inline ::capnp::schema::ElementSize getPreferredListEncoding() const; - - inline bool getIsGroup() const; - - inline ::uint16_t getDiscriminantCount() const; - - inline ::uint32_t getDiscriminantOffset() const; - - inline bool hasFields() const; - inline ::capnp::List< ::capnp::schema::Field>::Reader getFields() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Struct::Builder { -public: - typedef Struct Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint16_t getDataWordCount(); - inline void setDataWordCount( ::uint16_t value); - - inline ::uint16_t getPointerCount(); - inline void setPointerCount( ::uint16_t value); - - inline ::capnp::schema::ElementSize getPreferredListEncoding(); - inline void setPreferredListEncoding( ::capnp::schema::ElementSize value); - - inline bool getIsGroup(); - inline void setIsGroup(bool value); - - inline ::uint16_t getDiscriminantCount(); - inline void setDiscriminantCount( ::uint16_t value); - - inline ::uint32_t getDiscriminantOffset(); - inline void setDiscriminantOffset( ::uint32_t value); - - inline bool hasFields(); - inline ::capnp::List< ::capnp::schema::Field>::Builder getFields(); - inline void setFields( ::capnp::List< ::capnp::schema::Field>::Reader value); - inline ::capnp::List< ::capnp::schema::Field>::Builder initFields(unsigned int size); - inline void adoptFields(::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>> disownFields(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Struct::Pipeline { -public: - typedef Struct Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Enum::Reader { -public: - typedef Enum Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasEnumerants() const; - inline ::capnp::List< ::capnp::schema::Enumerant>::Reader getEnumerants() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Enum::Builder { -public: - typedef Enum Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasEnumerants(); - inline ::capnp::List< ::capnp::schema::Enumerant>::Builder getEnumerants(); - inline void setEnumerants( ::capnp::List< ::capnp::schema::Enumerant>::Reader value); - inline ::capnp::List< ::capnp::schema::Enumerant>::Builder initEnumerants(unsigned int size); - inline void adoptEnumerants(::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>> disownEnumerants(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Enum::Pipeline { -public: - typedef Enum Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Interface::Reader { -public: - typedef Interface Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasMethods() const; - inline ::capnp::List< ::capnp::schema::Method>::Reader getMethods() const; - - inline bool hasSuperclasses() const; - inline ::capnp::List< ::capnp::schema::Superclass>::Reader getSuperclasses() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Interface::Builder { -public: - typedef Interface Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasMethods(); - inline ::capnp::List< ::capnp::schema::Method>::Builder getMethods(); - inline void setMethods( ::capnp::List< ::capnp::schema::Method>::Reader value); - inline ::capnp::List< ::capnp::schema::Method>::Builder initMethods(unsigned int size); - inline void adoptMethods(::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>> disownMethods(); - - inline bool hasSuperclasses(); - inline ::capnp::List< ::capnp::schema::Superclass>::Builder getSuperclasses(); - inline void setSuperclasses( ::capnp::List< ::capnp::schema::Superclass>::Reader value); - inline ::capnp::List< ::capnp::schema::Superclass>::Builder initSuperclasses(unsigned int size); - inline void adoptSuperclasses(::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>> disownSuperclasses(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Interface::Pipeline { -public: - typedef Interface Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Const::Reader { -public: - typedef Const Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasType() const; - inline ::capnp::schema::Type::Reader getType() const; - - inline bool hasValue() const; - inline ::capnp::schema::Value::Reader getValue() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Const::Builder { -public: - typedef Const Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasType(); - inline ::capnp::schema::Type::Builder getType(); - inline void setType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initType(); - inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); - - inline bool hasValue(); - inline ::capnp::schema::Value::Builder getValue(); - inline void setValue( ::capnp::schema::Value::Reader value); - inline ::capnp::schema::Value::Builder initValue(); - inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); - inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Const::Pipeline { -public: - typedef Const Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Type::Pipeline getType(); - inline ::capnp::schema::Value::Pipeline getValue(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Annotation::Reader { -public: - typedef Annotation Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasType() const; - inline ::capnp::schema::Type::Reader getType() const; - - inline bool getTargetsFile() const; - - inline bool getTargetsConst() const; - - inline bool getTargetsEnum() const; - - inline bool getTargetsEnumerant() const; - - inline bool getTargetsStruct() const; - - inline bool getTargetsField() const; - - inline bool getTargetsUnion() const; - - inline bool getTargetsGroup() const; - - inline bool getTargetsInterface() const; - - inline bool getTargetsMethod() const; - - inline bool getTargetsParam() const; - - inline bool getTargetsAnnotation() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Annotation::Builder { -public: - typedef Annotation Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasType(); - inline ::capnp::schema::Type::Builder getType(); - inline void setType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initType(); - inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); - - inline bool getTargetsFile(); - inline void setTargetsFile(bool value); - - inline bool getTargetsConst(); - inline void setTargetsConst(bool value); - - inline bool getTargetsEnum(); - inline void setTargetsEnum(bool value); - - inline bool getTargetsEnumerant(); - inline void setTargetsEnumerant(bool value); - - inline bool getTargetsStruct(); - inline void setTargetsStruct(bool value); - - inline bool getTargetsField(); - inline void setTargetsField(bool value); - - inline bool getTargetsUnion(); - inline void setTargetsUnion(bool value); - - inline bool getTargetsGroup(); - inline void setTargetsGroup(bool value); - - inline bool getTargetsInterface(); - inline void setTargetsInterface(bool value); - - inline bool getTargetsMethod(); - inline void setTargetsMethod(bool value); - - inline bool getTargetsParam(); - inline void setTargetsParam(bool value); - - inline bool getTargetsAnnotation(); - inline void setTargetsAnnotation(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Annotation::Pipeline { -public: - typedef Annotation Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Type::Pipeline getType(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Field::Reader { -public: - typedef Field Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline ::uint16_t getCodeOrder() const; - - inline bool hasAnnotations() const; - inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; - - inline ::uint16_t getDiscriminantValue() const; - - inline bool isSlot() const; - inline typename Slot::Reader getSlot() const; - - inline bool isGroup() const; - inline typename Group::Reader getGroup() const; - - inline typename Ordinal::Reader getOrdinal() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Field::Builder { -public: - typedef Field Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline ::uint16_t getCodeOrder(); - inline void setCodeOrder( ::uint16_t value); - - inline bool hasAnnotations(); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); - inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); - inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); - - inline ::uint16_t getDiscriminantValue(); - inline void setDiscriminantValue( ::uint16_t value); - - inline bool isSlot(); - inline typename Slot::Builder getSlot(); - inline typename Slot::Builder initSlot(); - - inline bool isGroup(); - inline typename Group::Builder getGroup(); - inline typename Group::Builder initGroup(); - - inline typename Ordinal::Builder getOrdinal(); - inline typename Ordinal::Builder initOrdinal(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Field::Pipeline { -public: - typedef Field Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline typename Ordinal::Pipeline getOrdinal(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Field::Slot::Reader { -public: - typedef Slot Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getOffset() const; - - inline bool hasType() const; - inline ::capnp::schema::Type::Reader getType() const; - - inline bool hasDefaultValue() const; - inline ::capnp::schema::Value::Reader getDefaultValue() const; - - inline bool getHadExplicitDefault() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Field::Slot::Builder { -public: - typedef Slot Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getOffset(); - inline void setOffset( ::uint32_t value); - - inline bool hasType(); - inline ::capnp::schema::Type::Builder getType(); - inline void setType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initType(); - inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); - - inline bool hasDefaultValue(); - inline ::capnp::schema::Value::Builder getDefaultValue(); - inline void setDefaultValue( ::capnp::schema::Value::Reader value); - inline ::capnp::schema::Value::Builder initDefaultValue(); - inline void adoptDefaultValue(::capnp::Orphan< ::capnp::schema::Value>&& value); - inline ::capnp::Orphan< ::capnp::schema::Value> disownDefaultValue(); - - inline bool getHadExplicitDefault(); - inline void setHadExplicitDefault(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Field::Slot::Pipeline { -public: - typedef Slot Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Type::Pipeline getType(); - inline ::capnp::schema::Value::Pipeline getDefaultValue(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Field::Group::Reader { -public: - typedef Group Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Field::Group::Builder { -public: - typedef Group Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId(); - inline void setTypeId( ::uint64_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Field::Group::Pipeline { -public: - typedef Group Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Field::Ordinal::Reader { -public: - typedef Ordinal Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isImplicit() const; - inline ::capnp::Void getImplicit() const; - - inline bool isExplicit() const; - inline ::uint16_t getExplicit() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Field::Ordinal::Builder { -public: - typedef Ordinal Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isImplicit(); - inline ::capnp::Void getImplicit(); - inline void setImplicit( ::capnp::Void value = ::capnp::VOID); - - inline bool isExplicit(); - inline ::uint16_t getExplicit(); - inline void setExplicit( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Field::Ordinal::Pipeline { -public: - typedef Ordinal Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Enumerant::Reader { -public: - typedef Enumerant Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline ::uint16_t getCodeOrder() const; - - inline bool hasAnnotations() const; - inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Enumerant::Builder { -public: - typedef Enumerant Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline ::uint16_t getCodeOrder(); - inline void setCodeOrder( ::uint16_t value); - - inline bool hasAnnotations(); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); - inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); - inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Enumerant::Pipeline { -public: - typedef Enumerant Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Superclass::Reader { -public: - typedef Superclass Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getId() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Superclass::Builder { -public: - typedef Superclass Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Superclass::Pipeline { -public: - typedef Superclass Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Method::Reader { -public: - typedef Method Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline ::uint16_t getCodeOrder() const; - - inline ::uint64_t getParamStructType() const; - - inline ::uint64_t getResultStructType() const; - - inline bool hasAnnotations() const; - inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; - - inline bool hasParamBrand() const; - inline ::capnp::schema::Brand::Reader getParamBrand() const; - - inline bool hasResultBrand() const; - inline ::capnp::schema::Brand::Reader getResultBrand() const; - - inline bool hasImplicitParameters() const; - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader getImplicitParameters() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Method::Builder { -public: - typedef Method Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline ::uint16_t getCodeOrder(); - inline void setCodeOrder( ::uint16_t value); - - inline ::uint64_t getParamStructType(); - inline void setParamStructType( ::uint64_t value); - - inline ::uint64_t getResultStructType(); - inline void setResultStructType( ::uint64_t value); - - inline bool hasAnnotations(); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); - inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); - inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); - - inline bool hasParamBrand(); - inline ::capnp::schema::Brand::Builder getParamBrand(); - inline void setParamBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initParamBrand(); - inline void adoptParamBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownParamBrand(); - - inline bool hasResultBrand(); - inline ::capnp::schema::Brand::Builder getResultBrand(); - inline void setResultBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initResultBrand(); - inline void adoptResultBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownResultBrand(); - - inline bool hasImplicitParameters(); - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder getImplicitParameters(); - inline void setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value); - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder initImplicitParameters(unsigned int size); - inline void adoptImplicitParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> disownImplicitParameters(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Method::Pipeline { -public: - typedef Method Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getParamBrand(); - inline ::capnp::schema::Brand::Pipeline getResultBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::Reader { -public: - typedef Type Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isVoid() const; - inline ::capnp::Void getVoid() const; - - inline bool isBool() const; - inline ::capnp::Void getBool() const; - - inline bool isInt8() const; - inline ::capnp::Void getInt8() const; - - inline bool isInt16() const; - inline ::capnp::Void getInt16() const; - - inline bool isInt32() const; - inline ::capnp::Void getInt32() const; - - inline bool isInt64() const; - inline ::capnp::Void getInt64() const; - - inline bool isUint8() const; - inline ::capnp::Void getUint8() const; - - inline bool isUint16() const; - inline ::capnp::Void getUint16() const; - - inline bool isUint32() const; - inline ::capnp::Void getUint32() const; - - inline bool isUint64() const; - inline ::capnp::Void getUint64() const; - - inline bool isFloat32() const; - inline ::capnp::Void getFloat32() const; - - inline bool isFloat64() const; - inline ::capnp::Void getFloat64() const; - - inline bool isText() const; - inline ::capnp::Void getText() const; - - inline bool isData() const; - inline ::capnp::Void getData() const; - - inline bool isList() const; - inline typename List::Reader getList() const; - - inline bool isEnum() const; - inline typename Enum::Reader getEnum() const; - - inline bool isStruct() const; - inline typename Struct::Reader getStruct() const; - - inline bool isInterface() const; - inline typename Interface::Reader getInterface() const; - - inline bool isAnyPointer() const; - inline typename AnyPointer::Reader getAnyPointer() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::Builder { -public: - typedef Type Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isVoid(); - inline ::capnp::Void getVoid(); - inline void setVoid( ::capnp::Void value = ::capnp::VOID); - - inline bool isBool(); - inline ::capnp::Void getBool(); - inline void setBool( ::capnp::Void value = ::capnp::VOID); - - inline bool isInt8(); - inline ::capnp::Void getInt8(); - inline void setInt8( ::capnp::Void value = ::capnp::VOID); - - inline bool isInt16(); - inline ::capnp::Void getInt16(); - inline void setInt16( ::capnp::Void value = ::capnp::VOID); - - inline bool isInt32(); - inline ::capnp::Void getInt32(); - inline void setInt32( ::capnp::Void value = ::capnp::VOID); - - inline bool isInt64(); - inline ::capnp::Void getInt64(); - inline void setInt64( ::capnp::Void value = ::capnp::VOID); - - inline bool isUint8(); - inline ::capnp::Void getUint8(); - inline void setUint8( ::capnp::Void value = ::capnp::VOID); - - inline bool isUint16(); - inline ::capnp::Void getUint16(); - inline void setUint16( ::capnp::Void value = ::capnp::VOID); - - inline bool isUint32(); - inline ::capnp::Void getUint32(); - inline void setUint32( ::capnp::Void value = ::capnp::VOID); - - inline bool isUint64(); - inline ::capnp::Void getUint64(); - inline void setUint64( ::capnp::Void value = ::capnp::VOID); - - inline bool isFloat32(); - inline ::capnp::Void getFloat32(); - inline void setFloat32( ::capnp::Void value = ::capnp::VOID); - - inline bool isFloat64(); - inline ::capnp::Void getFloat64(); - inline void setFloat64( ::capnp::Void value = ::capnp::VOID); - - inline bool isText(); - inline ::capnp::Void getText(); - inline void setText( ::capnp::Void value = ::capnp::VOID); - - inline bool isData(); - inline ::capnp::Void getData(); - inline void setData( ::capnp::Void value = ::capnp::VOID); - - inline bool isList(); - inline typename List::Builder getList(); - inline typename List::Builder initList(); - - inline bool isEnum(); - inline typename Enum::Builder getEnum(); - inline typename Enum::Builder initEnum(); - - inline bool isStruct(); - inline typename Struct::Builder getStruct(); - inline typename Struct::Builder initStruct(); - - inline bool isInterface(); - inline typename Interface::Builder getInterface(); - inline typename Interface::Builder initInterface(); - - inline bool isAnyPointer(); - inline typename AnyPointer::Builder getAnyPointer(); - inline typename AnyPointer::Builder initAnyPointer(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::Pipeline { -public: - typedef Type Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::List::Reader { -public: - typedef List Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasElementType() const; - inline ::capnp::schema::Type::Reader getElementType() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::List::Builder { -public: - typedef List Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasElementType(); - inline ::capnp::schema::Type::Builder getElementType(); - inline void setElementType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initElementType(); - inline void adoptElementType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownElementType(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::List::Pipeline { -public: - typedef List Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Type::Pipeline getElementType(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::Enum::Reader { -public: - typedef Enum Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::Enum::Builder { -public: - typedef Enum Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId(); - inline void setTypeId( ::uint64_t value); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::Enum::Pipeline { -public: - typedef Enum Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::Struct::Reader { -public: - typedef Struct Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::Struct::Builder { -public: - typedef Struct Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId(); - inline void setTypeId( ::uint64_t value); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::Struct::Pipeline { -public: - typedef Struct Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::Interface::Reader { -public: - typedef Interface Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::Interface::Builder { -public: - typedef Interface Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId(); - inline void setTypeId( ::uint64_t value); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::Interface::Pipeline { -public: - typedef Interface Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::AnyPointer::Reader { -public: - typedef AnyPointer Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isUnconstrained() const; - inline typename Unconstrained::Reader getUnconstrained() const; - - inline bool isParameter() const; - inline typename Parameter::Reader getParameter() const; - - inline bool isImplicitMethodParameter() const; - inline typename ImplicitMethodParameter::Reader getImplicitMethodParameter() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::AnyPointer::Builder { -public: - typedef AnyPointer Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isUnconstrained(); - inline typename Unconstrained::Builder getUnconstrained(); - inline typename Unconstrained::Builder initUnconstrained(); - - inline bool isParameter(); - inline typename Parameter::Builder getParameter(); - inline typename Parameter::Builder initParameter(); - - inline bool isImplicitMethodParameter(); - inline typename ImplicitMethodParameter::Builder getImplicitMethodParameter(); - inline typename ImplicitMethodParameter::Builder initImplicitMethodParameter(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::AnyPointer::Pipeline { -public: - typedef AnyPointer Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::AnyPointer::Unconstrained::Reader { -public: - typedef Unconstrained Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isAnyKind() const; - inline ::capnp::Void getAnyKind() const; - - inline bool isStruct() const; - inline ::capnp::Void getStruct() const; - - inline bool isList() const; - inline ::capnp::Void getList() const; - - inline bool isCapability() const; - inline ::capnp::Void getCapability() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::AnyPointer::Unconstrained::Builder { -public: - typedef Unconstrained Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isAnyKind(); - inline ::capnp::Void getAnyKind(); - inline void setAnyKind( ::capnp::Void value = ::capnp::VOID); - - inline bool isStruct(); - inline ::capnp::Void getStruct(); - inline void setStruct( ::capnp::Void value = ::capnp::VOID); - - inline bool isList(); - inline ::capnp::Void getList(); - inline void setList( ::capnp::Void value = ::capnp::VOID); - - inline bool isCapability(); - inline ::capnp::Void getCapability(); - inline void setCapability( ::capnp::Void value = ::capnp::VOID); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::AnyPointer::Unconstrained::Pipeline { -public: - typedef Unconstrained Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::AnyPointer::Parameter::Reader { -public: - typedef Parameter Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getScopeId() const; - - inline ::uint16_t getParameterIndex() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::AnyPointer::Parameter::Builder { -public: - typedef Parameter Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getScopeId(); - inline void setScopeId( ::uint64_t value); - - inline ::uint16_t getParameterIndex(); - inline void setParameterIndex( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::AnyPointer::Parameter::Pipeline { -public: - typedef Parameter Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::AnyPointer::ImplicitMethodParameter::Reader { -public: - typedef ImplicitMethodParameter Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint16_t getParameterIndex() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::AnyPointer::ImplicitMethodParameter::Builder { -public: - typedef ImplicitMethodParameter Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint16_t getParameterIndex(); - inline void setParameterIndex( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::AnyPointer::ImplicitMethodParameter::Pipeline { -public: - typedef ImplicitMethodParameter Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Brand::Reader { -public: - typedef Brand Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasScopes() const; - inline ::capnp::List< ::capnp::schema::Brand::Scope>::Reader getScopes() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Brand::Builder { -public: - typedef Brand Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasScopes(); - inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder getScopes(); - inline void setScopes( ::capnp::List< ::capnp::schema::Brand::Scope>::Reader value); - inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder initScopes(unsigned int size); - inline void adoptScopes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>> disownScopes(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Brand::Pipeline { -public: - typedef Brand Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Brand::Scope::Reader { -public: - typedef Scope Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline ::uint64_t getScopeId() const; - - inline bool isBind() const; - inline bool hasBind() const; - inline ::capnp::List< ::capnp::schema::Brand::Binding>::Reader getBind() const; - - inline bool isInherit() const; - inline ::capnp::Void getInherit() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Brand::Scope::Builder { -public: - typedef Scope Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline ::uint64_t getScopeId(); - inline void setScopeId( ::uint64_t value); - - inline bool isBind(); - inline bool hasBind(); - inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder getBind(); - inline void setBind( ::capnp::List< ::capnp::schema::Brand::Binding>::Reader value); - inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder initBind(unsigned int size); - inline void adoptBind(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>> disownBind(); - - inline bool isInherit(); - inline ::capnp::Void getInherit(); - inline void setInherit( ::capnp::Void value = ::capnp::VOID); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Brand::Scope::Pipeline { -public: - typedef Scope Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Brand::Binding::Reader { -public: - typedef Binding Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isUnbound() const; - inline ::capnp::Void getUnbound() const; - - inline bool isType() const; - inline bool hasType() const; - inline ::capnp::schema::Type::Reader getType() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Brand::Binding::Builder { -public: - typedef Binding Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isUnbound(); - inline ::capnp::Void getUnbound(); - inline void setUnbound( ::capnp::Void value = ::capnp::VOID); - - inline bool isType(); - inline bool hasType(); - inline ::capnp::schema::Type::Builder getType(); - inline void setType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initType(); - inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Brand::Binding::Pipeline { -public: - typedef Binding Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Value::Reader { -public: - typedef Value Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isVoid() const; - inline ::capnp::Void getVoid() const; - - inline bool isBool() const; - inline bool getBool() const; - - inline bool isInt8() const; - inline ::int8_t getInt8() const; - - inline bool isInt16() const; - inline ::int16_t getInt16() const; - - inline bool isInt32() const; - inline ::int32_t getInt32() const; - - inline bool isInt64() const; - inline ::int64_t getInt64() const; - - inline bool isUint8() const; - inline ::uint8_t getUint8() const; - - inline bool isUint16() const; - inline ::uint16_t getUint16() const; - - inline bool isUint32() const; - inline ::uint32_t getUint32() const; - - inline bool isUint64() const; - inline ::uint64_t getUint64() const; - - inline bool isFloat32() const; - inline float getFloat32() const; - - inline bool isFloat64() const; - inline double getFloat64() const; - - inline bool isText() const; - inline bool hasText() const; - inline ::capnp::Text::Reader getText() const; - - inline bool isData() const; - inline bool hasData() const; - inline ::capnp::Data::Reader getData() const; - - inline bool isList() const; - inline bool hasList() const; - inline ::capnp::AnyPointer::Reader getList() const; - - inline bool isEnum() const; - inline ::uint16_t getEnum() const; - - inline bool isStruct() const; - inline bool hasStruct() const; - inline ::capnp::AnyPointer::Reader getStruct() const; - - inline bool isInterface() const; - inline ::capnp::Void getInterface() const; - - inline bool isAnyPointer() const; - inline bool hasAnyPointer() const; - inline ::capnp::AnyPointer::Reader getAnyPointer() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Value::Builder { -public: - typedef Value Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isVoid(); - inline ::capnp::Void getVoid(); - inline void setVoid( ::capnp::Void value = ::capnp::VOID); - - inline bool isBool(); - inline bool getBool(); - inline void setBool(bool value); - - inline bool isInt8(); - inline ::int8_t getInt8(); - inline void setInt8( ::int8_t value); - - inline bool isInt16(); - inline ::int16_t getInt16(); - inline void setInt16( ::int16_t value); - - inline bool isInt32(); - inline ::int32_t getInt32(); - inline void setInt32( ::int32_t value); - - inline bool isInt64(); - inline ::int64_t getInt64(); - inline void setInt64( ::int64_t value); - - inline bool isUint8(); - inline ::uint8_t getUint8(); - inline void setUint8( ::uint8_t value); - - inline bool isUint16(); - inline ::uint16_t getUint16(); - inline void setUint16( ::uint16_t value); - - inline bool isUint32(); - inline ::uint32_t getUint32(); - inline void setUint32( ::uint32_t value); - - inline bool isUint64(); - inline ::uint64_t getUint64(); - inline void setUint64( ::uint64_t value); - - inline bool isFloat32(); - inline float getFloat32(); - inline void setFloat32(float value); - - inline bool isFloat64(); - inline double getFloat64(); - inline void setFloat64(double value); - - inline bool isText(); - inline bool hasText(); - inline ::capnp::Text::Builder getText(); - inline void setText( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initText(unsigned int size); - inline void adoptText(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownText(); - - inline bool isData(); - inline bool hasData(); - inline ::capnp::Data::Builder getData(); - inline void setData( ::capnp::Data::Reader value); - inline ::capnp::Data::Builder initData(unsigned int size); - inline void adoptData(::capnp::Orphan< ::capnp::Data>&& value); - inline ::capnp::Orphan< ::capnp::Data> disownData(); - - inline bool isList(); - inline bool hasList(); - inline ::capnp::AnyPointer::Builder getList(); - inline ::capnp::AnyPointer::Builder initList(); - - inline bool isEnum(); - inline ::uint16_t getEnum(); - inline void setEnum( ::uint16_t value); - - inline bool isStruct(); - inline bool hasStruct(); - inline ::capnp::AnyPointer::Builder getStruct(); - inline ::capnp::AnyPointer::Builder initStruct(); - - inline bool isInterface(); - inline ::capnp::Void getInterface(); - inline void setInterface( ::capnp::Void value = ::capnp::VOID); - - inline bool isAnyPointer(); - inline bool hasAnyPointer(); - inline ::capnp::AnyPointer::Builder getAnyPointer(); - inline ::capnp::AnyPointer::Builder initAnyPointer(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Value::Pipeline { -public: - typedef Value Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Annotation::Reader { -public: - typedef Annotation Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getId() const; - - inline bool hasValue() const; - inline ::capnp::schema::Value::Reader getValue() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Annotation::Builder { -public: - typedef Annotation Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasValue(); - inline ::capnp::schema::Value::Builder getValue(); - inline void setValue( ::capnp::schema::Value::Reader value); - inline ::capnp::schema::Value::Builder initValue(); - inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); - inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Annotation::Pipeline { -public: - typedef Annotation Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Value::Pipeline getValue(); - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CodeGeneratorRequest::Reader { -public: - typedef CodeGeneratorRequest Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline bool hasNodes() const; - inline ::capnp::List< ::capnp::schema::Node>::Reader getNodes() const; - - inline bool hasRequestedFiles() const; - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader getRequestedFiles() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CodeGeneratorRequest::Builder { -public: - typedef CodeGeneratorRequest Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasNodes(); - inline ::capnp::List< ::capnp::schema::Node>::Builder getNodes(); - inline void setNodes( ::capnp::List< ::capnp::schema::Node>::Reader value); - inline ::capnp::List< ::capnp::schema::Node>::Builder initNodes(unsigned int size); - inline void adoptNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>> disownNodes(); - - inline bool hasRequestedFiles(); - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder getRequestedFiles(); - inline void setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader value); - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder initRequestedFiles(unsigned int size); - inline void adoptRequestedFiles(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>> disownRequestedFiles(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CodeGeneratorRequest::Pipeline { -public: - typedef CodeGeneratorRequest Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CodeGeneratorRequest::RequestedFile::Reader { -public: - typedef RequestedFile Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getId() const; - - inline bool hasFilename() const; - inline ::capnp::Text::Reader getFilename() const; - - inline bool hasImports() const; - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader getImports() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CodeGeneratorRequest::RequestedFile::Builder { -public: - typedef RequestedFile Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasFilename(); - inline ::capnp::Text::Builder getFilename(); - inline void setFilename( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initFilename(unsigned int size); - inline void adoptFilename(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownFilename(); - - inline bool hasImports(); - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder getImports(); - inline void setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader value); - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder initImports(unsigned int size); - inline void adoptImports(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>> disownImports(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CodeGeneratorRequest::RequestedFile::Pipeline { -public: - typedef RequestedFile Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CodeGeneratorRequest::RequestedFile::Import::Reader { -public: - typedef Import Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getId() const; - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CodeGeneratorRequest::RequestedFile::Import::Builder { -public: - typedef Import Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CodeGeneratorRequest::RequestedFile::Import::Pipeline { -public: - typedef Import Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -inline ::capnp::schema::Node::Which Node::Reader::which() const { - return _reader.getDataField(6 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Node::Which Node::Builder::which() { - return _builder.getDataField(6 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Node::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Node::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Node::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Reader::hasDisplayName() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Builder::hasDisplayName() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Node::Reader::getDisplayName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Node::Builder::getDisplayName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Node::Builder::setDisplayName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Node::Builder::initDisplayName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Node::Builder::adoptDisplayName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Node::Builder::disownDisplayName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint32_t Node::Reader::getDisplayNamePrefixLength() const { - return _reader.getDataField< ::uint32_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Node::Builder::getDisplayNamePrefixLength() { - return _builder.getDataField< ::uint32_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Node::Builder::setDisplayNamePrefixLength( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Node::Reader::getScopeId() const { - return _reader.getDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Node::Builder::getScopeId() { - return _builder.getDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Node::Builder::setScopeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Reader::hasNestedNodes() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Builder::hasNestedNodes() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader Node::Reader::getNestedNodes() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder Node::Builder::getNestedNodes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void Node::Builder::setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder Node::Builder::initNestedNodes(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::init( - _builder.getPointerField(1 * ::capnp::POINTERS), size); -} -inline void Node::Builder::adoptNestedNodes( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>> Node::Builder::disownNestedNodes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline bool Node::Reader::hasAnnotations() const { - return !_reader.getPointerField(2 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Builder::hasAnnotations() { - return !_builder.getPointerField(2 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Reader Node::Reader::getAnnotations() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( - _reader.getPointerField(2 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Node::Builder::getAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} -inline void Node::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set( - _builder.getPointerField(2 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Node::Builder::initAnnotations(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init( - _builder.getPointerField(2 * ::capnp::POINTERS), size); -} -inline void Node::Builder::adoptAnnotations( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt( - _builder.getPointerField(2 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Node::Builder::disownAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} - -inline bool Node::Reader::isFile() const { - return which() == Node::FILE; -} -inline bool Node::Builder::isFile() { - return which() == Node::FILE; -} -inline ::capnp::Void Node::Reader::getFile() const { - KJ_IREQUIRE((which() == Node::FILE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Node::Builder::getFile() { - KJ_IREQUIRE((which() == Node::FILE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Node::Builder::setFile( ::capnp::Void value) { - _builder.setDataField( - 6 * ::capnp::ELEMENTS, Node::FILE); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Reader::isStruct() const { - return which() == Node::STRUCT; -} -inline bool Node::Builder::isStruct() { - return which() == Node::STRUCT; -} -inline typename Node::Struct::Reader Node::Reader::getStruct() const { - KJ_IREQUIRE((which() == Node::STRUCT), - "Must check which() before get()ing a union member."); - return typename Node::Struct::Reader(_reader); -} -inline typename Node::Struct::Builder Node::Builder::getStruct() { - KJ_IREQUIRE((which() == Node::STRUCT), - "Must check which() before get()ing a union member."); - return typename Node::Struct::Builder(_builder); -} -inline typename Node::Struct::Builder Node::Builder::initStruct() { - _builder.setDataField( - 6 * ::capnp::ELEMENTS, Node::STRUCT); - _builder.setDataField< ::uint16_t>(7 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(12 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(13 * ::capnp::ELEMENTS, 0); - _builder.setDataField(224 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(15 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint32_t>(8 * ::capnp::ELEMENTS, 0); - _builder.getPointerField(3 * ::capnp::POINTERS).clear(); - return typename Node::Struct::Builder(_builder); -} -inline bool Node::Reader::isEnum() const { - return which() == Node::ENUM; -} -inline bool Node::Builder::isEnum() { - return which() == Node::ENUM; -} -inline typename Node::Enum::Reader Node::Reader::getEnum() const { - KJ_IREQUIRE((which() == Node::ENUM), - "Must check which() before get()ing a union member."); - return typename Node::Enum::Reader(_reader); -} -inline typename Node::Enum::Builder Node::Builder::getEnum() { - KJ_IREQUIRE((which() == Node::ENUM), - "Must check which() before get()ing a union member."); - return typename Node::Enum::Builder(_builder); -} -inline typename Node::Enum::Builder Node::Builder::initEnum() { - _builder.setDataField( - 6 * ::capnp::ELEMENTS, Node::ENUM); - _builder.getPointerField(3 * ::capnp::POINTERS).clear(); - return typename Node::Enum::Builder(_builder); -} -inline bool Node::Reader::isInterface() const { - return which() == Node::INTERFACE; -} -inline bool Node::Builder::isInterface() { - return which() == Node::INTERFACE; -} -inline typename Node::Interface::Reader Node::Reader::getInterface() const { - KJ_IREQUIRE((which() == Node::INTERFACE), - "Must check which() before get()ing a union member."); - return typename Node::Interface::Reader(_reader); -} -inline typename Node::Interface::Builder Node::Builder::getInterface() { - KJ_IREQUIRE((which() == Node::INTERFACE), - "Must check which() before get()ing a union member."); - return typename Node::Interface::Builder(_builder); -} -inline typename Node::Interface::Builder Node::Builder::initInterface() { - _builder.setDataField( - 6 * ::capnp::ELEMENTS, Node::INTERFACE); - _builder.getPointerField(3 * ::capnp::POINTERS).clear(); - _builder.getPointerField(4 * ::capnp::POINTERS).clear(); - return typename Node::Interface::Builder(_builder); -} -inline bool Node::Reader::isConst() const { - return which() == Node::CONST; -} -inline bool Node::Builder::isConst() { - return which() == Node::CONST; -} -inline typename Node::Const::Reader Node::Reader::getConst() const { - KJ_IREQUIRE((which() == Node::CONST), - "Must check which() before get()ing a union member."); - return typename Node::Const::Reader(_reader); -} -inline typename Node::Const::Builder Node::Builder::getConst() { - KJ_IREQUIRE((which() == Node::CONST), - "Must check which() before get()ing a union member."); - return typename Node::Const::Builder(_builder); -} -inline typename Node::Const::Builder Node::Builder::initConst() { - _builder.setDataField( - 6 * ::capnp::ELEMENTS, Node::CONST); - _builder.getPointerField(3 * ::capnp::POINTERS).clear(); - _builder.getPointerField(4 * ::capnp::POINTERS).clear(); - return typename Node::Const::Builder(_builder); -} -inline bool Node::Reader::isAnnotation() const { - return which() == Node::ANNOTATION; -} -inline bool Node::Builder::isAnnotation() { - return which() == Node::ANNOTATION; -} -inline typename Node::Annotation::Reader Node::Reader::getAnnotation() const { - KJ_IREQUIRE((which() == Node::ANNOTATION), - "Must check which() before get()ing a union member."); - return typename Node::Annotation::Reader(_reader); -} -inline typename Node::Annotation::Builder Node::Builder::getAnnotation() { - KJ_IREQUIRE((which() == Node::ANNOTATION), - "Must check which() before get()ing a union member."); - return typename Node::Annotation::Builder(_builder); -} -inline typename Node::Annotation::Builder Node::Builder::initAnnotation() { - _builder.setDataField( - 6 * ::capnp::ELEMENTS, Node::ANNOTATION); - _builder.setDataField(112 * ::capnp::ELEMENTS, 0); - _builder.setDataField(113 * ::capnp::ELEMENTS, 0); - _builder.setDataField(114 * ::capnp::ELEMENTS, 0); - _builder.setDataField(115 * ::capnp::ELEMENTS, 0); - _builder.setDataField(116 * ::capnp::ELEMENTS, 0); - _builder.setDataField(117 * ::capnp::ELEMENTS, 0); - _builder.setDataField(118 * ::capnp::ELEMENTS, 0); - _builder.setDataField(119 * ::capnp::ELEMENTS, 0); - _builder.setDataField(120 * ::capnp::ELEMENTS, 0); - _builder.setDataField(121 * ::capnp::ELEMENTS, 0); - _builder.setDataField(122 * ::capnp::ELEMENTS, 0); - _builder.setDataField(123 * ::capnp::ELEMENTS, 0); - _builder.getPointerField(3 * ::capnp::POINTERS).clear(); - return typename Node::Annotation::Builder(_builder); -} -inline bool Node::Reader::hasParameters() const { - return !_reader.getPointerField(5 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Builder::hasParameters() { - return !_builder.getPointerField(5 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader Node::Reader::getParameters() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get( - _reader.getPointerField(5 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Node::Builder::getParameters() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get( - _builder.getPointerField(5 * ::capnp::POINTERS)); -} -inline void Node::Builder::setParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::set( - _builder.getPointerField(5 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Node::Builder::initParameters(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::init( - _builder.getPointerField(5 * ::capnp::POINTERS), size); -} -inline void Node::Builder::adoptParameters( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::adopt( - _builder.getPointerField(5 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> Node::Builder::disownParameters() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::disown( - _builder.getPointerField(5 * ::capnp::POINTERS)); -} - -inline bool Node::Reader::getIsGeneric() const { - return _reader.getDataField( - 288 * ::capnp::ELEMENTS); -} - -inline bool Node::Builder::getIsGeneric() { - return _builder.getDataField( - 288 * ::capnp::ELEMENTS); -} -inline void Node::Builder::setIsGeneric(bool value) { - _builder.setDataField( - 288 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Parameter::Reader::hasName() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Parameter::Builder::hasName() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Node::Parameter::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Node::Parameter::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Node::Parameter::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Node::Parameter::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Node::Parameter::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Node::Parameter::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Node::NestedNode::Reader::hasName() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Node::NestedNode::Builder::hasName() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Node::NestedNode::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Node::NestedNode::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Node::NestedNode::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Node::NestedNode::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Node::NestedNode::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Node::NestedNode::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint64_t Node::NestedNode::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Node::NestedNode::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Node::NestedNode::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Node::Struct::Reader::getDataWordCount() const { - return _reader.getDataField< ::uint16_t>( - 7 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Node::Struct::Builder::getDataWordCount() { - return _builder.getDataField< ::uint16_t>( - 7 * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setDataWordCount( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 7 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Node::Struct::Reader::getPointerCount() const { - return _reader.getDataField< ::uint16_t>( - 12 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Node::Struct::Builder::getPointerCount() { - return _builder.getDataField< ::uint16_t>( - 12 * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setPointerCount( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 12 * ::capnp::ELEMENTS, value); -} - -inline ::capnp::schema::ElementSize Node::Struct::Reader::getPreferredListEncoding() const { - return _reader.getDataField< ::capnp::schema::ElementSize>( - 13 * ::capnp::ELEMENTS); -} - -inline ::capnp::schema::ElementSize Node::Struct::Builder::getPreferredListEncoding() { - return _builder.getDataField< ::capnp::schema::ElementSize>( - 13 * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setPreferredListEncoding( ::capnp::schema::ElementSize value) { - _builder.setDataField< ::capnp::schema::ElementSize>( - 13 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Struct::Reader::getIsGroup() const { - return _reader.getDataField( - 224 * ::capnp::ELEMENTS); -} - -inline bool Node::Struct::Builder::getIsGroup() { - return _builder.getDataField( - 224 * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setIsGroup(bool value) { - _builder.setDataField( - 224 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Node::Struct::Reader::getDiscriminantCount() const { - return _reader.getDataField< ::uint16_t>( - 15 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Node::Struct::Builder::getDiscriminantCount() { - return _builder.getDataField< ::uint16_t>( - 15 * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setDiscriminantCount( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 15 * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t Node::Struct::Reader::getDiscriminantOffset() const { - return _reader.getDataField< ::uint32_t>( - 8 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Node::Struct::Builder::getDiscriminantOffset() { - return _builder.getDataField< ::uint32_t>( - 8 * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setDiscriminantOffset( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 8 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Struct::Reader::hasFields() const { - return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Struct::Builder::hasFields() { - return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Field>::Reader Node::Struct::Reader::getFields() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::get( - _reader.getPointerField(3 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Field>::Builder Node::Struct::Builder::getFields() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::get( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -inline void Node::Struct::Builder::setFields( ::capnp::List< ::capnp::schema::Field>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::set( - _builder.getPointerField(3 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Field>::Builder Node::Struct::Builder::initFields(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::init( - _builder.getPointerField(3 * ::capnp::POINTERS), size); -} -inline void Node::Struct::Builder::adoptFields( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::adopt( - _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>> Node::Struct::Builder::disownFields() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::disown( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} - -inline bool Node::Enum::Reader::hasEnumerants() const { - return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Enum::Builder::hasEnumerants() { - return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Enumerant>::Reader Node::Enum::Reader::getEnumerants() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::get( - _reader.getPointerField(3 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Enumerant>::Builder Node::Enum::Builder::getEnumerants() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::get( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -inline void Node::Enum::Builder::setEnumerants( ::capnp::List< ::capnp::schema::Enumerant>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::set( - _builder.getPointerField(3 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Enumerant>::Builder Node::Enum::Builder::initEnumerants(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::init( - _builder.getPointerField(3 * ::capnp::POINTERS), size); -} -inline void Node::Enum::Builder::adoptEnumerants( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::adopt( - _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>> Node::Enum::Builder::disownEnumerants() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::disown( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} - -inline bool Node::Interface::Reader::hasMethods() const { - return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Interface::Builder::hasMethods() { - return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Method>::Reader Node::Interface::Reader::getMethods() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::get( - _reader.getPointerField(3 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Method>::Builder Node::Interface::Builder::getMethods() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::get( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -inline void Node::Interface::Builder::setMethods( ::capnp::List< ::capnp::schema::Method>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::set( - _builder.getPointerField(3 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Method>::Builder Node::Interface::Builder::initMethods(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::init( - _builder.getPointerField(3 * ::capnp::POINTERS), size); -} -inline void Node::Interface::Builder::adoptMethods( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::adopt( - _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>> Node::Interface::Builder::disownMethods() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::disown( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} - -inline bool Node::Interface::Reader::hasSuperclasses() const { - return !_reader.getPointerField(4 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Interface::Builder::hasSuperclasses() { - return !_builder.getPointerField(4 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Superclass>::Reader Node::Interface::Reader::getSuperclasses() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::get( - _reader.getPointerField(4 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Superclass>::Builder Node::Interface::Builder::getSuperclasses() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::get( - _builder.getPointerField(4 * ::capnp::POINTERS)); -} -inline void Node::Interface::Builder::setSuperclasses( ::capnp::List< ::capnp::schema::Superclass>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::set( - _builder.getPointerField(4 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Superclass>::Builder Node::Interface::Builder::initSuperclasses(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::init( - _builder.getPointerField(4 * ::capnp::POINTERS), size); -} -inline void Node::Interface::Builder::adoptSuperclasses( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::adopt( - _builder.getPointerField(4 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>> Node::Interface::Builder::disownSuperclasses() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::disown( - _builder.getPointerField(4 * ::capnp::POINTERS)); -} - -inline bool Node::Const::Reader::hasType() const { - return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Const::Builder::hasType() { - return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Node::Const::Reader::getType() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _reader.getPointerField(3 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Node::Const::Builder::getType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Type::Pipeline Node::Const::Pipeline::getType() { - return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); -} -#endif // !CAPNP_LITE -inline void Node::Const::Builder::setType( ::capnp::schema::Type::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( - _builder.getPointerField(3 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Node::Const::Builder::initType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -inline void Node::Const::Builder::adoptType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( - _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Node::Const::Builder::disownType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} - -inline bool Node::Const::Reader::hasValue() const { - return !_reader.getPointerField(4 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Const::Builder::hasValue() { - return !_builder.getPointerField(4 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Value::Reader Node::Const::Reader::getValue() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( - _reader.getPointerField(4 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Value::Builder Node::Const::Builder::getValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( - _builder.getPointerField(4 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Value::Pipeline Node::Const::Pipeline::getValue() { - return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(4)); -} -#endif // !CAPNP_LITE -inline void Node::Const::Builder::setValue( ::capnp::schema::Value::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set( - _builder.getPointerField(4 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Value::Builder Node::Const::Builder::initValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init( - _builder.getPointerField(4 * ::capnp::POINTERS)); -} -inline void Node::Const::Builder::adoptValue( - ::capnp::Orphan< ::capnp::schema::Value>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt( - _builder.getPointerField(4 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Value> Node::Const::Builder::disownValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown( - _builder.getPointerField(4 * ::capnp::POINTERS)); -} - -inline bool Node::Annotation::Reader::hasType() const { - return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline bool Node::Annotation::Builder::hasType() { - return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Node::Annotation::Reader::getType() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _reader.getPointerField(3 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Node::Annotation::Builder::getType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Type::Pipeline Node::Annotation::Pipeline::getType() { - return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); -} -#endif // !CAPNP_LITE -inline void Node::Annotation::Builder::setType( ::capnp::schema::Type::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( - _builder.getPointerField(3 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Node::Annotation::Builder::initType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -inline void Node::Annotation::Builder::adoptType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( - _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Node::Annotation::Builder::disownType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} - -inline bool Node::Annotation::Reader::getTargetsFile() const { - return _reader.getDataField( - 112 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsFile() { - return _builder.getDataField( - 112 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsFile(bool value) { - _builder.setDataField( - 112 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsConst() const { - return _reader.getDataField( - 113 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsConst() { - return _builder.getDataField( - 113 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsConst(bool value) { - _builder.setDataField( - 113 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsEnum() const { - return _reader.getDataField( - 114 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsEnum() { - return _builder.getDataField( - 114 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsEnum(bool value) { - _builder.setDataField( - 114 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsEnumerant() const { - return _reader.getDataField( - 115 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsEnumerant() { - return _builder.getDataField( - 115 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsEnumerant(bool value) { - _builder.setDataField( - 115 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsStruct() const { - return _reader.getDataField( - 116 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsStruct() { - return _builder.getDataField( - 116 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsStruct(bool value) { - _builder.setDataField( - 116 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsField() const { - return _reader.getDataField( - 117 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsField() { - return _builder.getDataField( - 117 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsField(bool value) { - _builder.setDataField( - 117 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsUnion() const { - return _reader.getDataField( - 118 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsUnion() { - return _builder.getDataField( - 118 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsUnion(bool value) { - _builder.setDataField( - 118 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsGroup() const { - return _reader.getDataField( - 119 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsGroup() { - return _builder.getDataField( - 119 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsGroup(bool value) { - _builder.setDataField( - 119 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsInterface() const { - return _reader.getDataField( - 120 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsInterface() { - return _builder.getDataField( - 120 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsInterface(bool value) { - _builder.setDataField( - 120 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsMethod() const { - return _reader.getDataField( - 121 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsMethod() { - return _builder.getDataField( - 121 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsMethod(bool value) { - _builder.setDataField( - 121 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsParam() const { - return _reader.getDataField( - 122 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsParam() { - return _builder.getDataField( - 122 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsParam(bool value) { - _builder.setDataField( - 122 * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsAnnotation() const { - return _reader.getDataField( - 123 * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsAnnotation() { - return _builder.getDataField( - 123 * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsAnnotation(bool value) { - _builder.setDataField( - 123 * ::capnp::ELEMENTS, value); -} - -inline ::capnp::schema::Field::Which Field::Reader::which() const { - return _reader.getDataField(4 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Field::Which Field::Builder::which() { - return _builder.getDataField(4 * ::capnp::ELEMENTS); -} - -inline bool Field::Reader::hasName() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Field::Builder::hasName() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Field::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Field::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Field::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Field::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Field::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Field::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint16_t Field::Reader::getCodeOrder() const { - return _reader.getDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Field::Builder::getCodeOrder() { - return _builder.getDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Field::Builder::setCodeOrder( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Field::Reader::hasAnnotations() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Field::Builder::hasAnnotations() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Reader Field::Reader::getAnnotations() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Field::Builder::getAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void Field::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Field::Builder::initAnnotations(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init( - _builder.getPointerField(1 * ::capnp::POINTERS), size); -} -inline void Field::Builder::adoptAnnotations( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Field::Builder::disownAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline ::uint16_t Field::Reader::getDiscriminantValue() const { - return _reader.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS, 65535u); -} - -inline ::uint16_t Field::Builder::getDiscriminantValue() { - return _builder.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS, 65535u); -} -inline void Field::Builder::setDiscriminantValue( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS, value, 65535u); -} - -inline bool Field::Reader::isSlot() const { - return which() == Field::SLOT; -} -inline bool Field::Builder::isSlot() { - return which() == Field::SLOT; -} -inline typename Field::Slot::Reader Field::Reader::getSlot() const { - KJ_IREQUIRE((which() == Field::SLOT), - "Must check which() before get()ing a union member."); - return typename Field::Slot::Reader(_reader); -} -inline typename Field::Slot::Builder Field::Builder::getSlot() { - KJ_IREQUIRE((which() == Field::SLOT), - "Must check which() before get()ing a union member."); - return typename Field::Slot::Builder(_builder); -} -inline typename Field::Slot::Builder Field::Builder::initSlot() { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Field::SLOT); - _builder.setDataField< ::uint32_t>(1 * ::capnp::ELEMENTS, 0); - _builder.setDataField(128 * ::capnp::ELEMENTS, 0); - _builder.getPointerField(2 * ::capnp::POINTERS).clear(); - _builder.getPointerField(3 * ::capnp::POINTERS).clear(); - return typename Field::Slot::Builder(_builder); -} -inline bool Field::Reader::isGroup() const { - return which() == Field::GROUP; -} -inline bool Field::Builder::isGroup() { - return which() == Field::GROUP; -} -inline typename Field::Group::Reader Field::Reader::getGroup() const { - KJ_IREQUIRE((which() == Field::GROUP), - "Must check which() before get()ing a union member."); - return typename Field::Group::Reader(_reader); -} -inline typename Field::Group::Builder Field::Builder::getGroup() { - KJ_IREQUIRE((which() == Field::GROUP), - "Must check which() before get()ing a union member."); - return typename Field::Group::Builder(_builder); -} -inline typename Field::Group::Builder Field::Builder::initGroup() { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Field::GROUP); - _builder.setDataField< ::uint64_t>(2 * ::capnp::ELEMENTS, 0); - return typename Field::Group::Builder(_builder); -} -inline typename Field::Ordinal::Reader Field::Reader::getOrdinal() const { - return typename Field::Ordinal::Reader(_reader); -} -inline typename Field::Ordinal::Builder Field::Builder::getOrdinal() { - return typename Field::Ordinal::Builder(_builder); -} -#if !CAPNP_LITE -inline typename Field::Ordinal::Pipeline Field::Pipeline::getOrdinal() { - return typename Field::Ordinal::Pipeline(_typeless.noop()); -} -#endif // !CAPNP_LITE -inline typename Field::Ordinal::Builder Field::Builder::initOrdinal() { - _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(6 * ::capnp::ELEMENTS, 0); - return typename Field::Ordinal::Builder(_builder); -} -inline ::uint32_t Field::Slot::Reader::getOffset() const { - return _reader.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Field::Slot::Builder::getOffset() { - return _builder.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Field::Slot::Builder::setOffset( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Field::Slot::Reader::hasType() const { - return !_reader.getPointerField(2 * ::capnp::POINTERS).isNull(); -} -inline bool Field::Slot::Builder::hasType() { - return !_builder.getPointerField(2 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Field::Slot::Reader::getType() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _reader.getPointerField(2 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Field::Slot::Builder::getType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Type::Pipeline Field::Slot::Pipeline::getType() { - return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(2)); -} -#endif // !CAPNP_LITE -inline void Field::Slot::Builder::setType( ::capnp::schema::Type::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( - _builder.getPointerField(2 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Field::Slot::Builder::initType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} -inline void Field::Slot::Builder::adoptType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( - _builder.getPointerField(2 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Field::Slot::Builder::disownType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} - -inline bool Field::Slot::Reader::hasDefaultValue() const { - return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline bool Field::Slot::Builder::hasDefaultValue() { - return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Value::Reader Field::Slot::Reader::getDefaultValue() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( - _reader.getPointerField(3 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Value::Builder Field::Slot::Builder::getDefaultValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Value::Pipeline Field::Slot::Pipeline::getDefaultValue() { - return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(3)); -} -#endif // !CAPNP_LITE -inline void Field::Slot::Builder::setDefaultValue( ::capnp::schema::Value::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set( - _builder.getPointerField(3 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Value::Builder Field::Slot::Builder::initDefaultValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -inline void Field::Slot::Builder::adoptDefaultValue( - ::capnp::Orphan< ::capnp::schema::Value>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt( - _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Value> Field::Slot::Builder::disownDefaultValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} - -inline bool Field::Slot::Reader::getHadExplicitDefault() const { - return _reader.getDataField( - 128 * ::capnp::ELEMENTS); -} - -inline bool Field::Slot::Builder::getHadExplicitDefault() { - return _builder.getDataField( - 128 * ::capnp::ELEMENTS); -} -inline void Field::Slot::Builder::setHadExplicitDefault(bool value) { - _builder.setDataField( - 128 * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Field::Group::Reader::getTypeId() const { - return _reader.getDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Field::Group::Builder::getTypeId() { - return _builder.getDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Field::Group::Builder::setTypeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Reader::which() const { - return _reader.getDataField(5 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Builder::which() { - return _builder.getDataField(5 * ::capnp::ELEMENTS); -} - -inline bool Field::Ordinal::Reader::isImplicit() const { - return which() == Field::Ordinal::IMPLICIT; -} -inline bool Field::Ordinal::Builder::isImplicit() { - return which() == Field::Ordinal::IMPLICIT; -} -inline ::capnp::Void Field::Ordinal::Reader::getImplicit() const { - KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Field::Ordinal::Builder::getImplicit() { - KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Field::Ordinal::Builder::setImplicit( ::capnp::Void value) { - _builder.setDataField( - 5 * ::capnp::ELEMENTS, Field::Ordinal::IMPLICIT); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Field::Ordinal::Reader::isExplicit() const { - return which() == Field::Ordinal::EXPLICIT; -} -inline bool Field::Ordinal::Builder::isExplicit() { - return which() == Field::Ordinal::EXPLICIT; -} -inline ::uint16_t Field::Ordinal::Reader::getExplicit() const { - KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint16_t>( - 6 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Field::Ordinal::Builder::getExplicit() { - KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint16_t>( - 6 * ::capnp::ELEMENTS); -} -inline void Field::Ordinal::Builder::setExplicit( ::uint16_t value) { - _builder.setDataField( - 5 * ::capnp::ELEMENTS, Field::Ordinal::EXPLICIT); - _builder.setDataField< ::uint16_t>( - 6 * ::capnp::ELEMENTS, value); -} - -inline bool Enumerant::Reader::hasName() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Enumerant::Builder::hasName() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Enumerant::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Enumerant::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Enumerant::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Enumerant::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Enumerant::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Enumerant::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint16_t Enumerant::Reader::getCodeOrder() const { - return _reader.getDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Enumerant::Builder::getCodeOrder() { - return _builder.getDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Enumerant::Builder::setCodeOrder( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Enumerant::Reader::hasAnnotations() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Enumerant::Builder::hasAnnotations() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Reader Enumerant::Reader::getAnnotations() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Enumerant::Builder::getAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void Enumerant::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Enumerant::Builder::initAnnotations(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init( - _builder.getPointerField(1 * ::capnp::POINTERS), size); -} -inline void Enumerant::Builder::adoptAnnotations( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Enumerant::Builder::disownAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline ::uint64_t Superclass::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Superclass::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Superclass::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Superclass::Reader::hasBrand() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Superclass::Builder::hasBrand() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Superclass::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Superclass::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Superclass::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Superclass::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Superclass::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Superclass::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Superclass::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Method::Reader::hasName() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasName() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Method::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Method::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Method::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Method::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Method::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Method::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint16_t Method::Reader::getCodeOrder() const { - return _reader.getDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Method::Builder::getCodeOrder() { - return _builder.getDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Method::Builder::setCodeOrder( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Method::Reader::getParamStructType() const { - return _reader.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Method::Builder::getParamStructType() { - return _builder.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Method::Builder::setParamStructType( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Method::Reader::getResultStructType() const { - return _reader.getDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Method::Builder::getResultStructType() { - return _builder.getDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Method::Builder::setResultStructType( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline bool Method::Reader::hasAnnotations() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasAnnotations() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Reader Method::Reader::getAnnotations() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Method::Builder::getAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void Method::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Method::Builder::initAnnotations(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init( - _builder.getPointerField(1 * ::capnp::POINTERS), size); -} -inline void Method::Builder::adoptAnnotations( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Method::Builder::disownAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline bool Method::Reader::hasParamBrand() const { - return !_reader.getPointerField(2 * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasParamBrand() { - return !_builder.getPointerField(2 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Method::Reader::getParamBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _reader.getPointerField(2 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Method::Builder::getParamBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getParamBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(2)); -} -#endif // !CAPNP_LITE -inline void Method::Builder::setParamBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( - _builder.getPointerField(2 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Method::Builder::initParamBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} -inline void Method::Builder::adoptParamBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( - _builder.getPointerField(2 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownParamBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( - _builder.getPointerField(2 * ::capnp::POINTERS)); -} - -inline bool Method::Reader::hasResultBrand() const { - return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasResultBrand() { - return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Method::Reader::getResultBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _reader.getPointerField(3 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Method::Builder::getResultBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getResultBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(3)); -} -#endif // !CAPNP_LITE -inline void Method::Builder::setResultBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( - _builder.getPointerField(3 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Method::Builder::initResultBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} -inline void Method::Builder::adoptResultBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( - _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownResultBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( - _builder.getPointerField(3 * ::capnp::POINTERS)); -} - -inline bool Method::Reader::hasImplicitParameters() const { - return !_reader.getPointerField(4 * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasImplicitParameters() { - return !_builder.getPointerField(4 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader Method::Reader::getImplicitParameters() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get( - _reader.getPointerField(4 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Method::Builder::getImplicitParameters() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get( - _builder.getPointerField(4 * ::capnp::POINTERS)); -} -inline void Method::Builder::setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::set( - _builder.getPointerField(4 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Method::Builder::initImplicitParameters(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::init( - _builder.getPointerField(4 * ::capnp::POINTERS), size); -} -inline void Method::Builder::adoptImplicitParameters( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::adopt( - _builder.getPointerField(4 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> Method::Builder::disownImplicitParameters() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::disown( - _builder.getPointerField(4 * ::capnp::POINTERS)); -} - -inline ::capnp::schema::Type::Which Type::Reader::which() const { - return _reader.getDataField(0 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Type::Which Type::Builder::which() { - return _builder.getDataField(0 * ::capnp::ELEMENTS); -} - -inline bool Type::Reader::isVoid() const { - return which() == Type::VOID; -} -inline bool Type::Builder::isVoid() { - return which() == Type::VOID; -} -inline ::capnp::Void Type::Reader::getVoid() const { - KJ_IREQUIRE((which() == Type::VOID), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getVoid() { - KJ_IREQUIRE((which() == Type::VOID), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setVoid( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::VOID); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isBool() const { - return which() == Type::BOOL; -} -inline bool Type::Builder::isBool() { - return which() == Type::BOOL; -} -inline ::capnp::Void Type::Reader::getBool() const { - KJ_IREQUIRE((which() == Type::BOOL), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getBool() { - KJ_IREQUIRE((which() == Type::BOOL), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setBool( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::BOOL); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isInt8() const { - return which() == Type::INT8; -} -inline bool Type::Builder::isInt8() { - return which() == Type::INT8; -} -inline ::capnp::Void Type::Reader::getInt8() const { - KJ_IREQUIRE((which() == Type::INT8), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getInt8() { - KJ_IREQUIRE((which() == Type::INT8), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setInt8( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::INT8); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isInt16() const { - return which() == Type::INT16; -} -inline bool Type::Builder::isInt16() { - return which() == Type::INT16; -} -inline ::capnp::Void Type::Reader::getInt16() const { - KJ_IREQUIRE((which() == Type::INT16), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getInt16() { - KJ_IREQUIRE((which() == Type::INT16), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setInt16( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::INT16); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isInt32() const { - return which() == Type::INT32; -} -inline bool Type::Builder::isInt32() { - return which() == Type::INT32; -} -inline ::capnp::Void Type::Reader::getInt32() const { - KJ_IREQUIRE((which() == Type::INT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getInt32() { - KJ_IREQUIRE((which() == Type::INT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setInt32( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::INT32); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isInt64() const { - return which() == Type::INT64; -} -inline bool Type::Builder::isInt64() { - return which() == Type::INT64; -} -inline ::capnp::Void Type::Reader::getInt64() const { - KJ_IREQUIRE((which() == Type::INT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getInt64() { - KJ_IREQUIRE((which() == Type::INT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setInt64( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::INT64); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isUint8() const { - return which() == Type::UINT8; -} -inline bool Type::Builder::isUint8() { - return which() == Type::UINT8; -} -inline ::capnp::Void Type::Reader::getUint8() const { - KJ_IREQUIRE((which() == Type::UINT8), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getUint8() { - KJ_IREQUIRE((which() == Type::UINT8), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setUint8( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::UINT8); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isUint16() const { - return which() == Type::UINT16; -} -inline bool Type::Builder::isUint16() { - return which() == Type::UINT16; -} -inline ::capnp::Void Type::Reader::getUint16() const { - KJ_IREQUIRE((which() == Type::UINT16), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getUint16() { - KJ_IREQUIRE((which() == Type::UINT16), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setUint16( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::UINT16); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isUint32() const { - return which() == Type::UINT32; -} -inline bool Type::Builder::isUint32() { - return which() == Type::UINT32; -} -inline ::capnp::Void Type::Reader::getUint32() const { - KJ_IREQUIRE((which() == Type::UINT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getUint32() { - KJ_IREQUIRE((which() == Type::UINT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setUint32( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::UINT32); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isUint64() const { - return which() == Type::UINT64; -} -inline bool Type::Builder::isUint64() { - return which() == Type::UINT64; -} -inline ::capnp::Void Type::Reader::getUint64() const { - KJ_IREQUIRE((which() == Type::UINT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getUint64() { - KJ_IREQUIRE((which() == Type::UINT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setUint64( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::UINT64); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isFloat32() const { - return which() == Type::FLOAT32; -} -inline bool Type::Builder::isFloat32() { - return which() == Type::FLOAT32; -} -inline ::capnp::Void Type::Reader::getFloat32() const { - KJ_IREQUIRE((which() == Type::FLOAT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getFloat32() { - KJ_IREQUIRE((which() == Type::FLOAT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setFloat32( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::FLOAT32); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isFloat64() const { - return which() == Type::FLOAT64; -} -inline bool Type::Builder::isFloat64() { - return which() == Type::FLOAT64; -} -inline ::capnp::Void Type::Reader::getFloat64() const { - KJ_IREQUIRE((which() == Type::FLOAT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getFloat64() { - KJ_IREQUIRE((which() == Type::FLOAT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setFloat64( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::FLOAT64); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isText() const { - return which() == Type::TEXT; -} -inline bool Type::Builder::isText() { - return which() == Type::TEXT; -} -inline ::capnp::Void Type::Reader::getText() const { - KJ_IREQUIRE((which() == Type::TEXT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getText() { - KJ_IREQUIRE((which() == Type::TEXT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setText( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::TEXT); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isData() const { - return which() == Type::DATA; -} -inline bool Type::Builder::isData() { - return which() == Type::DATA; -} -inline ::capnp::Void Type::Reader::getData() const { - KJ_IREQUIRE((which() == Type::DATA), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getData() { - KJ_IREQUIRE((which() == Type::DATA), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::Builder::setData( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::DATA); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isList() const { - return which() == Type::LIST; -} -inline bool Type::Builder::isList() { - return which() == Type::LIST; -} -inline typename Type::List::Reader Type::Reader::getList() const { - KJ_IREQUIRE((which() == Type::LIST), - "Must check which() before get()ing a union member."); - return typename Type::List::Reader(_reader); -} -inline typename Type::List::Builder Type::Builder::getList() { - KJ_IREQUIRE((which() == Type::LIST), - "Must check which() before get()ing a union member."); - return typename Type::List::Builder(_builder); -} -inline typename Type::List::Builder Type::Builder::initList() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::LIST); - _builder.getPointerField(0 * ::capnp::POINTERS).clear(); - return typename Type::List::Builder(_builder); -} -inline bool Type::Reader::isEnum() const { - return which() == Type::ENUM; -} -inline bool Type::Builder::isEnum() { - return which() == Type::ENUM; -} -inline typename Type::Enum::Reader Type::Reader::getEnum() const { - KJ_IREQUIRE((which() == Type::ENUM), - "Must check which() before get()ing a union member."); - return typename Type::Enum::Reader(_reader); -} -inline typename Type::Enum::Builder Type::Builder::getEnum() { - KJ_IREQUIRE((which() == Type::ENUM), - "Must check which() before get()ing a union member."); - return typename Type::Enum::Builder(_builder); -} -inline typename Type::Enum::Builder Type::Builder::initEnum() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::ENUM); - _builder.setDataField< ::uint64_t>(1 * ::capnp::ELEMENTS, 0); - _builder.getPointerField(0 * ::capnp::POINTERS).clear(); - return typename Type::Enum::Builder(_builder); -} -inline bool Type::Reader::isStruct() const { - return which() == Type::STRUCT; -} -inline bool Type::Builder::isStruct() { - return which() == Type::STRUCT; -} -inline typename Type::Struct::Reader Type::Reader::getStruct() const { - KJ_IREQUIRE((which() == Type::STRUCT), - "Must check which() before get()ing a union member."); - return typename Type::Struct::Reader(_reader); -} -inline typename Type::Struct::Builder Type::Builder::getStruct() { - KJ_IREQUIRE((which() == Type::STRUCT), - "Must check which() before get()ing a union member."); - return typename Type::Struct::Builder(_builder); -} -inline typename Type::Struct::Builder Type::Builder::initStruct() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::STRUCT); - _builder.setDataField< ::uint64_t>(1 * ::capnp::ELEMENTS, 0); - _builder.getPointerField(0 * ::capnp::POINTERS).clear(); - return typename Type::Struct::Builder(_builder); -} -inline bool Type::Reader::isInterface() const { - return which() == Type::INTERFACE; -} -inline bool Type::Builder::isInterface() { - return which() == Type::INTERFACE; -} -inline typename Type::Interface::Reader Type::Reader::getInterface() const { - KJ_IREQUIRE((which() == Type::INTERFACE), - "Must check which() before get()ing a union member."); - return typename Type::Interface::Reader(_reader); -} -inline typename Type::Interface::Builder Type::Builder::getInterface() { - KJ_IREQUIRE((which() == Type::INTERFACE), - "Must check which() before get()ing a union member."); - return typename Type::Interface::Builder(_builder); -} -inline typename Type::Interface::Builder Type::Builder::initInterface() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::INTERFACE); - _builder.setDataField< ::uint64_t>(1 * ::capnp::ELEMENTS, 0); - _builder.getPointerField(0 * ::capnp::POINTERS).clear(); - return typename Type::Interface::Builder(_builder); -} -inline bool Type::Reader::isAnyPointer() const { - return which() == Type::ANY_POINTER; -} -inline bool Type::Builder::isAnyPointer() { - return which() == Type::ANY_POINTER; -} -inline typename Type::AnyPointer::Reader Type::Reader::getAnyPointer() const { - KJ_IREQUIRE((which() == Type::ANY_POINTER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Reader(_reader); -} -inline typename Type::AnyPointer::Builder Type::Builder::getAnyPointer() { - KJ_IREQUIRE((which() == Type::ANY_POINTER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Builder(_builder); -} -inline typename Type::AnyPointer::Builder Type::Builder::initAnyPointer() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Type::ANY_POINTER); - _builder.setDataField< ::uint16_t>(4 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint64_t>(2 * ::capnp::ELEMENTS, 0); - return typename Type::AnyPointer::Builder(_builder); -} -inline bool Type::List::Reader::hasElementType() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Type::List::Builder::hasElementType() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Type::List::Reader::getElementType() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Type::List::Builder::getElementType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Type::Pipeline Type::List::Pipeline::getElementType() { - return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Type::List::Builder::setElementType( ::capnp::schema::Type::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Type::List::Builder::initElementType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Type::List::Builder::adoptElementType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Type::List::Builder::disownElementType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint64_t Type::Enum::Reader::getTypeId() const { - return _reader.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Type::Enum::Builder::getTypeId() { - return _builder.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Type::Enum::Builder::setTypeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Enum::Reader::hasBrand() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Type::Enum::Builder::hasBrand() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Type::Enum::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Type::Enum::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Type::Enum::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Type::Enum::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Type::Enum::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Type::Enum::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Enum::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint64_t Type::Struct::Reader::getTypeId() const { - return _reader.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Type::Struct::Builder::getTypeId() { - return _builder.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Type::Struct::Builder::setTypeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Struct::Reader::hasBrand() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Type::Struct::Builder::hasBrand() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Type::Struct::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Type::Struct::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Type::Struct::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Type::Struct::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Type::Struct::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Type::Struct::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Struct::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::uint64_t Type::Interface::Reader::getTypeId() const { - return _reader.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Type::Interface::Builder::getTypeId() { - return _builder.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Type::Interface::Builder::setTypeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Type::Interface::Reader::hasBrand() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Type::Interface::Builder::hasBrand() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Type::Interface::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Type::Interface::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Type::Interface::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Type::Interface::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Type::Interface::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Type::Interface::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Interface::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Reader::which() const { - return _reader.getDataField(4 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Builder::which() { - return _builder.getDataField(4 * ::capnp::ELEMENTS); -} - -inline bool Type::AnyPointer::Reader::isUnconstrained() const { - return which() == Type::AnyPointer::UNCONSTRAINED; -} -inline bool Type::AnyPointer::Builder::isUnconstrained() { - return which() == Type::AnyPointer::UNCONSTRAINED; -} -inline typename Type::AnyPointer::Unconstrained::Reader Type::AnyPointer::Reader::getUnconstrained() const { - KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Unconstrained::Reader(_reader); -} -inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::getUnconstrained() { - KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Unconstrained::Builder(_builder); -} -inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::initUnconstrained() { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Type::AnyPointer::UNCONSTRAINED); - _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); - return typename Type::AnyPointer::Unconstrained::Builder(_builder); -} -inline bool Type::AnyPointer::Reader::isParameter() const { - return which() == Type::AnyPointer::PARAMETER; -} -inline bool Type::AnyPointer::Builder::isParameter() { - return which() == Type::AnyPointer::PARAMETER; -} -inline typename Type::AnyPointer::Parameter::Reader Type::AnyPointer::Reader::getParameter() const { - KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Parameter::Reader(_reader); -} -inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::getParameter() { - KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Parameter::Builder(_builder); -} -inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::initParameter() { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Type::AnyPointer::PARAMETER); - _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint64_t>(2 * ::capnp::ELEMENTS, 0); - return typename Type::AnyPointer::Parameter::Builder(_builder); -} -inline bool Type::AnyPointer::Reader::isImplicitMethodParameter() const { - return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; -} -inline bool Type::AnyPointer::Builder::isImplicitMethodParameter() { - return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; -} -inline typename Type::AnyPointer::ImplicitMethodParameter::Reader Type::AnyPointer::Reader::getImplicitMethodParameter() const { - KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::ImplicitMethodParameter::Reader(_reader); -} -inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::getImplicitMethodParameter() { - KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); -} -inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::initImplicitMethodParameter() { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Type::AnyPointer::IMPLICIT_METHOD_PARAMETER); - _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); - return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); -} -inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Reader::which() const { - return _reader.getDataField(5 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Builder::which() { - return _builder.getDataField(5 * ::capnp::ELEMENTS); -} - -inline bool Type::AnyPointer::Unconstrained::Reader::isAnyKind() const { - return which() == Type::AnyPointer::Unconstrained::ANY_KIND; -} -inline bool Type::AnyPointer::Unconstrained::Builder::isAnyKind() { - return which() == Type::AnyPointer::Unconstrained::ANY_KIND; -} -inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getAnyKind() const { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getAnyKind() { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Unconstrained::Builder::setAnyKind( ::capnp::Void value) { - _builder.setDataField( - 5 * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::ANY_KIND); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::AnyPointer::Unconstrained::Reader::isStruct() const { - return which() == Type::AnyPointer::Unconstrained::STRUCT; -} -inline bool Type::AnyPointer::Unconstrained::Builder::isStruct() { - return which() == Type::AnyPointer::Unconstrained::STRUCT; -} -inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getStruct() const { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getStruct() { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Unconstrained::Builder::setStruct( ::capnp::Void value) { - _builder.setDataField( - 5 * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::STRUCT); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::AnyPointer::Unconstrained::Reader::isList() const { - return which() == Type::AnyPointer::Unconstrained::LIST; -} -inline bool Type::AnyPointer::Unconstrained::Builder::isList() { - return which() == Type::AnyPointer::Unconstrained::LIST; -} -inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getList() const { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getList() { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Unconstrained::Builder::setList( ::capnp::Void value) { - _builder.setDataField( - 5 * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::LIST); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Type::AnyPointer::Unconstrained::Reader::isCapability() const { - return which() == Type::AnyPointer::Unconstrained::CAPABILITY; -} -inline bool Type::AnyPointer::Unconstrained::Builder::isCapability() { - return which() == Type::AnyPointer::Unconstrained::CAPABILITY; -} -inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getCapability() const { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getCapability() { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Unconstrained::Builder::setCapability( ::capnp::Void value) { - _builder.setDataField( - 5 * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::CAPABILITY); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Type::AnyPointer::Parameter::Reader::getScopeId() const { - return _reader.getDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Type::AnyPointer::Parameter::Builder::getScopeId() { - return _builder.getDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Parameter::Builder::setScopeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Type::AnyPointer::Parameter::Reader::getParameterIndex() const { - return _reader.getDataField< ::uint16_t>( - 5 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Type::AnyPointer::Parameter::Builder::getParameterIndex() { - return _builder.getDataField< ::uint16_t>( - 5 * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Parameter::Builder::setParameterIndex( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 5 * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Reader::getParameterIndex() const { - return _reader.getDataField< ::uint16_t>( - 5 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Builder::getParameterIndex() { - return _builder.getDataField< ::uint16_t>( - 5 * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::ImplicitMethodParameter::Builder::setParameterIndex( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - 5 * ::capnp::ELEMENTS, value); -} - -inline bool Brand::Reader::hasScopes() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Brand::Builder::hasScopes() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Brand::Scope>::Reader Brand::Reader::getScopes() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder Brand::Builder::getScopes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Brand::Builder::setScopes( ::capnp::List< ::capnp::schema::Brand::Scope>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder Brand::Builder::initScopes(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Brand::Builder::adoptScopes( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>> Brand::Builder::disownScopes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Reader::which() const { - return _reader.getDataField(4 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Builder::which() { - return _builder.getDataField(4 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Brand::Scope::Reader::getScopeId() const { - return _reader.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Brand::Scope::Builder::getScopeId() { - return _builder.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Brand::Scope::Builder::setScopeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Brand::Scope::Reader::isBind() const { - return which() == Brand::Scope::BIND; -} -inline bool Brand::Scope::Builder::isBind() { - return which() == Brand::Scope::BIND; -} -inline bool Brand::Scope::Reader::hasBind() const { - if (which() != Brand::Scope::BIND) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Brand::Scope::Builder::hasBind() { - if (which() != Brand::Scope::BIND) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Brand::Binding>::Reader Brand::Scope::Reader::getBind() const { - KJ_IREQUIRE((which() == Brand::Scope::BIND), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder Brand::Scope::Builder::getBind() { - KJ_IREQUIRE((which() == Brand::Scope::BIND), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Brand::Scope::Builder::setBind( ::capnp::List< ::capnp::schema::Brand::Binding>::Reader value) { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Brand::Scope::BIND); - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder Brand::Scope::Builder::initBind(unsigned int size) { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Brand::Scope::BIND); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Brand::Scope::Builder::adoptBind( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>>&& value) { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Brand::Scope::BIND); - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>> Brand::Scope::Builder::disownBind() { - KJ_IREQUIRE((which() == Brand::Scope::BIND), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Brand::Scope::Reader::isInherit() const { - return which() == Brand::Scope::INHERIT; -} -inline bool Brand::Scope::Builder::isInherit() { - return which() == Brand::Scope::INHERIT; -} -inline ::capnp::Void Brand::Scope::Reader::getInherit() const { - KJ_IREQUIRE((which() == Brand::Scope::INHERIT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Brand::Scope::Builder::getInherit() { - KJ_IREQUIRE((which() == Brand::Scope::INHERIT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Brand::Scope::Builder::setInherit( ::capnp::Void value) { - _builder.setDataField( - 4 * ::capnp::ELEMENTS, Brand::Scope::INHERIT); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Reader::which() const { - return _reader.getDataField(0 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Builder::which() { - return _builder.getDataField(0 * ::capnp::ELEMENTS); -} - -inline bool Brand::Binding::Reader::isUnbound() const { - return which() == Brand::Binding::UNBOUND; -} -inline bool Brand::Binding::Builder::isUnbound() { - return which() == Brand::Binding::UNBOUND; -} -inline ::capnp::Void Brand::Binding::Reader::getUnbound() const { - KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Brand::Binding::Builder::getUnbound() { - KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Brand::Binding::Builder::setUnbound( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Brand::Binding::UNBOUND); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Brand::Binding::Reader::isType() const { - return which() == Brand::Binding::TYPE; -} -inline bool Brand::Binding::Builder::isType() { - return which() == Brand::Binding::TYPE; -} -inline bool Brand::Binding::Reader::hasType() const { - if (which() != Brand::Binding::TYPE) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Brand::Binding::Builder::hasType() { - if (which() != Brand::Binding::TYPE) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Brand::Binding::Reader::getType() const { - KJ_IREQUIRE((which() == Brand::Binding::TYPE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Brand::Binding::Builder::getType() { - KJ_IREQUIRE((which() == Brand::Binding::TYPE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Brand::Binding::Builder::setType( ::capnp::schema::Type::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Brand::Binding::TYPE); - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Brand::Binding::Builder::initType() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Brand::Binding::TYPE); - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Brand::Binding::Builder::adoptType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Brand::Binding::TYPE); - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Brand::Binding::Builder::disownType() { - KJ_IREQUIRE((which() == Brand::Binding::TYPE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline ::capnp::schema::Value::Which Value::Reader::which() const { - return _reader.getDataField(0 * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Value::Which Value::Builder::which() { - return _builder.getDataField(0 * ::capnp::ELEMENTS); -} - -inline bool Value::Reader::isVoid() const { - return which() == Value::VOID; -} -inline bool Value::Builder::isVoid() { - return which() == Value::VOID; -} -inline ::capnp::Void Value::Reader::getVoid() const { - KJ_IREQUIRE((which() == Value::VOID), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Value::Builder::getVoid() { - KJ_IREQUIRE((which() == Value::VOID), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setVoid( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::VOID); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isBool() const { - return which() == Value::BOOL; -} -inline bool Value::Builder::isBool() { - return which() == Value::BOOL; -} -inline bool Value::Reader::getBool() const { - KJ_IREQUIRE((which() == Value::BOOL), - "Must check which() before get()ing a union member."); - return _reader.getDataField( - 16 * ::capnp::ELEMENTS); -} - -inline bool Value::Builder::getBool() { - KJ_IREQUIRE((which() == Value::BOOL), - "Must check which() before get()ing a union member."); - return _builder.getDataField( - 16 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setBool(bool value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::BOOL); - _builder.setDataField( - 16 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isInt8() const { - return which() == Value::INT8; -} -inline bool Value::Builder::isInt8() { - return which() == Value::INT8; -} -inline ::int8_t Value::Reader::getInt8() const { - KJ_IREQUIRE((which() == Value::INT8), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::int8_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::int8_t Value::Builder::getInt8() { - KJ_IREQUIRE((which() == Value::INT8), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::int8_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInt8( ::int8_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::INT8); - _builder.setDataField< ::int8_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isInt16() const { - return which() == Value::INT16; -} -inline bool Value::Builder::isInt16() { - return which() == Value::INT16; -} -inline ::int16_t Value::Reader::getInt16() const { - KJ_IREQUIRE((which() == Value::INT16), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::int16_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::int16_t Value::Builder::getInt16() { - KJ_IREQUIRE((which() == Value::INT16), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::int16_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInt16( ::int16_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::INT16); - _builder.setDataField< ::int16_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isInt32() const { - return which() == Value::INT32; -} -inline bool Value::Builder::isInt32() { - return which() == Value::INT32; -} -inline ::int32_t Value::Reader::getInt32() const { - KJ_IREQUIRE((which() == Value::INT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::int32_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::int32_t Value::Builder::getInt32() { - KJ_IREQUIRE((which() == Value::INT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::int32_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInt32( ::int32_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::INT32); - _builder.setDataField< ::int32_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isInt64() const { - return which() == Value::INT64; -} -inline bool Value::Builder::isInt64() { - return which() == Value::INT64; -} -inline ::int64_t Value::Reader::getInt64() const { - KJ_IREQUIRE((which() == Value::INT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::int64_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::int64_t Value::Builder::getInt64() { - KJ_IREQUIRE((which() == Value::INT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::int64_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInt64( ::int64_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::INT64); - _builder.setDataField< ::int64_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isUint8() const { - return which() == Value::UINT8; -} -inline bool Value::Builder::isUint8() { - return which() == Value::UINT8; -} -inline ::uint8_t Value::Reader::getUint8() const { - KJ_IREQUIRE((which() == Value::UINT8), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint8_t>( - 2 * ::capnp::ELEMENTS); -} - -inline ::uint8_t Value::Builder::getUint8() { - KJ_IREQUIRE((which() == Value::UINT8), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint8_t>( - 2 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setUint8( ::uint8_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::UINT8); - _builder.setDataField< ::uint8_t>( - 2 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isUint16() const { - return which() == Value::UINT16; -} -inline bool Value::Builder::isUint16() { - return which() == Value::UINT16; -} -inline ::uint16_t Value::Reader::getUint16() const { - KJ_IREQUIRE((which() == Value::UINT16), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Value::Builder::getUint16() { - KJ_IREQUIRE((which() == Value::UINT16), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setUint16( ::uint16_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::UINT16); - _builder.setDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isUint32() const { - return which() == Value::UINT32; -} -inline bool Value::Builder::isUint32() { - return which() == Value::UINT32; -} -inline ::uint32_t Value::Reader::getUint32() const { - KJ_IREQUIRE((which() == Value::UINT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint32_t Value::Builder::getUint32() { - KJ_IREQUIRE((which() == Value::UINT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setUint32( ::uint32_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::UINT32); - _builder.setDataField< ::uint32_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isUint64() const { - return which() == Value::UINT64; -} -inline bool Value::Builder::isUint64() { - return which() == Value::UINT64; -} -inline ::uint64_t Value::Reader::getUint64() const { - KJ_IREQUIRE((which() == Value::UINT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Value::Builder::getUint64() { - KJ_IREQUIRE((which() == Value::UINT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setUint64( ::uint64_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::UINT64); - _builder.setDataField< ::uint64_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isFloat32() const { - return which() == Value::FLOAT32; -} -inline bool Value::Builder::isFloat32() { - return which() == Value::FLOAT32; -} -inline float Value::Reader::getFloat32() const { - KJ_IREQUIRE((which() == Value::FLOAT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField( - 1 * ::capnp::ELEMENTS); -} - -inline float Value::Builder::getFloat32() { - KJ_IREQUIRE((which() == Value::FLOAT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setFloat32(float value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::FLOAT32); - _builder.setDataField( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isFloat64() const { - return which() == Value::FLOAT64; -} -inline bool Value::Builder::isFloat64() { - return which() == Value::FLOAT64; -} -inline double Value::Reader::getFloat64() const { - KJ_IREQUIRE((which() == Value::FLOAT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField( - 1 * ::capnp::ELEMENTS); -} - -inline double Value::Builder::getFloat64() { - KJ_IREQUIRE((which() == Value::FLOAT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setFloat64(double value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::FLOAT64); - _builder.setDataField( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isText() const { - return which() == Value::TEXT; -} -inline bool Value::Builder::isText() { - return which() == Value::TEXT; -} -inline bool Value::Reader::hasText() const { - if (which() != Value::TEXT) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasText() { - if (which() != Value::TEXT) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Value::Reader::getText() const { - KJ_IREQUIRE((which() == Value::TEXT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Value::Builder::getText() { - KJ_IREQUIRE((which() == Value::TEXT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Value::Builder::setText( ::capnp::Text::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::TEXT); - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Value::Builder::initText(unsigned int size) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::TEXT); - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Value::Builder::adoptText( - ::capnp::Orphan< ::capnp::Text>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::TEXT); - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Value::Builder::disownText() { - KJ_IREQUIRE((which() == Value::TEXT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Value::Reader::isData() const { - return which() == Value::DATA; -} -inline bool Value::Builder::isData() { - return which() == Value::DATA; -} -inline bool Value::Reader::hasData() const { - if (which() != Value::DATA) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasData() { - if (which() != Value::DATA) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Data::Reader Value::Reader::getData() const { - KJ_IREQUIRE((which() == Value::DATA), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Data>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Data::Builder Value::Builder::getData() { - KJ_IREQUIRE((which() == Value::DATA), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Data>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Value::Builder::setData( ::capnp::Data::Reader value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::DATA); - ::capnp::_::PointerHelpers< ::capnp::Data>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Data::Builder Value::Builder::initData(unsigned int size) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::DATA); - return ::capnp::_::PointerHelpers< ::capnp::Data>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void Value::Builder::adoptData( - ::capnp::Orphan< ::capnp::Data>&& value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::DATA); - ::capnp::_::PointerHelpers< ::capnp::Data>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Data> Value::Builder::disownData() { - KJ_IREQUIRE((which() == Value::DATA), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Data>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Value::Reader::isList() const { - return which() == Value::LIST; -} -inline bool Value::Builder::isList() { - return which() == Value::LIST; -} -inline bool Value::Reader::hasList() const { - if (which() != Value::LIST) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasList() { - if (which() != Value::LIST) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Value::Reader::getList() const { - KJ_IREQUIRE((which() == Value::LIST), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::getList() { - KJ_IREQUIRE((which() == Value::LIST), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::initList() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::LIST); - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Value::Reader::isEnum() const { - return which() == Value::ENUM; -} -inline bool Value::Builder::isEnum() { - return which() == Value::ENUM; -} -inline ::uint16_t Value::Reader::getEnum() const { - KJ_IREQUIRE((which() == Value::ENUM), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS); -} - -inline ::uint16_t Value::Builder::getEnum() { - KJ_IREQUIRE((which() == Value::ENUM), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setEnum( ::uint16_t value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::ENUM); - _builder.setDataField< ::uint16_t>( - 1 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isStruct() const { - return which() == Value::STRUCT; -} -inline bool Value::Builder::isStruct() { - return which() == Value::STRUCT; -} -inline bool Value::Reader::hasStruct() const { - if (which() != Value::STRUCT) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasStruct() { - if (which() != Value::STRUCT) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Value::Reader::getStruct() const { - KJ_IREQUIRE((which() == Value::STRUCT), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::getStruct() { - KJ_IREQUIRE((which() == Value::STRUCT), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::initStruct() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::STRUCT); - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Value::Reader::isInterface() const { - return which() == Value::INTERFACE; -} -inline bool Value::Builder::isInterface() { - return which() == Value::INTERFACE; -} -inline ::capnp::Void Value::Reader::getInterface() const { - KJ_IREQUIRE((which() == Value::INTERFACE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Value::Builder::getInterface() { - KJ_IREQUIRE((which() == Value::INTERFACE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInterface( ::capnp::Void value) { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::INTERFACE); - _builder.setDataField< ::capnp::Void>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isAnyPointer() const { - return which() == Value::ANY_POINTER; -} -inline bool Value::Builder::isAnyPointer() { - return which() == Value::ANY_POINTER; -} -inline bool Value::Reader::hasAnyPointer() const { - if (which() != Value::ANY_POINTER) return false; - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasAnyPointer() { - if (which() != Value::ANY_POINTER) return false; - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Value::Reader::getAnyPointer() const { - KJ_IREQUIRE((which() == Value::ANY_POINTER), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::getAnyPointer() { - KJ_IREQUIRE((which() == Value::ANY_POINTER), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::initAnyPointer() { - _builder.setDataField( - 0 * ::capnp::ELEMENTS, Value::ANY_POINTER); - auto result = ::capnp::AnyPointer::Builder( - _builder.getPointerField(0 * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint64_t Annotation::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint64_t Annotation::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} -inline void Annotation::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool Annotation::Reader::hasValue() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool Annotation::Builder::hasValue() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Value::Reader Annotation::Reader::getValue() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Value::Builder Annotation::Builder::getValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Value::Pipeline Annotation::Pipeline::getValue() { - return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Annotation::Builder::setValue( ::capnp::schema::Value::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Value::Builder Annotation::Builder::initValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void Annotation::Builder::adoptValue( - ::capnp::Orphan< ::capnp::schema::Value>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Value> Annotation::Builder::disownValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool Annotation::Reader::hasBrand() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool Annotation::Builder::hasBrand() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Annotation::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Annotation::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Annotation::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -inline void Annotation::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Annotation::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void Annotation::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Annotation::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline bool CodeGeneratorRequest::Reader::hasNodes() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::Builder::hasNodes() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Node>::Reader CodeGeneratorRequest::Reader::getNodes() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Node>::Builder CodeGeneratorRequest::Builder::getNodes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::Builder::setNodes( ::capnp::List< ::capnp::schema::Node>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Node>::Builder CodeGeneratorRequest::Builder::initNodes(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::Builder::adoptNodes( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>> CodeGeneratorRequest::Builder::disownNodes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool CodeGeneratorRequest::Reader::hasRequestedFiles() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::Builder::hasRequestedFiles() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader CodeGeneratorRequest::Reader::getRequestedFiles() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder CodeGeneratorRequest::Builder::getRequestedFiles() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::Builder::setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder CodeGeneratorRequest::Builder::initRequestedFiles(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::init( - _builder.getPointerField(1 * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::Builder::adoptRequestedFiles( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>> CodeGeneratorRequest::Builder::disownRequestedFiles() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline ::uint64_t CodeGeneratorRequest::RequestedFile::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint64_t CodeGeneratorRequest::RequestedFile::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool CodeGeneratorRequest::RequestedFile::Reader::hasFilename() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::RequestedFile::Builder::hasFilename() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Reader::getFilename() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::getFilename() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::setFilename( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::initFilename(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::adoptFilename( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Builder::disownFilename() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -inline bool CodeGeneratorRequest::RequestedFile::Reader::hasImports() const { - return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::RequestedFile::Builder::hasImports() { - return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader CodeGeneratorRequest::RequestedFile::Reader::getImports() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::get( - _reader.getPointerField(1 * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder CodeGeneratorRequest::RequestedFile::Builder::getImports() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::get( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::set( - _builder.getPointerField(1 * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder CodeGeneratorRequest::RequestedFile::Builder::initImports(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::init( - _builder.getPointerField(1 * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::adoptImports( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::adopt( - _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>> CodeGeneratorRequest::RequestedFile::Builder::disownImports() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::disown( - _builder.getPointerField(1 * ::capnp::POINTERS)); -} - -inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} - -inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS); -} -inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - 0 * ::capnp::ELEMENTS, value); -} - -inline bool CodeGeneratorRequest::RequestedFile::Import::Reader::hasName() const { - return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::RequestedFile::Import::Builder::hasName() { - return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Import::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _reader.getPointerField(0 * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set( - _builder.getPointerField(0 * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init( - _builder.getPointerField(0 * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::RequestedFile::Import::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( - _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Import::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( - _builder.getPointerField(0 * ::capnp::POINTERS)); -} - -} // namespace -} // namespace - -#endif // CAPNP_INCLUDED_a93fc509624c72d9_ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: schema.capnp + +#ifndef CAPNP_INCLUDED_a93fc509624c72d9_ +#define CAPNP_INCLUDED_a93fc509624c72d9_ + +#include + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(e682ab4cf923a417); +CAPNP_DECLARE_SCHEMA(b9521bccf10fa3b1); +CAPNP_DECLARE_SCHEMA(debf55bbfa0fc242); +CAPNP_DECLARE_SCHEMA(9ea0b19b37fb4435); +CAPNP_DECLARE_SCHEMA(b54ab3364333f598); +CAPNP_DECLARE_SCHEMA(e82753cff0c2218f); +CAPNP_DECLARE_SCHEMA(b18aa5ac7a0d9420); +CAPNP_DECLARE_SCHEMA(ec1619d4400a0290); +CAPNP_DECLARE_SCHEMA(9aad50a41f4af45f); +CAPNP_DECLARE_SCHEMA(97b14cbe7cfec712); +CAPNP_DECLARE_SCHEMA(c42305476bb4746f); +CAPNP_DECLARE_SCHEMA(cafccddb68db1d11); +CAPNP_DECLARE_SCHEMA(bb90d5c287870be6); +CAPNP_DECLARE_SCHEMA(978a7cebdc549a4d); +CAPNP_DECLARE_SCHEMA(a9962a9ed0a4d7f8); +CAPNP_DECLARE_SCHEMA(9500cce23b334d80); +CAPNP_DECLARE_SCHEMA(d07378ede1f9cc60); +CAPNP_DECLARE_SCHEMA(87e739250a60ea97); +CAPNP_DECLARE_SCHEMA(9e0e78711a7f87a9); +CAPNP_DECLARE_SCHEMA(ac3a6f60ef4cc6d3); +CAPNP_DECLARE_SCHEMA(ed8bca69f7fb0cbf); +CAPNP_DECLARE_SCHEMA(c2573fe8a23e49f1); +CAPNP_DECLARE_SCHEMA(8e3b5f79fe593656); +CAPNP_DECLARE_SCHEMA(9dd1f724f4614a85); +CAPNP_DECLARE_SCHEMA(baefc9120c56e274); +CAPNP_DECLARE_SCHEMA(903455f06065422b); +CAPNP_DECLARE_SCHEMA(abd73485a9636bc9); +CAPNP_DECLARE_SCHEMA(c863cd16969ee7fc); +CAPNP_DECLARE_SCHEMA(ce23dcd2d7b00c9b); +CAPNP_DECLARE_SCHEMA(f1c8950dab257542); +CAPNP_DECLARE_SCHEMA(d1958f7dba521926); +enum class ElementSize_d1958f7dba521926: uint16_t { + EMPTY, + BIT, + BYTE, + TWO_BYTES, + FOUR_BYTES, + EIGHT_BYTES, + POINTER, + INLINE_COMPOSITE, +}; +CAPNP_DECLARE_ENUM(ElementSize, d1958f7dba521926); +CAPNP_DECLARE_SCHEMA(d85d305b7d839963); +CAPNP_DECLARE_SCHEMA(bfc546f6210ad7ce); +CAPNP_DECLARE_SCHEMA(cfea0eb02e810062); +CAPNP_DECLARE_SCHEMA(ae504193122357e5); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace schema { + +struct Node { + Node() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + FILE, + STRUCT, + ENUM, + INTERFACE, + CONST, + ANNOTATION, + }; + struct Parameter; + struct NestedNode; + struct Struct; + struct Enum; + struct Interface; + struct Const; + struct Annotation; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(e682ab4cf923a417, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Parameter { + Parameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b9521bccf10fa3b1, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::NestedNode { + NestedNode() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(debf55bbfa0fc242, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Struct { + Struct() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9ea0b19b37fb4435, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Enum { + Enum() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b54ab3364333f598, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Interface { + Interface() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(e82753cff0c2218f, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Const { + Const() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b18aa5ac7a0d9420, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Annotation { + Annotation() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ec1619d4400a0290, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Field { + Field() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + SLOT, + GROUP, + }; + static constexpr ::uint16_t NO_DISCRIMINANT = 65535u; + struct Slot; + struct Group; + struct Ordinal; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9aad50a41f4af45f, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Field::Slot { + Slot() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c42305476bb4746f, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Field::Group { + Group() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(cafccddb68db1d11, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Field::Ordinal { + Ordinal() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + IMPLICIT, + EXPLICIT, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bb90d5c287870be6, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Enumerant { + Enumerant() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(978a7cebdc549a4d, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Superclass { + Superclass() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(a9962a9ed0a4d7f8, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Method { + Method() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9500cce23b334d80, 3, 5) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type { + Type() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + VOID, + BOOL, + INT8, + INT16, + INT32, + INT64, + UINT8, + UINT16, + UINT32, + UINT64, + FLOAT32, + FLOAT64, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + INTERFACE, + ANY_POINTER, + }; + struct List; + struct Enum; + struct Struct; + struct Interface; + struct AnyPointer; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d07378ede1f9cc60, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::List { + List() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(87e739250a60ea97, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::Enum { + Enum() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9e0e78711a7f87a9, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::Struct { + Struct() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ac3a6f60ef4cc6d3, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::Interface { + Interface() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ed8bca69f7fb0cbf, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer { + AnyPointer() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + UNCONSTRAINED, + PARAMETER, + IMPLICIT_METHOD_PARAMETER, + }; + struct Unconstrained; + struct Parameter; + struct ImplicitMethodParameter; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c2573fe8a23e49f1, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::Unconstrained { + Unconstrained() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + ANY_KIND, + STRUCT, + LIST, + CAPABILITY, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(8e3b5f79fe593656, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::Parameter { + Parameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9dd1f724f4614a85, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::ImplicitMethodParameter { + ImplicitMethodParameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(baefc9120c56e274, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Brand { + Brand() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Scope; + struct Binding; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(903455f06065422b, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Brand::Scope { + Scope() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + BIND, + INHERIT, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(abd73485a9636bc9, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Brand::Binding { + Binding() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + UNBOUND, + TYPE, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c863cd16969ee7fc, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Value { + Value() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + VOID, + BOOL, + INT8, + INT16, + INT32, + INT64, + UINT8, + UINT16, + UINT32, + UINT64, + FLOAT32, + FLOAT64, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + INTERFACE, + ANY_POINTER, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ce23dcd2d7b00c9b, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Annotation { + Annotation() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f1c8950dab257542, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +typedef ::capnp::schemas::ElementSize_d1958f7dba521926 ElementSize; + +struct CapnpVersion { + CapnpVersion() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d85d305b7d839963, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CodeGeneratorRequest { + CodeGeneratorRequest() = delete; + + class Reader; + class Builder; + class Pipeline; + struct RequestedFile; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bfc546f6210ad7ce, 0, 3) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CodeGeneratorRequest::RequestedFile { + RequestedFile() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Import; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(cfea0eb02e810062, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CodeGeneratorRequest::RequestedFile::Import { + Import() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ae504193122357e5, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class Node::Reader { +public: + typedef Node Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline ::uint64_t getId() const; + + inline bool hasDisplayName() const; + inline ::capnp::Text::Reader getDisplayName() const; + + inline ::uint32_t getDisplayNamePrefixLength() const; + + inline ::uint64_t getScopeId() const; + + inline bool hasNestedNodes() const; + inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader getNestedNodes() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; + + inline bool isFile() const; + inline ::capnp::Void getFile() const; + + inline bool isStruct() const; + inline typename Struct::Reader getStruct() const; + + inline bool isEnum() const; + inline typename Enum::Reader getEnum() const; + + inline bool isInterface() const; + inline typename Interface::Reader getInterface() const; + + inline bool isConst() const; + inline typename Const::Reader getConst() const; + + inline bool isAnnotation() const; + inline typename Annotation::Reader getAnnotation() const; + + inline bool hasParameters() const; + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader getParameters() const; + + inline bool getIsGeneric() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Builder { +public: + typedef Node Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasDisplayName(); + inline ::capnp::Text::Builder getDisplayName(); + inline void setDisplayName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initDisplayName(unsigned int size); + inline void adoptDisplayName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownDisplayName(); + + inline ::uint32_t getDisplayNamePrefixLength(); + inline void setDisplayNamePrefixLength( ::uint32_t value); + + inline ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline bool hasNestedNodes(); + inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder getNestedNodes(); + inline void setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder initNestedNodes(unsigned int size); + inline void adoptNestedNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>> disownNestedNodes(); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); + + inline bool isFile(); + inline ::capnp::Void getFile(); + inline void setFile( ::capnp::Void value = ::capnp::VOID); + + inline bool isStruct(); + inline typename Struct::Builder getStruct(); + inline typename Struct::Builder initStruct(); + + inline bool isEnum(); + inline typename Enum::Builder getEnum(); + inline typename Enum::Builder initEnum(); + + inline bool isInterface(); + inline typename Interface::Builder getInterface(); + inline typename Interface::Builder initInterface(); + + inline bool isConst(); + inline typename Const::Builder getConst(); + inline typename Const::Builder initConst(); + + inline bool isAnnotation(); + inline typename Annotation::Builder getAnnotation(); + inline typename Annotation::Builder initAnnotation(); + + inline bool hasParameters(); + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder getParameters(); + inline void setParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder initParameters(unsigned int size); + inline void adoptParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> disownParameters(); + + inline bool getIsGeneric(); + inline void setIsGeneric(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Pipeline { +public: + typedef Node Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Parameter::Reader { +public: + typedef Parameter Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Parameter::Builder { +public: + typedef Parameter Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Parameter::Pipeline { +public: + typedef Parameter Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::NestedNode::Reader { +public: + typedef NestedNode Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint64_t getId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::NestedNode::Builder { +public: + typedef NestedNode Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::NestedNode::Pipeline { +public: + typedef NestedNode Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Struct::Reader { +public: + typedef Struct Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint16_t getDataWordCount() const; + + inline ::uint16_t getPointerCount() const; + + inline ::capnp::schema::ElementSize getPreferredListEncoding() const; + + inline bool getIsGroup() const; + + inline ::uint16_t getDiscriminantCount() const; + + inline ::uint32_t getDiscriminantOffset() const; + + inline bool hasFields() const; + inline ::capnp::List< ::capnp::schema::Field>::Reader getFields() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Struct::Builder { +public: + typedef Struct Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint16_t getDataWordCount(); + inline void setDataWordCount( ::uint16_t value); + + inline ::uint16_t getPointerCount(); + inline void setPointerCount( ::uint16_t value); + + inline ::capnp::schema::ElementSize getPreferredListEncoding(); + inline void setPreferredListEncoding( ::capnp::schema::ElementSize value); + + inline bool getIsGroup(); + inline void setIsGroup(bool value); + + inline ::uint16_t getDiscriminantCount(); + inline void setDiscriminantCount( ::uint16_t value); + + inline ::uint32_t getDiscriminantOffset(); + inline void setDiscriminantOffset( ::uint32_t value); + + inline bool hasFields(); + inline ::capnp::List< ::capnp::schema::Field>::Builder getFields(); + inline void setFields( ::capnp::List< ::capnp::schema::Field>::Reader value); + inline ::capnp::List< ::capnp::schema::Field>::Builder initFields(unsigned int size); + inline void adoptFields(::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>> disownFields(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Struct::Pipeline { +public: + typedef Struct Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Enum::Reader { +public: + typedef Enum Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasEnumerants() const; + inline ::capnp::List< ::capnp::schema::Enumerant>::Reader getEnumerants() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Enum::Builder { +public: + typedef Enum Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasEnumerants(); + inline ::capnp::List< ::capnp::schema::Enumerant>::Builder getEnumerants(); + inline void setEnumerants( ::capnp::List< ::capnp::schema::Enumerant>::Reader value); + inline ::capnp::List< ::capnp::schema::Enumerant>::Builder initEnumerants(unsigned int size); + inline void adoptEnumerants(::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>> disownEnumerants(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Enum::Pipeline { +public: + typedef Enum Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Interface::Reader { +public: + typedef Interface Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasMethods() const; + inline ::capnp::List< ::capnp::schema::Method>::Reader getMethods() const; + + inline bool hasSuperclasses() const; + inline ::capnp::List< ::capnp::schema::Superclass>::Reader getSuperclasses() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Interface::Builder { +public: + typedef Interface Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasMethods(); + inline ::capnp::List< ::capnp::schema::Method>::Builder getMethods(); + inline void setMethods( ::capnp::List< ::capnp::schema::Method>::Reader value); + inline ::capnp::List< ::capnp::schema::Method>::Builder initMethods(unsigned int size); + inline void adoptMethods(::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>> disownMethods(); + + inline bool hasSuperclasses(); + inline ::capnp::List< ::capnp::schema::Superclass>::Builder getSuperclasses(); + inline void setSuperclasses( ::capnp::List< ::capnp::schema::Superclass>::Reader value); + inline ::capnp::List< ::capnp::schema::Superclass>::Builder initSuperclasses(unsigned int size); + inline void adoptSuperclasses(::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>> disownSuperclasses(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Interface::Pipeline { +public: + typedef Interface Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Const::Reader { +public: + typedef Const Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool hasValue() const; + inline ::capnp::schema::Value::Reader getValue() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Const::Builder { +public: + typedef Const Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool hasValue(); + inline ::capnp::schema::Value::Builder getValue(); + inline void setValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Const::Pipeline { +public: + typedef Const Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); + inline ::capnp::schema::Value::Pipeline getValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Annotation::Reader { +public: + typedef Annotation Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool getTargetsFile() const; + + inline bool getTargetsConst() const; + + inline bool getTargetsEnum() const; + + inline bool getTargetsEnumerant() const; + + inline bool getTargetsStruct() const; + + inline bool getTargetsField() const; + + inline bool getTargetsUnion() const; + + inline bool getTargetsGroup() const; + + inline bool getTargetsInterface() const; + + inline bool getTargetsMethod() const; + + inline bool getTargetsParam() const; + + inline bool getTargetsAnnotation() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Annotation::Builder { +public: + typedef Annotation Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool getTargetsFile(); + inline void setTargetsFile(bool value); + + inline bool getTargetsConst(); + inline void setTargetsConst(bool value); + + inline bool getTargetsEnum(); + inline void setTargetsEnum(bool value); + + inline bool getTargetsEnumerant(); + inline void setTargetsEnumerant(bool value); + + inline bool getTargetsStruct(); + inline void setTargetsStruct(bool value); + + inline bool getTargetsField(); + inline void setTargetsField(bool value); + + inline bool getTargetsUnion(); + inline void setTargetsUnion(bool value); + + inline bool getTargetsGroup(); + inline void setTargetsGroup(bool value); + + inline bool getTargetsInterface(); + inline void setTargetsInterface(bool value); + + inline bool getTargetsMethod(); + inline void setTargetsMethod(bool value); + + inline bool getTargetsParam(); + inline void setTargetsParam(bool value); + + inline bool getTargetsAnnotation(); + inline void setTargetsAnnotation(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Annotation::Pipeline { +public: + typedef Annotation Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Reader { +public: + typedef Field Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; + + inline ::uint16_t getDiscriminantValue() const; + + inline bool isSlot() const; + inline typename Slot::Reader getSlot() const; + + inline bool isGroup() const; + inline typename Group::Reader getGroup() const; + + inline typename Ordinal::Reader getOrdinal() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Field::Builder { +public: + typedef Field Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); + + inline ::uint16_t getDiscriminantValue(); + inline void setDiscriminantValue( ::uint16_t value); + + inline bool isSlot(); + inline typename Slot::Builder getSlot(); + inline typename Slot::Builder initSlot(); + + inline bool isGroup(); + inline typename Group::Builder getGroup(); + inline typename Group::Builder initGroup(); + + inline typename Ordinal::Builder getOrdinal(); + inline typename Ordinal::Builder initOrdinal(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Field::Pipeline { +public: + typedef Field Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename Ordinal::Pipeline getOrdinal(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Slot::Reader { +public: + typedef Slot Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getOffset() const; + + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool hasDefaultValue() const; + inline ::capnp::schema::Value::Reader getDefaultValue() const; + + inline bool getHadExplicitDefault() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Field::Slot::Builder { +public: + typedef Slot Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getOffset(); + inline void setOffset( ::uint32_t value); + + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool hasDefaultValue(); + inline ::capnp::schema::Value::Builder getDefaultValue(); + inline void setDefaultValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initDefaultValue(); + inline void adoptDefaultValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownDefaultValue(); + + inline bool getHadExplicitDefault(); + inline void setHadExplicitDefault(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Field::Slot::Pipeline { +public: + typedef Slot Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); + inline ::capnp::schema::Value::Pipeline getDefaultValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Group::Reader { +public: + typedef Group Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Field::Group::Builder { +public: + typedef Group Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Field::Group::Pipeline { +public: + typedef Group Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Ordinal::Reader { +public: + typedef Ordinal Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isImplicit() const; + inline ::capnp::Void getImplicit() const; + + inline bool isExplicit() const; + inline ::uint16_t getExplicit() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Field::Ordinal::Builder { +public: + typedef Ordinal Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isImplicit(); + inline ::capnp::Void getImplicit(); + inline void setImplicit( ::capnp::Void value = ::capnp::VOID); + + inline bool isExplicit(); + inline ::uint16_t getExplicit(); + inline void setExplicit( ::uint16_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Field::Ordinal::Pipeline { +public: + typedef Ordinal Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Enumerant::Reader { +public: + typedef Enumerant Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Enumerant::Builder { +public: + typedef Enumerant Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Enumerant::Pipeline { +public: + typedef Enumerant Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Superclass::Reader { +public: + typedef Superclass Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Superclass::Builder { +public: + typedef Superclass Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Superclass::Pipeline { +public: + typedef Superclass Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Method::Reader { +public: + typedef Method Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline ::uint64_t getParamStructType() const; + + inline ::uint64_t getResultStructType() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; + + inline bool hasParamBrand() const; + inline ::capnp::schema::Brand::Reader getParamBrand() const; + + inline bool hasResultBrand() const; + inline ::capnp::schema::Brand::Reader getResultBrand() const; + + inline bool hasImplicitParameters() const; + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader getImplicitParameters() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Method::Builder { +public: + typedef Method Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline ::uint64_t getParamStructType(); + inline void setParamStructType( ::uint64_t value); + + inline ::uint64_t getResultStructType(); + inline void setResultStructType( ::uint64_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); + + inline bool hasParamBrand(); + inline ::capnp::schema::Brand::Builder getParamBrand(); + inline void setParamBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initParamBrand(); + inline void adoptParamBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownParamBrand(); + + inline bool hasResultBrand(); + inline ::capnp::schema::Brand::Builder getResultBrand(); + inline void setResultBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initResultBrand(); + inline void adoptResultBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownResultBrand(); + + inline bool hasImplicitParameters(); + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder getImplicitParameters(); + inline void setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder initImplicitParameters(unsigned int size); + inline void adoptImplicitParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> disownImplicitParameters(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Method::Pipeline { +public: + typedef Method Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getParamBrand(); + inline ::capnp::schema::Brand::Pipeline getResultBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Reader { +public: + typedef Type Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isVoid() const; + inline ::capnp::Void getVoid() const; + + inline bool isBool() const; + inline ::capnp::Void getBool() const; + + inline bool isInt8() const; + inline ::capnp::Void getInt8() const; + + inline bool isInt16() const; + inline ::capnp::Void getInt16() const; + + inline bool isInt32() const; + inline ::capnp::Void getInt32() const; + + inline bool isInt64() const; + inline ::capnp::Void getInt64() const; + + inline bool isUint8() const; + inline ::capnp::Void getUint8() const; + + inline bool isUint16() const; + inline ::capnp::Void getUint16() const; + + inline bool isUint32() const; + inline ::capnp::Void getUint32() const; + + inline bool isUint64() const; + inline ::capnp::Void getUint64() const; + + inline bool isFloat32() const; + inline ::capnp::Void getFloat32() const; + + inline bool isFloat64() const; + inline ::capnp::Void getFloat64() const; + + inline bool isText() const; + inline ::capnp::Void getText() const; + + inline bool isData() const; + inline ::capnp::Void getData() const; + + inline bool isList() const; + inline typename List::Reader getList() const; + + inline bool isEnum() const; + inline typename Enum::Reader getEnum() const; + + inline bool isStruct() const; + inline typename Struct::Reader getStruct() const; + + inline bool isInterface() const; + inline typename Interface::Reader getInterface() const; + + inline bool isAnyPointer() const; + inline typename AnyPointer::Reader getAnyPointer() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::Builder { +public: + typedef Type Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isVoid(); + inline ::capnp::Void getVoid(); + inline void setVoid( ::capnp::Void value = ::capnp::VOID); + + inline bool isBool(); + inline ::capnp::Void getBool(); + inline void setBool( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt8(); + inline ::capnp::Void getInt8(); + inline void setInt8( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt16(); + inline ::capnp::Void getInt16(); + inline void setInt16( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt32(); + inline ::capnp::Void getInt32(); + inline void setInt32( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt64(); + inline ::capnp::Void getInt64(); + inline void setInt64( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint8(); + inline ::capnp::Void getUint8(); + inline void setUint8( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint16(); + inline ::capnp::Void getUint16(); + inline void setUint16( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint32(); + inline ::capnp::Void getUint32(); + inline void setUint32( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint64(); + inline ::capnp::Void getUint64(); + inline void setUint64( ::capnp::Void value = ::capnp::VOID); + + inline bool isFloat32(); + inline ::capnp::Void getFloat32(); + inline void setFloat32( ::capnp::Void value = ::capnp::VOID); + + inline bool isFloat64(); + inline ::capnp::Void getFloat64(); + inline void setFloat64( ::capnp::Void value = ::capnp::VOID); + + inline bool isText(); + inline ::capnp::Void getText(); + inline void setText( ::capnp::Void value = ::capnp::VOID); + + inline bool isData(); + inline ::capnp::Void getData(); + inline void setData( ::capnp::Void value = ::capnp::VOID); + + inline bool isList(); + inline typename List::Builder getList(); + inline typename List::Builder initList(); + + inline bool isEnum(); + inline typename Enum::Builder getEnum(); + inline typename Enum::Builder initEnum(); + + inline bool isStruct(); + inline typename Struct::Builder getStruct(); + inline typename Struct::Builder initStruct(); + + inline bool isInterface(); + inline typename Interface::Builder getInterface(); + inline typename Interface::Builder initInterface(); + + inline bool isAnyPointer(); + inline typename AnyPointer::Builder getAnyPointer(); + inline typename AnyPointer::Builder initAnyPointer(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::Pipeline { +public: + typedef Type Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::List::Reader { +public: + typedef List Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasElementType() const; + inline ::capnp::schema::Type::Reader getElementType() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::List::Builder { +public: + typedef List Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasElementType(); + inline ::capnp::schema::Type::Builder getElementType(); + inline void setElementType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initElementType(); + inline void adoptElementType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownElementType(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::List::Pipeline { +public: + typedef List Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getElementType(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Enum::Reader { +public: + typedef Enum Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::Enum::Builder { +public: + typedef Enum Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::Enum::Pipeline { +public: + typedef Enum Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Struct::Reader { +public: + typedef Struct Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::Struct::Builder { +public: + typedef Struct Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::Struct::Pipeline { +public: + typedef Struct Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Interface::Reader { +public: + typedef Interface Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::Interface::Builder { +public: + typedef Interface Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::Interface::Pipeline { +public: + typedef Interface Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::Reader { +public: + typedef AnyPointer Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isUnconstrained() const; + inline typename Unconstrained::Reader getUnconstrained() const; + + inline bool isParameter() const; + inline typename Parameter::Reader getParameter() const; + + inline bool isImplicitMethodParameter() const; + inline typename ImplicitMethodParameter::Reader getImplicitMethodParameter() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::AnyPointer::Builder { +public: + typedef AnyPointer Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isUnconstrained(); + inline typename Unconstrained::Builder getUnconstrained(); + inline typename Unconstrained::Builder initUnconstrained(); + + inline bool isParameter(); + inline typename Parameter::Builder getParameter(); + inline typename Parameter::Builder initParameter(); + + inline bool isImplicitMethodParameter(); + inline typename ImplicitMethodParameter::Builder getImplicitMethodParameter(); + inline typename ImplicitMethodParameter::Builder initImplicitMethodParameter(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::AnyPointer::Pipeline { +public: + typedef AnyPointer Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::Unconstrained::Reader { +public: + typedef Unconstrained Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isAnyKind() const; + inline ::capnp::Void getAnyKind() const; + + inline bool isStruct() const; + inline ::capnp::Void getStruct() const; + + inline bool isList() const; + inline ::capnp::Void getList() const; + + inline bool isCapability() const; + inline ::capnp::Void getCapability() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::AnyPointer::Unconstrained::Builder { +public: + typedef Unconstrained Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isAnyKind(); + inline ::capnp::Void getAnyKind(); + inline void setAnyKind( ::capnp::Void value = ::capnp::VOID); + + inline bool isStruct(); + inline ::capnp::Void getStruct(); + inline void setStruct( ::capnp::Void value = ::capnp::VOID); + + inline bool isList(); + inline ::capnp::Void getList(); + inline void setList( ::capnp::Void value = ::capnp::VOID); + + inline bool isCapability(); + inline ::capnp::Void getCapability(); + inline void setCapability( ::capnp::Void value = ::capnp::VOID); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::AnyPointer::Unconstrained::Pipeline { +public: + typedef Unconstrained Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::Parameter::Reader { +public: + typedef Parameter Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getScopeId() const; + + inline ::uint16_t getParameterIndex() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::AnyPointer::Parameter::Builder { +public: + typedef Parameter Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline ::uint16_t getParameterIndex(); + inline void setParameterIndex( ::uint16_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::AnyPointer::Parameter::Pipeline { +public: + typedef Parameter Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::ImplicitMethodParameter::Reader { +public: + typedef ImplicitMethodParameter Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint16_t getParameterIndex() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::AnyPointer::ImplicitMethodParameter::Builder { +public: + typedef ImplicitMethodParameter Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint16_t getParameterIndex(); + inline void setParameterIndex( ::uint16_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::AnyPointer::ImplicitMethodParameter::Pipeline { +public: + typedef ImplicitMethodParameter Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Brand::Reader { +public: + typedef Brand Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasScopes() const; + inline ::capnp::List< ::capnp::schema::Brand::Scope>::Reader getScopes() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Brand::Builder { +public: + typedef Brand Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasScopes(); + inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder getScopes(); + inline void setScopes( ::capnp::List< ::capnp::schema::Brand::Scope>::Reader value); + inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder initScopes(unsigned int size); + inline void adoptScopes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>> disownScopes(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Brand::Pipeline { +public: + typedef Brand Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Brand::Scope::Reader { +public: + typedef Scope Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline ::uint64_t getScopeId() const; + + inline bool isBind() const; + inline bool hasBind() const; + inline ::capnp::List< ::capnp::schema::Brand::Binding>::Reader getBind() const; + + inline bool isInherit() const; + inline ::capnp::Void getInherit() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Brand::Scope::Builder { +public: + typedef Scope Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline bool isBind(); + inline bool hasBind(); + inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder getBind(); + inline void setBind( ::capnp::List< ::capnp::schema::Brand::Binding>::Reader value); + inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder initBind(unsigned int size); + inline void adoptBind(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>> disownBind(); + + inline bool isInherit(); + inline ::capnp::Void getInherit(); + inline void setInherit( ::capnp::Void value = ::capnp::VOID); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Brand::Scope::Pipeline { +public: + typedef Scope Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Brand::Binding::Reader { +public: + typedef Binding Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isUnbound() const; + inline ::capnp::Void getUnbound() const; + + inline bool isType() const; + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Brand::Binding::Builder { +public: + typedef Binding Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isUnbound(); + inline ::capnp::Void getUnbound(); + inline void setUnbound( ::capnp::Void value = ::capnp::VOID); + + inline bool isType(); + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Brand::Binding::Pipeline { +public: + typedef Binding Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Value::Reader { +public: + typedef Value Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isVoid() const; + inline ::capnp::Void getVoid() const; + + inline bool isBool() const; + inline bool getBool() const; + + inline bool isInt8() const; + inline ::int8_t getInt8() const; + + inline bool isInt16() const; + inline ::int16_t getInt16() const; + + inline bool isInt32() const; + inline ::int32_t getInt32() const; + + inline bool isInt64() const; + inline ::int64_t getInt64() const; + + inline bool isUint8() const; + inline ::uint8_t getUint8() const; + + inline bool isUint16() const; + inline ::uint16_t getUint16() const; + + inline bool isUint32() const; + inline ::uint32_t getUint32() const; + + inline bool isUint64() const; + inline ::uint64_t getUint64() const; + + inline bool isFloat32() const; + inline float getFloat32() const; + + inline bool isFloat64() const; + inline double getFloat64() const; + + inline bool isText() const; + inline bool hasText() const; + inline ::capnp::Text::Reader getText() const; + + inline bool isData() const; + inline bool hasData() const; + inline ::capnp::Data::Reader getData() const; + + inline bool isList() const; + inline bool hasList() const; + inline ::capnp::AnyPointer::Reader getList() const; + + inline bool isEnum() const; + inline ::uint16_t getEnum() const; + + inline bool isStruct() const; + inline bool hasStruct() const; + inline ::capnp::AnyPointer::Reader getStruct() const; + + inline bool isInterface() const; + inline ::capnp::Void getInterface() const; + + inline bool isAnyPointer() const; + inline bool hasAnyPointer() const; + inline ::capnp::AnyPointer::Reader getAnyPointer() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Value::Builder { +public: + typedef Value Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isVoid(); + inline ::capnp::Void getVoid(); + inline void setVoid( ::capnp::Void value = ::capnp::VOID); + + inline bool isBool(); + inline bool getBool(); + inline void setBool(bool value); + + inline bool isInt8(); + inline ::int8_t getInt8(); + inline void setInt8( ::int8_t value); + + inline bool isInt16(); + inline ::int16_t getInt16(); + inline void setInt16( ::int16_t value); + + inline bool isInt32(); + inline ::int32_t getInt32(); + inline void setInt32( ::int32_t value); + + inline bool isInt64(); + inline ::int64_t getInt64(); + inline void setInt64( ::int64_t value); + + inline bool isUint8(); + inline ::uint8_t getUint8(); + inline void setUint8( ::uint8_t value); + + inline bool isUint16(); + inline ::uint16_t getUint16(); + inline void setUint16( ::uint16_t value); + + inline bool isUint32(); + inline ::uint32_t getUint32(); + inline void setUint32( ::uint32_t value); + + inline bool isUint64(); + inline ::uint64_t getUint64(); + inline void setUint64( ::uint64_t value); + + inline bool isFloat32(); + inline float getFloat32(); + inline void setFloat32(float value); + + inline bool isFloat64(); + inline double getFloat64(); + inline void setFloat64(double value); + + inline bool isText(); + inline bool hasText(); + inline ::capnp::Text::Builder getText(); + inline void setText( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initText(unsigned int size); + inline void adoptText(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownText(); + + inline bool isData(); + inline bool hasData(); + inline ::capnp::Data::Builder getData(); + inline void setData( ::capnp::Data::Reader value); + inline ::capnp::Data::Builder initData(unsigned int size); + inline void adoptData(::capnp::Orphan< ::capnp::Data>&& value); + inline ::capnp::Orphan< ::capnp::Data> disownData(); + + inline bool isList(); + inline bool hasList(); + inline ::capnp::AnyPointer::Builder getList(); + inline ::capnp::AnyPointer::Builder initList(); + + inline bool isEnum(); + inline ::uint16_t getEnum(); + inline void setEnum( ::uint16_t value); + + inline bool isStruct(); + inline bool hasStruct(); + inline ::capnp::AnyPointer::Builder getStruct(); + inline ::capnp::AnyPointer::Builder initStruct(); + + inline bool isInterface(); + inline ::capnp::Void getInterface(); + inline void setInterface( ::capnp::Void value = ::capnp::VOID); + + inline bool isAnyPointer(); + inline bool hasAnyPointer(); + inline ::capnp::AnyPointer::Builder getAnyPointer(); + inline ::capnp::AnyPointer::Builder initAnyPointer(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Value::Pipeline { +public: + typedef Value Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Annotation::Reader { +public: + typedef Annotation Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasValue() const; + inline ::capnp::schema::Value::Reader getValue() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Annotation::Builder { +public: + typedef Annotation Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasValue(); + inline ::capnp::schema::Value::Builder getValue(); + inline void setValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Annotation::Pipeline { +public: + typedef Annotation Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Value::Pipeline getValue(); + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CapnpVersion::Reader { +public: + typedef CapnpVersion Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint16_t getMajor() const; + + inline ::uint8_t getMinor() const; + + inline ::uint8_t getMicro() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CapnpVersion::Builder { +public: + typedef CapnpVersion Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint16_t getMajor(); + inline void setMajor( ::uint16_t value); + + inline ::uint8_t getMinor(); + inline void setMinor( ::uint8_t value); + + inline ::uint8_t getMicro(); + inline void setMicro( ::uint8_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CapnpVersion::Pipeline { +public: + typedef CapnpVersion Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CodeGeneratorRequest::Reader { +public: + typedef CodeGeneratorRequest Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasNodes() const; + inline ::capnp::List< ::capnp::schema::Node>::Reader getNodes() const; + + inline bool hasRequestedFiles() const; + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader getRequestedFiles() const; + + inline bool hasCapnpVersion() const; + inline ::capnp::schema::CapnpVersion::Reader getCapnpVersion() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CodeGeneratorRequest::Builder { +public: + typedef CodeGeneratorRequest Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasNodes(); + inline ::capnp::List< ::capnp::schema::Node>::Builder getNodes(); + inline void setNodes( ::capnp::List< ::capnp::schema::Node>::Reader value); + inline ::capnp::List< ::capnp::schema::Node>::Builder initNodes(unsigned int size); + inline void adoptNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>> disownNodes(); + + inline bool hasRequestedFiles(); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder getRequestedFiles(); + inline void setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader value); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder initRequestedFiles(unsigned int size); + inline void adoptRequestedFiles(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>> disownRequestedFiles(); + + inline bool hasCapnpVersion(); + inline ::capnp::schema::CapnpVersion::Builder getCapnpVersion(); + inline void setCapnpVersion( ::capnp::schema::CapnpVersion::Reader value); + inline ::capnp::schema::CapnpVersion::Builder initCapnpVersion(); + inline void adoptCapnpVersion(::capnp::Orphan< ::capnp::schema::CapnpVersion>&& value); + inline ::capnp::Orphan< ::capnp::schema::CapnpVersion> disownCapnpVersion(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CodeGeneratorRequest::Pipeline { +public: + typedef CodeGeneratorRequest Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::CapnpVersion::Pipeline getCapnpVersion(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CodeGeneratorRequest::RequestedFile::Reader { +public: + typedef RequestedFile Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasFilename() const; + inline ::capnp::Text::Reader getFilename() const; + + inline bool hasImports() const; + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader getImports() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CodeGeneratorRequest::RequestedFile::Builder { +public: + typedef RequestedFile Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasFilename(); + inline ::capnp::Text::Builder getFilename(); + inline void setFilename( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initFilename(unsigned int size); + inline void adoptFilename(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownFilename(); + + inline bool hasImports(); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder getImports(); + inline void setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader value); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder initImports(unsigned int size); + inline void adoptImports(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>> disownImports(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CodeGeneratorRequest::RequestedFile::Pipeline { +public: + typedef RequestedFile Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CodeGeneratorRequest::RequestedFile::Import::Reader { +public: + typedef Import Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CodeGeneratorRequest::RequestedFile::Import::Builder { +public: + typedef Import Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CodeGeneratorRequest::RequestedFile::Import::Pipeline { +public: + typedef Import Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline ::capnp::schema::Node::Which Node::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Node::Which Node::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::hasDisplayName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasDisplayName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::Reader::getDisplayName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::Builder::getDisplayName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Node::Builder::setDisplayName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::Builder::initDisplayName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptDisplayName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::Builder::disownDisplayName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint32_t Node::Reader::getDisplayNamePrefixLength() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Node::Builder::getDisplayNamePrefixLength() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setDisplayNamePrefixLength( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Node::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::hasNestedNodes() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasNestedNodes() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader Node::Reader::getNestedNodes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder Node::Builder::getNestedNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Node::Builder::setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder Node::Builder::initNestedNodes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptNestedNodes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>> Node::Builder::disownNestedNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Node::Reader::hasAnnotations() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasAnnotations() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Reader Node::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Node::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Node::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Node::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Node::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Node::Reader::isFile() const { + return which() == Node::FILE; +} +inline bool Node::Builder::isFile() { + return which() == Node::FILE; +} +inline ::capnp::Void Node::Reader::getFile() const { + KJ_IREQUIRE((which() == Node::FILE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Node::Builder::getFile() { + KJ_IREQUIRE((which() == Node::FILE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setFile( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::FILE); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::isStruct() const { + return which() == Node::STRUCT; +} +inline bool Node::Builder::isStruct() { + return which() == Node::STRUCT; +} +inline typename Node::Struct::Reader Node::Reader::getStruct() const { + KJ_IREQUIRE((which() == Node::STRUCT), + "Must check which() before get()ing a union member."); + return typename Node::Struct::Reader(_reader); +} +inline typename Node::Struct::Builder Node::Builder::getStruct() { + KJ_IREQUIRE((which() == Node::STRUCT), + "Must check which() before get()ing a union member."); + return typename Node::Struct::Builder(_builder); +} +inline typename Node::Struct::Builder Node::Builder::initStruct() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::STRUCT); + _builder.setDataField< ::uint16_t>(::capnp::bounded<7>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<12>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<13>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<224>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<15>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint32_t>(::capnp::bounded<8>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + return typename Node::Struct::Builder(_builder); +} +inline bool Node::Reader::isEnum() const { + return which() == Node::ENUM; +} +inline bool Node::Builder::isEnum() { + return which() == Node::ENUM; +} +inline typename Node::Enum::Reader Node::Reader::getEnum() const { + KJ_IREQUIRE((which() == Node::ENUM), + "Must check which() before get()ing a union member."); + return typename Node::Enum::Reader(_reader); +} +inline typename Node::Enum::Builder Node::Builder::getEnum() { + KJ_IREQUIRE((which() == Node::ENUM), + "Must check which() before get()ing a union member."); + return typename Node::Enum::Builder(_builder); +} +inline typename Node::Enum::Builder Node::Builder::initEnum() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::ENUM); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + return typename Node::Enum::Builder(_builder); +} +inline bool Node::Reader::isInterface() const { + return which() == Node::INTERFACE; +} +inline bool Node::Builder::isInterface() { + return which() == Node::INTERFACE; +} +inline typename Node::Interface::Reader Node::Reader::getInterface() const { + KJ_IREQUIRE((which() == Node::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Node::Interface::Reader(_reader); +} +inline typename Node::Interface::Builder Node::Builder::getInterface() { + KJ_IREQUIRE((which() == Node::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Node::Interface::Builder(_builder); +} +inline typename Node::Interface::Builder Node::Builder::initInterface() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::INTERFACE); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + _builder.getPointerField(::capnp::bounded<4>() * ::capnp::POINTERS).clear(); + return typename Node::Interface::Builder(_builder); +} +inline bool Node::Reader::isConst() const { + return which() == Node::CONST; +} +inline bool Node::Builder::isConst() { + return which() == Node::CONST; +} +inline typename Node::Const::Reader Node::Reader::getConst() const { + KJ_IREQUIRE((which() == Node::CONST), + "Must check which() before get()ing a union member."); + return typename Node::Const::Reader(_reader); +} +inline typename Node::Const::Builder Node::Builder::getConst() { + KJ_IREQUIRE((which() == Node::CONST), + "Must check which() before get()ing a union member."); + return typename Node::Const::Builder(_builder); +} +inline typename Node::Const::Builder Node::Builder::initConst() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::CONST); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + _builder.getPointerField(::capnp::bounded<4>() * ::capnp::POINTERS).clear(); + return typename Node::Const::Builder(_builder); +} +inline bool Node::Reader::isAnnotation() const { + return which() == Node::ANNOTATION; +} +inline bool Node::Builder::isAnnotation() { + return which() == Node::ANNOTATION; +} +inline typename Node::Annotation::Reader Node::Reader::getAnnotation() const { + KJ_IREQUIRE((which() == Node::ANNOTATION), + "Must check which() before get()ing a union member."); + return typename Node::Annotation::Reader(_reader); +} +inline typename Node::Annotation::Builder Node::Builder::getAnnotation() { + KJ_IREQUIRE((which() == Node::ANNOTATION), + "Must check which() before get()ing a union member."); + return typename Node::Annotation::Builder(_builder); +} +inline typename Node::Annotation::Builder Node::Builder::initAnnotation() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::ANNOTATION); + _builder.setDataField(::capnp::bounded<112>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<113>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<114>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<115>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<116>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<117>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<118>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<119>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<120>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<121>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<122>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<123>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + return typename Node::Annotation::Builder(_builder); +} +inline bool Node::Reader::hasParameters() const { + return !_reader.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasParameters() { + return !_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader Node::Reader::getParameters() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get(_reader.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Node::Builder::getParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +inline void Node::Builder::setParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::set(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Node::Builder::initParameters(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::init(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptParameters( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::adopt(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> Node::Builder::disownParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::disown(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} + +inline bool Node::Reader::getIsGeneric() const { + return _reader.getDataField( + ::capnp::bounded<288>() * ::capnp::ELEMENTS); +} + +inline bool Node::Builder::getIsGeneric() { + return _builder.getDataField( + ::capnp::bounded<288>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setIsGeneric(bool value) { + _builder.setDataField( + ::capnp::bounded<288>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Parameter::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Parameter::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::Parameter::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::Parameter::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Node::Parameter::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::Parameter::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Node::Parameter::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::Parameter::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Node::NestedNode::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::NestedNode::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::NestedNode::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::NestedNode::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Node::NestedNode::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::NestedNode::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Node::NestedNode::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::NestedNode::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Node::NestedNode::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::NestedNode::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Node::NestedNode::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Node::Struct::Reader::getDataWordCount() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<7>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getDataWordCount() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<7>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDataWordCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<7>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Node::Struct::Reader::getPointerCount() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getPointerCount() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setPointerCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::ElementSize Node::Struct::Reader::getPreferredListEncoding() const { + return _reader.getDataField< ::capnp::schema::ElementSize>( + ::capnp::bounded<13>() * ::capnp::ELEMENTS); +} + +inline ::capnp::schema::ElementSize Node::Struct::Builder::getPreferredListEncoding() { + return _builder.getDataField< ::capnp::schema::ElementSize>( + ::capnp::bounded<13>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setPreferredListEncoding( ::capnp::schema::ElementSize value) { + _builder.setDataField< ::capnp::schema::ElementSize>( + ::capnp::bounded<13>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Struct::Reader::getIsGroup() const { + return _reader.getDataField( + ::capnp::bounded<224>() * ::capnp::ELEMENTS); +} + +inline bool Node::Struct::Builder::getIsGroup() { + return _builder.getDataField( + ::capnp::bounded<224>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setIsGroup(bool value) { + _builder.setDataField( + ::capnp::bounded<224>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Node::Struct::Reader::getDiscriminantCount() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<15>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getDiscriminantCount() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<15>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDiscriminantCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<15>() * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Node::Struct::Reader::getDiscriminantOffset() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<8>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Node::Struct::Builder::getDiscriminantOffset() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<8>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDiscriminantOffset( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<8>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Struct::Reader::hasFields() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Struct::Builder::hasFields() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Field>::Reader Node::Struct::Reader::getFields() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Field>::Builder Node::Struct::Builder::getFields() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Struct::Builder::setFields( ::capnp::List< ::capnp::schema::Field>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Field>::Builder Node::Struct::Builder::initFields(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +inline void Node::Struct::Builder::adoptFields( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>> Node::Struct::Builder::disownFields() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Enum::Reader::hasEnumerants() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Enum::Builder::hasEnumerants() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Enumerant>::Reader Node::Enum::Reader::getEnumerants() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Enumerant>::Builder Node::Enum::Builder::getEnumerants() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Enum::Builder::setEnumerants( ::capnp::List< ::capnp::schema::Enumerant>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Enumerant>::Builder Node::Enum::Builder::initEnumerants(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +inline void Node::Enum::Builder::adoptEnumerants( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>> Node::Enum::Builder::disownEnumerants() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Interface::Reader::hasMethods() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Interface::Builder::hasMethods() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Method>::Reader Node::Interface::Reader::getMethods() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Method>::Builder Node::Interface::Builder::getMethods() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Interface::Builder::setMethods( ::capnp::List< ::capnp::schema::Method>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Method>::Builder Node::Interface::Builder::initMethods(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +inline void Node::Interface::Builder::adoptMethods( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>> Node::Interface::Builder::disownMethods() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Interface::Reader::hasSuperclasses() const { + return !_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Interface::Builder::hasSuperclasses() { + return !_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Superclass>::Reader Node::Interface::Reader::getSuperclasses() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::get(_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Superclass>::Builder Node::Interface::Builder::getSuperclasses() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::get(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline void Node::Interface::Builder::setSuperclasses( ::capnp::List< ::capnp::schema::Superclass>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::set(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Superclass>::Builder Node::Interface::Builder::initSuperclasses(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::init(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), size); +} +inline void Node::Interface::Builder::adoptSuperclasses( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::adopt(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>> Node::Interface::Builder::disownSuperclasses() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::disown(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} + +inline bool Node::Const::Reader::hasType() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Const::Builder::hasType() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Node::Const::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Node::Const::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Node::Const::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Node::Const::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Node::Const::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Const::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Node::Const::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Const::Reader::hasValue() const { + return !_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Const::Builder::hasValue() { + return !_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Node::Const::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Node::Const::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Node::Const::Pipeline::getValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(4)); +} +#endif // !CAPNP_LITE +inline void Node::Const::Builder::setValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Node::Const::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline void Node::Const::Builder::adoptValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Node::Const::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} + +inline bool Node::Annotation::Reader::hasType() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Annotation::Builder::hasType() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Node::Annotation::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Node::Annotation::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Node::Annotation::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Node::Annotation::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Node::Annotation::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Annotation::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Node::Annotation::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Annotation::Reader::getTargetsFile() const { + return _reader.getDataField( + ::capnp::bounded<112>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsFile() { + return _builder.getDataField( + ::capnp::bounded<112>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsFile(bool value) { + _builder.setDataField( + ::capnp::bounded<112>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsConst() const { + return _reader.getDataField( + ::capnp::bounded<113>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsConst() { + return _builder.getDataField( + ::capnp::bounded<113>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsConst(bool value) { + _builder.setDataField( + ::capnp::bounded<113>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsEnum() const { + return _reader.getDataField( + ::capnp::bounded<114>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsEnum() { + return _builder.getDataField( + ::capnp::bounded<114>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsEnum(bool value) { + _builder.setDataField( + ::capnp::bounded<114>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsEnumerant() const { + return _reader.getDataField( + ::capnp::bounded<115>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsEnumerant() { + return _builder.getDataField( + ::capnp::bounded<115>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsEnumerant(bool value) { + _builder.setDataField( + ::capnp::bounded<115>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsStruct() const { + return _reader.getDataField( + ::capnp::bounded<116>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsStruct() { + return _builder.getDataField( + ::capnp::bounded<116>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsStruct(bool value) { + _builder.setDataField( + ::capnp::bounded<116>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsField() const { + return _reader.getDataField( + ::capnp::bounded<117>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsField() { + return _builder.getDataField( + ::capnp::bounded<117>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsField(bool value) { + _builder.setDataField( + ::capnp::bounded<117>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsUnion() const { + return _reader.getDataField( + ::capnp::bounded<118>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsUnion() { + return _builder.getDataField( + ::capnp::bounded<118>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsUnion(bool value) { + _builder.setDataField( + ::capnp::bounded<118>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsGroup() const { + return _reader.getDataField( + ::capnp::bounded<119>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsGroup() { + return _builder.getDataField( + ::capnp::bounded<119>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsGroup(bool value) { + _builder.setDataField( + ::capnp::bounded<119>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsInterface() const { + return _reader.getDataField( + ::capnp::bounded<120>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsInterface() { + return _builder.getDataField( + ::capnp::bounded<120>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsInterface(bool value) { + _builder.setDataField( + ::capnp::bounded<120>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsMethod() const { + return _reader.getDataField( + ::capnp::bounded<121>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsMethod() { + return _builder.getDataField( + ::capnp::bounded<121>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsMethod(bool value) { + _builder.setDataField( + ::capnp::bounded<121>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsParam() const { + return _reader.getDataField( + ::capnp::bounded<122>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsParam() { + return _builder.getDataField( + ::capnp::bounded<122>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsParam(bool value) { + _builder.setDataField( + ::capnp::bounded<122>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsAnnotation() const { + return _reader.getDataField( + ::capnp::bounded<123>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsAnnotation() { + return _builder.getDataField( + ::capnp::bounded<123>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsAnnotation(bool value) { + _builder.setDataField( + ::capnp::bounded<123>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Field::Which Field::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Field::Which Field::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} + +inline bool Field::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Field::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Field::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Field::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Field::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Field::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Field::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Field::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Field::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Field::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Field::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Field::Reader::hasAnnotations() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Field::Builder::hasAnnotations() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Reader Field::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Field::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Field::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Field::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Field::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Field::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Field::Reader::getDiscriminantValue() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, 65535u); +} + +inline ::uint16_t Field::Builder::getDiscriminantValue() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, 65535u); +} +inline void Field::Builder::setDiscriminantValue( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value, 65535u); +} + +inline bool Field::Reader::isSlot() const { + return which() == Field::SLOT; +} +inline bool Field::Builder::isSlot() { + return which() == Field::SLOT; +} +inline typename Field::Slot::Reader Field::Reader::getSlot() const { + KJ_IREQUIRE((which() == Field::SLOT), + "Must check which() before get()ing a union member."); + return typename Field::Slot::Reader(_reader); +} +inline typename Field::Slot::Builder Field::Builder::getSlot() { + KJ_IREQUIRE((which() == Field::SLOT), + "Must check which() before get()ing a union member."); + return typename Field::Slot::Builder(_builder); +} +inline typename Field::Slot::Builder Field::Builder::initSlot() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Field::SLOT); + _builder.setDataField< ::uint32_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<128>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<2>() * ::capnp::POINTERS).clear(); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + return typename Field::Slot::Builder(_builder); +} +inline bool Field::Reader::isGroup() const { + return which() == Field::GROUP; +} +inline bool Field::Builder::isGroup() { + return which() == Field::GROUP; +} +inline typename Field::Group::Reader Field::Reader::getGroup() const { + KJ_IREQUIRE((which() == Field::GROUP), + "Must check which() before get()ing a union member."); + return typename Field::Group::Reader(_reader); +} +inline typename Field::Group::Builder Field::Builder::getGroup() { + KJ_IREQUIRE((which() == Field::GROUP), + "Must check which() before get()ing a union member."); + return typename Field::Group::Builder(_builder); +} +inline typename Field::Group::Builder Field::Builder::initGroup() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Field::GROUP); + _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename Field::Group::Builder(_builder); +} +inline typename Field::Ordinal::Reader Field::Reader::getOrdinal() const { + return typename Field::Ordinal::Reader(_reader); +} +inline typename Field::Ordinal::Builder Field::Builder::getOrdinal() { + return typename Field::Ordinal::Builder(_builder); +} +#if !CAPNP_LITE +inline typename Field::Ordinal::Pipeline Field::Pipeline::getOrdinal() { + return typename Field::Ordinal::Pipeline(_typeless.noop()); +} +#endif // !CAPNP_LITE +inline typename Field::Ordinal::Builder Field::Builder::initOrdinal() { + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<6>() * ::capnp::ELEMENTS, 0); + return typename Field::Ordinal::Builder(_builder); +} +inline ::uint32_t Field::Slot::Reader::getOffset() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Field::Slot::Builder::getOffset() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Field::Slot::Builder::setOffset( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Field::Slot::Reader::hasType() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Field::Slot::Builder::hasType() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Field::Slot::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Field::Slot::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Field::Slot::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void Field::Slot::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Field::Slot::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Field::Slot::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Field::Slot::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Field::Slot::Reader::hasDefaultValue() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Field::Slot::Builder::hasDefaultValue() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Field::Slot::Reader::getDefaultValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Field::Slot::Builder::getDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Field::Slot::Pipeline::getDefaultValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Field::Slot::Builder::setDefaultValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Field::Slot::Builder::initDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Field::Slot::Builder::adoptDefaultValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Field::Slot::Builder::disownDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Field::Slot::Reader::getHadExplicitDefault() const { + return _reader.getDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS); +} + +inline bool Field::Slot::Builder::getHadExplicitDefault() { + return _builder.getDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS); +} +inline void Field::Slot::Builder::setHadExplicitDefault(bool value) { + _builder.setDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Field::Group::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Field::Group::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Field::Group::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} + +inline bool Field::Ordinal::Reader::isImplicit() const { + return which() == Field::Ordinal::IMPLICIT; +} +inline bool Field::Ordinal::Builder::isImplicit() { + return which() == Field::Ordinal::IMPLICIT; +} +inline ::capnp::Void Field::Ordinal::Reader::getImplicit() const { + KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Field::Ordinal::Builder::getImplicit() { + KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Field::Ordinal::Builder::setImplicit( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Field::Ordinal::IMPLICIT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Field::Ordinal::Reader::isExplicit() const { + return which() == Field::Ordinal::EXPLICIT; +} +inline bool Field::Ordinal::Builder::isExplicit() { + return which() == Field::Ordinal::EXPLICIT; +} +inline ::uint16_t Field::Ordinal::Reader::getExplicit() const { + KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<6>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Field::Ordinal::Builder::getExplicit() { + KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<6>() * ::capnp::ELEMENTS); +} +inline void Field::Ordinal::Builder::setExplicit( ::uint16_t value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Field::Ordinal::EXPLICIT); + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, value); +} + +inline bool Enumerant::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Enumerant::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Enumerant::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Enumerant::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Enumerant::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Enumerant::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Enumerant::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Enumerant::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Enumerant::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Enumerant::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Enumerant::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Enumerant::Reader::hasAnnotations() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Enumerant::Builder::hasAnnotations() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Reader Enumerant::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Enumerant::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Enumerant::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Enumerant::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Enumerant::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Enumerant::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Superclass::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Superclass::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Superclass::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Superclass::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Superclass::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Superclass::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Superclass::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Superclass::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Superclass::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Superclass::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Superclass::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Superclass::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Method::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Method::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Method::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Method::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Method::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Method::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Method::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Method::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Method::Reader::getParamStructType() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Method::Builder::getParamStructType() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Method::Builder::setParamStructType( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Method::Reader::getResultStructType() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Method::Builder::getResultStructType() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Method::Builder::setResultStructType( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Method::Reader::hasAnnotations() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasAnnotations() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Reader Method::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Method::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Method::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Method::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Method::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasParamBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasParamBrand() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Method::Reader::getParamBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Method::Builder::getParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getParamBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void Method::Builder::setParamBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Method::Builder::initParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Method::Builder::adoptParamBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasResultBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasResultBrand() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Method::Reader::getResultBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Method::Builder::getResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getResultBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Method::Builder::setResultBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Method::Builder::initResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Method::Builder::adoptResultBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasImplicitParameters() const { + return !_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasImplicitParameters() { + return !_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader Method::Reader::getImplicitParameters() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get(_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Method::Builder::getImplicitParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline void Method::Builder::setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::set(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Method::Builder::initImplicitParameters(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::init(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptImplicitParameters( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::adopt(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> Method::Builder::disownImplicitParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::disown(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Type::Which Type::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::Which Type::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Type::Reader::isVoid() const { + return which() == Type::VOID; +} +inline bool Type::Builder::isVoid() { + return which() == Type::VOID; +} +inline ::capnp::Void Type::Reader::getVoid() const { + KJ_IREQUIRE((which() == Type::VOID), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getVoid() { + KJ_IREQUIRE((which() == Type::VOID), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setVoid( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::VOID); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isBool() const { + return which() == Type::BOOL; +} +inline bool Type::Builder::isBool() { + return which() == Type::BOOL; +} +inline ::capnp::Void Type::Reader::getBool() const { + KJ_IREQUIRE((which() == Type::BOOL), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getBool() { + KJ_IREQUIRE((which() == Type::BOOL), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setBool( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::BOOL); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt8() const { + return which() == Type::INT8; +} +inline bool Type::Builder::isInt8() { + return which() == Type::INT8; +} +inline ::capnp::Void Type::Reader::getInt8() const { + KJ_IREQUIRE((which() == Type::INT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt8() { + KJ_IREQUIRE((which() == Type::INT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt8( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT8); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt16() const { + return which() == Type::INT16; +} +inline bool Type::Builder::isInt16() { + return which() == Type::INT16; +} +inline ::capnp::Void Type::Reader::getInt16() const { + KJ_IREQUIRE((which() == Type::INT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt16() { + KJ_IREQUIRE((which() == Type::INT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt16( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT16); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt32() const { + return which() == Type::INT32; +} +inline bool Type::Builder::isInt32() { + return which() == Type::INT32; +} +inline ::capnp::Void Type::Reader::getInt32() const { + KJ_IREQUIRE((which() == Type::INT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt32() { + KJ_IREQUIRE((which() == Type::INT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt32( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT32); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt64() const { + return which() == Type::INT64; +} +inline bool Type::Builder::isInt64() { + return which() == Type::INT64; +} +inline ::capnp::Void Type::Reader::getInt64() const { + KJ_IREQUIRE((which() == Type::INT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt64() { + KJ_IREQUIRE((which() == Type::INT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt64( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT64); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint8() const { + return which() == Type::UINT8; +} +inline bool Type::Builder::isUint8() { + return which() == Type::UINT8; +} +inline ::capnp::Void Type::Reader::getUint8() const { + KJ_IREQUIRE((which() == Type::UINT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint8() { + KJ_IREQUIRE((which() == Type::UINT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint8( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT8); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint16() const { + return which() == Type::UINT16; +} +inline bool Type::Builder::isUint16() { + return which() == Type::UINT16; +} +inline ::capnp::Void Type::Reader::getUint16() const { + KJ_IREQUIRE((which() == Type::UINT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint16() { + KJ_IREQUIRE((which() == Type::UINT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint16( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT16); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint32() const { + return which() == Type::UINT32; +} +inline bool Type::Builder::isUint32() { + return which() == Type::UINT32; +} +inline ::capnp::Void Type::Reader::getUint32() const { + KJ_IREQUIRE((which() == Type::UINT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint32() { + KJ_IREQUIRE((which() == Type::UINT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint32( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT32); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint64() const { + return which() == Type::UINT64; +} +inline bool Type::Builder::isUint64() { + return which() == Type::UINT64; +} +inline ::capnp::Void Type::Reader::getUint64() const { + KJ_IREQUIRE((which() == Type::UINT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint64() { + KJ_IREQUIRE((which() == Type::UINT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint64( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT64); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isFloat32() const { + return which() == Type::FLOAT32; +} +inline bool Type::Builder::isFloat32() { + return which() == Type::FLOAT32; +} +inline ::capnp::Void Type::Reader::getFloat32() const { + KJ_IREQUIRE((which() == Type::FLOAT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getFloat32() { + KJ_IREQUIRE((which() == Type::FLOAT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setFloat32( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::FLOAT32); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isFloat64() const { + return which() == Type::FLOAT64; +} +inline bool Type::Builder::isFloat64() { + return which() == Type::FLOAT64; +} +inline ::capnp::Void Type::Reader::getFloat64() const { + KJ_IREQUIRE((which() == Type::FLOAT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getFloat64() { + KJ_IREQUIRE((which() == Type::FLOAT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setFloat64( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::FLOAT64); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isText() const { + return which() == Type::TEXT; +} +inline bool Type::Builder::isText() { + return which() == Type::TEXT; +} +inline ::capnp::Void Type::Reader::getText() const { + KJ_IREQUIRE((which() == Type::TEXT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getText() { + KJ_IREQUIRE((which() == Type::TEXT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setText( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::TEXT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isData() const { + return which() == Type::DATA; +} +inline bool Type::Builder::isData() { + return which() == Type::DATA; +} +inline ::capnp::Void Type::Reader::getData() const { + KJ_IREQUIRE((which() == Type::DATA), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getData() { + KJ_IREQUIRE((which() == Type::DATA), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setData( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::DATA); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isList() const { + return which() == Type::LIST; +} +inline bool Type::Builder::isList() { + return which() == Type::LIST; +} +inline typename Type::List::Reader Type::Reader::getList() const { + KJ_IREQUIRE((which() == Type::LIST), + "Must check which() before get()ing a union member."); + return typename Type::List::Reader(_reader); +} +inline typename Type::List::Builder Type::Builder::getList() { + KJ_IREQUIRE((which() == Type::LIST), + "Must check which() before get()ing a union member."); + return typename Type::List::Builder(_builder); +} +inline typename Type::List::Builder Type::Builder::initList() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::LIST); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Type::List::Builder(_builder); +} +inline bool Type::Reader::isEnum() const { + return which() == Type::ENUM; +} +inline bool Type::Builder::isEnum() { + return which() == Type::ENUM; +} +inline typename Type::Enum::Reader Type::Reader::getEnum() const { + KJ_IREQUIRE((which() == Type::ENUM), + "Must check which() before get()ing a union member."); + return typename Type::Enum::Reader(_reader); +} +inline typename Type::Enum::Builder Type::Builder::getEnum() { + KJ_IREQUIRE((which() == Type::ENUM), + "Must check which() before get()ing a union member."); + return typename Type::Enum::Builder(_builder); +} +inline typename Type::Enum::Builder Type::Builder::initEnum() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::ENUM); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Type::Enum::Builder(_builder); +} +inline bool Type::Reader::isStruct() const { + return which() == Type::STRUCT; +} +inline bool Type::Builder::isStruct() { + return which() == Type::STRUCT; +} +inline typename Type::Struct::Reader Type::Reader::getStruct() const { + KJ_IREQUIRE((which() == Type::STRUCT), + "Must check which() before get()ing a union member."); + return typename Type::Struct::Reader(_reader); +} +inline typename Type::Struct::Builder Type::Builder::getStruct() { + KJ_IREQUIRE((which() == Type::STRUCT), + "Must check which() before get()ing a union member."); + return typename Type::Struct::Builder(_builder); +} +inline typename Type::Struct::Builder Type::Builder::initStruct() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::STRUCT); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Type::Struct::Builder(_builder); +} +inline bool Type::Reader::isInterface() const { + return which() == Type::INTERFACE; +} +inline bool Type::Builder::isInterface() { + return which() == Type::INTERFACE; +} +inline typename Type::Interface::Reader Type::Reader::getInterface() const { + KJ_IREQUIRE((which() == Type::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Type::Interface::Reader(_reader); +} +inline typename Type::Interface::Builder Type::Builder::getInterface() { + KJ_IREQUIRE((which() == Type::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Type::Interface::Builder(_builder); +} +inline typename Type::Interface::Builder Type::Builder::initInterface() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INTERFACE); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Type::Interface::Builder(_builder); +} +inline bool Type::Reader::isAnyPointer() const { + return which() == Type::ANY_POINTER; +} +inline bool Type::Builder::isAnyPointer() { + return which() == Type::ANY_POINTER; +} +inline typename Type::AnyPointer::Reader Type::Reader::getAnyPointer() const { + KJ_IREQUIRE((which() == Type::ANY_POINTER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Reader(_reader); +} +inline typename Type::AnyPointer::Builder Type::Builder::getAnyPointer() { + KJ_IREQUIRE((which() == Type::ANY_POINTER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Builder(_builder); +} +inline typename Type::AnyPointer::Builder Type::Builder::initAnyPointer() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::ANY_POINTER); + _builder.setDataField< ::uint16_t>(::capnp::bounded<4>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Builder(_builder); +} +inline bool Type::List::Reader::hasElementType() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Type::List::Builder::hasElementType() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Type::List::Reader::getElementType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Type::List::Builder::getElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Type::List::Pipeline::getElementType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::List::Builder::setElementType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Type::List::Builder::initElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Type::List::Builder::adoptElementType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Type::List::Builder::disownElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Enum::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Enum::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Type::Enum::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Enum::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Type::Enum::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Enum::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Enum::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Enum::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Enum::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Enum::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Type::Enum::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Enum::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Struct::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Struct::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Type::Struct::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Struct::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Type::Struct::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Struct::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Struct::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Struct::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Struct::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Struct::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Type::Struct::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Struct::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Interface::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Interface::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Type::Interface::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Interface::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Type::Interface::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Interface::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Interface::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Interface::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Interface::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Interface::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Type::Interface::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Interface::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} + +inline bool Type::AnyPointer::Reader::isUnconstrained() const { + return which() == Type::AnyPointer::UNCONSTRAINED; +} +inline bool Type::AnyPointer::Builder::isUnconstrained() { + return which() == Type::AnyPointer::UNCONSTRAINED; +} +inline typename Type::AnyPointer::Unconstrained::Reader Type::AnyPointer::Reader::getUnconstrained() const { + KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Unconstrained::Reader(_reader); +} +inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::getUnconstrained() { + KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Unconstrained::Builder(_builder); +} +inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::initUnconstrained() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::UNCONSTRAINED); + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Unconstrained::Builder(_builder); +} +inline bool Type::AnyPointer::Reader::isParameter() const { + return which() == Type::AnyPointer::PARAMETER; +} +inline bool Type::AnyPointer::Builder::isParameter() { + return which() == Type::AnyPointer::PARAMETER; +} +inline typename Type::AnyPointer::Parameter::Reader Type::AnyPointer::Reader::getParameter() const { + KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Parameter::Reader(_reader); +} +inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::getParameter() { + KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Parameter::Builder(_builder); +} +inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::initParameter() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::PARAMETER); + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Parameter::Builder(_builder); +} +inline bool Type::AnyPointer::Reader::isImplicitMethodParameter() const { + return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; +} +inline bool Type::AnyPointer::Builder::isImplicitMethodParameter() { + return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Reader Type::AnyPointer::Reader::getImplicitMethodParameter() const { + KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::ImplicitMethodParameter::Reader(_reader); +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::getImplicitMethodParameter() { + KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::initImplicitMethodParameter() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::IMPLICIT_METHOD_PARAMETER); + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); +} +inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isAnyKind() const { + return which() == Type::AnyPointer::Unconstrained::ANY_KIND; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isAnyKind() { + return which() == Type::AnyPointer::Unconstrained::ANY_KIND; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getAnyKind() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getAnyKind() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setAnyKind( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::ANY_KIND); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isStruct() const { + return which() == Type::AnyPointer::Unconstrained::STRUCT; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isStruct() { + return which() == Type::AnyPointer::Unconstrained::STRUCT; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getStruct() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getStruct() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setStruct( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::STRUCT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isList() const { + return which() == Type::AnyPointer::Unconstrained::LIST; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isList() { + return which() == Type::AnyPointer::Unconstrained::LIST; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getList() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getList() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setList( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::LIST); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isCapability() const { + return which() == Type::AnyPointer::Unconstrained::CAPABILITY; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isCapability() { + return which() == Type::AnyPointer::Unconstrained::CAPABILITY; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getCapability() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getCapability() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setCapability( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::CAPABILITY); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Type::AnyPointer::Parameter::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::AnyPointer::Parameter::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Parameter::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Type::AnyPointer::Parameter::Reader::getParameterIndex() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Type::AnyPointer::Parameter::Builder::getParameterIndex() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Parameter::Builder::setParameterIndex( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Reader::getParameterIndex() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Builder::getParameterIndex() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::ImplicitMethodParameter::Builder::setParameterIndex( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Reader::hasScopes() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Builder::hasScopes() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope>::Reader Brand::Reader::getScopes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder Brand::Builder::getScopes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Brand::Builder::setScopes( ::capnp::List< ::capnp::schema::Brand::Scope>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder Brand::Builder::initScopes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Brand::Builder::adoptScopes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>> Brand::Builder::disownScopes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Brand::Scope::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Brand::Scope::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Brand::Scope::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Scope::Reader::isBind() const { + return which() == Brand::Scope::BIND; +} +inline bool Brand::Scope::Builder::isBind() { + return which() == Brand::Scope::BIND; +} +inline bool Brand::Scope::Reader::hasBind() const { + if (which() != Brand::Scope::BIND) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Scope::Builder::hasBind() { + if (which() != Brand::Scope::BIND) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding>::Reader Brand::Scope::Reader::getBind() const { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder Brand::Scope::Builder::getBind() { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Brand::Scope::Builder::setBind( ::capnp::List< ::capnp::schema::Brand::Binding>::Reader value) { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder Brand::Scope::Builder::initBind(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Brand::Scope::Builder::adoptBind( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>>&& value) { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>> Brand::Scope::Builder::disownBind() { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Brand::Scope::Reader::isInherit() const { + return which() == Brand::Scope::INHERIT; +} +inline bool Brand::Scope::Builder::isInherit() { + return which() == Brand::Scope::INHERIT; +} +inline ::capnp::Void Brand::Scope::Reader::getInherit() const { + KJ_IREQUIRE((which() == Brand::Scope::INHERIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Brand::Scope::Builder::getInherit() { + KJ_IREQUIRE((which() == Brand::Scope::INHERIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Brand::Scope::Builder::setInherit( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::INHERIT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Brand::Binding::Reader::isUnbound() const { + return which() == Brand::Binding::UNBOUND; +} +inline bool Brand::Binding::Builder::isUnbound() { + return which() == Brand::Binding::UNBOUND; +} +inline ::capnp::Void Brand::Binding::Reader::getUnbound() const { + KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Brand::Binding::Builder::getUnbound() { + KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Brand::Binding::Builder::setUnbound( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::UNBOUND); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Binding::Reader::isType() const { + return which() == Brand::Binding::TYPE; +} +inline bool Brand::Binding::Builder::isType() { + return which() == Brand::Binding::TYPE; +} +inline bool Brand::Binding::Reader::hasType() const { + if (which() != Brand::Binding::TYPE) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Binding::Builder::hasType() { + if (which() != Brand::Binding::TYPE) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Brand::Binding::Reader::getType() const { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Brand::Binding::Builder::getType() { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Brand::Binding::Builder::setType( ::capnp::schema::Type::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Brand::Binding::Builder::initType() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Brand::Binding::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Brand::Binding::Builder::disownType() { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Value::Which Value::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Value::Which Value::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Value::Reader::isVoid() const { + return which() == Value::VOID; +} +inline bool Value::Builder::isVoid() { + return which() == Value::VOID; +} +inline ::capnp::Void Value::Reader::getVoid() const { + KJ_IREQUIRE((which() == Value::VOID), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Value::Builder::getVoid() { + KJ_IREQUIRE((which() == Value::VOID), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setVoid( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::VOID); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isBool() const { + return which() == Value::BOOL; +} +inline bool Value::Builder::isBool() { + return which() == Value::BOOL; +} +inline bool Value::Reader::getBool() const { + KJ_IREQUIRE((which() == Value::BOOL), + "Must check which() before get()ing a union member."); + return _reader.getDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS); +} + +inline bool Value::Builder::getBool() { + KJ_IREQUIRE((which() == Value::BOOL), + "Must check which() before get()ing a union member."); + return _builder.getDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setBool(bool value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::BOOL); + _builder.setDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt8() const { + return which() == Value::INT8; +} +inline bool Value::Builder::isInt8() { + return which() == Value::INT8; +} +inline ::int8_t Value::Reader::getInt8() const { + KJ_IREQUIRE((which() == Value::INT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::int8_t Value::Builder::getInt8() { + KJ_IREQUIRE((which() == Value::INT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt8( ::int8_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT8); + _builder.setDataField< ::int8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt16() const { + return which() == Value::INT16; +} +inline bool Value::Builder::isInt16() { + return which() == Value::INT16; +} +inline ::int16_t Value::Reader::getInt16() const { + KJ_IREQUIRE((which() == Value::INT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int16_t Value::Builder::getInt16() { + KJ_IREQUIRE((which() == Value::INT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt16( ::int16_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT16); + _builder.setDataField< ::int16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt32() const { + return which() == Value::INT32; +} +inline bool Value::Builder::isInt32() { + return which() == Value::INT32; +} +inline ::int32_t Value::Reader::getInt32() const { + KJ_IREQUIRE((which() == Value::INT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int32_t Value::Builder::getInt32() { + KJ_IREQUIRE((which() == Value::INT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt32( ::int32_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT32); + _builder.setDataField< ::int32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt64() const { + return which() == Value::INT64; +} +inline bool Value::Builder::isInt64() { + return which() == Value::INT64; +} +inline ::int64_t Value::Reader::getInt64() const { + KJ_IREQUIRE((which() == Value::INT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Value::Builder::getInt64() { + KJ_IREQUIRE((which() == Value::INT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt64( ::int64_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT64); + _builder.setDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint8() const { + return which() == Value::UINT8; +} +inline bool Value::Builder::isUint8() { + return which() == Value::UINT8; +} +inline ::uint8_t Value::Reader::getUint8() const { + KJ_IREQUIRE((which() == Value::UINT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint8_t Value::Builder::getUint8() { + KJ_IREQUIRE((which() == Value::UINT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint8( ::uint8_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT8); + _builder.setDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint16() const { + return which() == Value::UINT16; +} +inline bool Value::Builder::isUint16() { + return which() == Value::UINT16; +} +inline ::uint16_t Value::Reader::getUint16() const { + KJ_IREQUIRE((which() == Value::UINT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Value::Builder::getUint16() { + KJ_IREQUIRE((which() == Value::UINT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint16( ::uint16_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT16); + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint32() const { + return which() == Value::UINT32; +} +inline bool Value::Builder::isUint32() { + return which() == Value::UINT32; +} +inline ::uint32_t Value::Reader::getUint32() const { + KJ_IREQUIRE((which() == Value::UINT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Value::Builder::getUint32() { + KJ_IREQUIRE((which() == Value::UINT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint32( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT32); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint64() const { + return which() == Value::UINT64; +} +inline bool Value::Builder::isUint64() { + return which() == Value::UINT64; +} +inline ::uint64_t Value::Reader::getUint64() const { + KJ_IREQUIRE((which() == Value::UINT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Value::Builder::getUint64() { + KJ_IREQUIRE((which() == Value::UINT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint64( ::uint64_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT64); + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isFloat32() const { + return which() == Value::FLOAT32; +} +inline bool Value::Builder::isFloat32() { + return which() == Value::FLOAT32; +} +inline float Value::Reader::getFloat32() const { + KJ_IREQUIRE((which() == Value::FLOAT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline float Value::Builder::getFloat32() { + KJ_IREQUIRE((which() == Value::FLOAT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setFloat32(float value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::FLOAT32); + _builder.setDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isFloat64() const { + return which() == Value::FLOAT64; +} +inline bool Value::Builder::isFloat64() { + return which() == Value::FLOAT64; +} +inline double Value::Reader::getFloat64() const { + KJ_IREQUIRE((which() == Value::FLOAT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline double Value::Builder::getFloat64() { + KJ_IREQUIRE((which() == Value::FLOAT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setFloat64(double value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::FLOAT64); + _builder.setDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isText() const { + return which() == Value::TEXT; +} +inline bool Value::Builder::isText() { + return which() == Value::TEXT; +} +inline bool Value::Reader::hasText() const { + if (which() != Value::TEXT) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasText() { + if (which() != Value::TEXT) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Value::Reader::getText() const { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Value::Builder::getText() { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Value::Builder::setText( ::capnp::Text::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Value::Builder::initText(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Value::Builder::adoptText( + ::capnp::Orphan< ::capnp::Text>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Value::Builder::disownText() { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Value::Reader::isData() const { + return which() == Value::DATA; +} +inline bool Value::Builder::isData() { + return which() == Value::DATA; +} +inline bool Value::Reader::hasData() const { + if (which() != Value::DATA) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasData() { + if (which() != Value::DATA) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Data::Reader Value::Reader::getData() const { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Data::Builder Value::Builder::getData() { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Value::Builder::setData( ::capnp::Data::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); + ::capnp::_::PointerHelpers< ::capnp::Data>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Data::Builder Value::Builder::initData(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); + return ::capnp::_::PointerHelpers< ::capnp::Data>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Value::Builder::adoptData( + ::capnp::Orphan< ::capnp::Data>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); + ::capnp::_::PointerHelpers< ::capnp::Data>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Data> Value::Builder::disownData() { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Value::Reader::isList() const { + return which() == Value::LIST; +} +inline bool Value::Builder::isList() { + return which() == Value::LIST; +} +inline bool Value::Reader::hasList() const { + if (which() != Value::LIST) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasList() { + if (which() != Value::LIST) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getList() const { + KJ_IREQUIRE((which() == Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getList() { + KJ_IREQUIRE((which() == Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initList() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::LIST); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Value::Reader::isEnum() const { + return which() == Value::ENUM; +} +inline bool Value::Builder::isEnum() { + return which() == Value::ENUM; +} +inline ::uint16_t Value::Reader::getEnum() const { + KJ_IREQUIRE((which() == Value::ENUM), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Value::Builder::getEnum() { + KJ_IREQUIRE((which() == Value::ENUM), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setEnum( ::uint16_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ENUM); + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isStruct() const { + return which() == Value::STRUCT; +} +inline bool Value::Builder::isStruct() { + return which() == Value::STRUCT; +} +inline bool Value::Reader::hasStruct() const { + if (which() != Value::STRUCT) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasStruct() { + if (which() != Value::STRUCT) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getStruct() const { + KJ_IREQUIRE((which() == Value::STRUCT), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getStruct() { + KJ_IREQUIRE((which() == Value::STRUCT), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initStruct() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::STRUCT); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Value::Reader::isInterface() const { + return which() == Value::INTERFACE; +} +inline bool Value::Builder::isInterface() { + return which() == Value::INTERFACE; +} +inline ::capnp::Void Value::Reader::getInterface() const { + KJ_IREQUIRE((which() == Value::INTERFACE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Value::Builder::getInterface() { + KJ_IREQUIRE((which() == Value::INTERFACE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInterface( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INTERFACE); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isAnyPointer() const { + return which() == Value::ANY_POINTER; +} +inline bool Value::Builder::isAnyPointer() { + return which() == Value::ANY_POINTER; +} +inline bool Value::Reader::hasAnyPointer() const { + if (which() != Value::ANY_POINTER) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasAnyPointer() { + if (which() != Value::ANY_POINTER) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getAnyPointer() const { + KJ_IREQUIRE((which() == Value::ANY_POINTER), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getAnyPointer() { + KJ_IREQUIRE((which() == Value::ANY_POINTER), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initAnyPointer() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ANY_POINTER); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint64_t Annotation::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Annotation::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Annotation::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Annotation::Reader::hasValue() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Annotation::Builder::hasValue() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Annotation::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Annotation::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Annotation::Pipeline::getValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Annotation::Builder::setValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Annotation::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Annotation::Builder::adoptValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Annotation::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Annotation::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Annotation::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Annotation::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Annotation::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Annotation::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Annotation::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Annotation::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Annotation::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Annotation::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint16_t CapnpVersion::Reader::getMajor() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t CapnpVersion::Builder::getMajor() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CapnpVersion::Builder::setMajor( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint8_t CapnpVersion::Reader::getMinor() const { + return _reader.getDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint8_t CapnpVersion::Builder::getMinor() { + return _builder.getDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void CapnpVersion::Builder::setMinor( ::uint8_t value) { + _builder.setDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint8_t CapnpVersion::Reader::getMicro() const { + return _reader.getDataField< ::uint8_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} + +inline ::uint8_t CapnpVersion::Builder::getMicro() { + return _builder.getDataField< ::uint8_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} +inline void CapnpVersion::Builder::setMicro( ::uint8_t value) { + _builder.setDataField< ::uint8_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, value); +} + +inline bool CodeGeneratorRequest::Reader::hasNodes() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasNodes() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node>::Reader CodeGeneratorRequest::Reader::getNodes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node>::Builder CodeGeneratorRequest::Builder::getNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::setNodes( ::capnp::List< ::capnp::schema::Node>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node>::Builder CodeGeneratorRequest::Builder::initNodes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::Builder::adoptNodes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>> CodeGeneratorRequest::Builder::disownNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::Reader::hasRequestedFiles() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasRequestedFiles() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader CodeGeneratorRequest::Reader::getRequestedFiles() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder CodeGeneratorRequest::Builder::getRequestedFiles() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder CodeGeneratorRequest::Builder::initRequestedFiles(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::Builder::adoptRequestedFiles( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>> CodeGeneratorRequest::Builder::disownRequestedFiles() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::Reader::hasCapnpVersion() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasCapnpVersion() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::CapnpVersion::Reader CodeGeneratorRequest::Reader::getCapnpVersion() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::CapnpVersion::Builder CodeGeneratorRequest::Builder::getCapnpVersion() { + return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::CapnpVersion::Pipeline CodeGeneratorRequest::Pipeline::getCapnpVersion() { + return ::capnp::schema::CapnpVersion::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void CodeGeneratorRequest::Builder::setCapnpVersion( ::capnp::schema::CapnpVersion::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::CapnpVersion::Builder CodeGeneratorRequest::Builder::initCapnpVersion() { + return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::adoptCapnpVersion( + ::capnp::Orphan< ::capnp::schema::CapnpVersion>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::CapnpVersion> CodeGeneratorRequest::Builder::disownCapnpVersion() { + return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CodeGeneratorRequest::RequestedFile::Reader::hasFilename() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Builder::hasFilename() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Reader::getFilename() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::getFilename() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setFilename( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::initFilename(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::adoptFilename( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Builder::disownFilename() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::RequestedFile::Reader::hasImports() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Builder::hasImports() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader CodeGeneratorRequest::RequestedFile::Reader::getImports() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder CodeGeneratorRequest::RequestedFile::Builder::getImports() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder CodeGeneratorRequest::RequestedFile::Builder::initImports(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::adoptImports( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>> CodeGeneratorRequest::RequestedFile::Builder::disownImports() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CodeGeneratorRequest::RequestedFile::Import::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Import::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Import::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Import::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +#endif // CAPNP_INCLUDED_a93fc509624c72d9_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/schema.h --- a/win32-mingw/include/capnp/schema.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/schema.h Tue May 23 09:16:54 2017 +0100 @@ -1,934 +1,934 @@ -// 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. - -#ifndef CAPNP_SCHEMA_H_ -#define CAPNP_SCHEMA_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#if CAPNP_LITE -#error "Reflection APIs, including this header, are not available in lite mode." -#endif - -#include - -namespace capnp { - -class Schema; -class StructSchema; -class EnumSchema; -class InterfaceSchema; -class ConstSchema; -class ListSchema; -class Type; - -template ()> struct SchemaType_ { typedef Schema Type; }; -template struct SchemaType_ { typedef schema::Type::Which Type; }; -template struct SchemaType_ { typedef schema::Type::Which Type; }; -template struct SchemaType_ { typedef EnumSchema Type; }; -template struct SchemaType_ { typedef StructSchema Type; }; -template struct SchemaType_ { typedef InterfaceSchema Type; }; -template struct SchemaType_ { typedef ListSchema Type; }; - -template -using SchemaType = typename SchemaType_::Type; -// SchemaType is the type of T's schema, e.g. StructSchema if T is a struct. - -namespace _ { // private -extern const RawSchema NULL_SCHEMA; -extern const RawSchema NULL_STRUCT_SCHEMA; -extern const RawSchema NULL_ENUM_SCHEMA; -extern const RawSchema NULL_INTERFACE_SCHEMA; -extern const RawSchema NULL_CONST_SCHEMA; -// The schema types default to these null (empty) schemas in case of error, especially when -// exceptions are disabled. -} // namespace _ (private) - -class Schema { - // Convenience wrapper around capnp::schema::Node. - -public: - inline Schema(): raw(&_::NULL_SCHEMA.defaultBrand) {} - - template - static inline SchemaType from() { return SchemaType::template fromImpl(); } - // Get the Schema for a particular compiled-in type. - - schema::Node::Reader getProto() const; - // Get the underlying Cap'n Proto representation of the schema node. (Note that this accessor - // has performance comparable to accessors of struct-typed fields on Reader classes.) - - kj::ArrayPtr asUncheckedMessage() const; - // Get the encoded schema node content as a single message segment. It is safe to read as an - // unchecked message. - - Schema getDependency(uint64_t id) const KJ_DEPRECATED("Does not handle generics correctly."); - // DEPRECATED: This method cannot correctly account for generic type parameter bindings that - // may apply to the dependency. Instead of using this method, use a method of the Schema API - // that corresponds to the exact kind of dependency. For example, to get a field type, use - // StructSchema::Field::getType(). - // - // Gets the Schema for one of this Schema's dependencies. For example, if this Schema is for a - // struct, you could look up the schema for one of its fields' types. Throws an exception if this - // schema doesn't actually depend on the given id. - // - // Note that not all type IDs found in the schema node are considered "dependencies" -- only the - // ones that are needed to implement the dynamic API are. That includes: - // - Field types. - // - Group types. - // - scopeId for group nodes, but NOT otherwise. - // - Method parameter and return types. - // - // The following are NOT considered dependencies: - // - Nested nodes. - // - scopeId for a non-group node. - // - Annotations. - // - // To obtain schemas for those, you would need a SchemaLoader. - - bool isBranded() const; - // Returns true if this schema represents a non-default parameterization of this type. - - Schema getGeneric() const; - // Get the version of this schema with any brands removed. - - class BrandArgumentList; - BrandArgumentList getBrandArgumentsAtScope(uint64_t scopeId) const; - // Gets the values bound to the brand parameters at the given scope. - - StructSchema asStruct() const; - EnumSchema asEnum() const; - InterfaceSchema asInterface() const; - ConstSchema asConst() const; - // Cast the Schema to a specific type. Throws an exception if the type doesn't match. Use - // getProto() to determine type, e.g. getProto().isStruct(). - - inline bool operator==(const Schema& other) const { return raw == other.raw; } - inline bool operator!=(const Schema& other) const { return raw != other.raw; } - // Determine whether two Schemas are wrapping the exact same underlying data, by identity. If - // you want to check if two Schemas represent the same type (but possibly different versions of - // it), compare their IDs instead. - - template - void requireUsableAs() const; - // Throws an exception if a value with this Schema cannot safely be cast to a native value of - // the given type. This passes if either: - // - *this == from() - // - This schema was loaded with SchemaLoader, the type ID matches typeId(), and - // loadCompiledTypeAndDependencies() was called on the SchemaLoader. - - kj::StringPtr getShortDisplayName() const; - // Get the short version of the node's display name. - -private: - const _::RawBrandedSchema* raw; - - inline explicit Schema(const _::RawBrandedSchema* raw): raw(raw) { - KJ_IREQUIRE(raw->lazyInitializer == nullptr, - "Must call ensureInitialized() on RawSchema before constructing Schema."); - } - - template static inline Schema fromImpl() { - return Schema(&_::rawSchema()); - } - - void requireUsableAs(const _::RawSchema* expected) const; - - uint32_t getSchemaOffset(const schema::Value::Reader& value) const; - - Type getBrandBinding(uint64_t scopeId, uint index) const; - // Look up the binding for a brand parameter used by this Schema. Returns `AnyPointer` if the - // parameter is not bound. - // - // TODO(someday): Public interface for iterating over all bindings? - - Schema getDependency(uint64_t id, uint location) const; - // Look up schema for a particular dependency of this schema. `location` is the dependency - // location number as defined in _::RawBrandedSchema. - - Type interpretType(schema::Type::Reader proto, uint location) const; - // Interpret a schema::Type in the given location within the schema, compiling it into a - // Type object. - - friend class StructSchema; - friend class EnumSchema; - friend class InterfaceSchema; - friend class ConstSchema; - friend class ListSchema; - friend class SchemaLoader; - friend class Type; - friend kj::StringTree _::structString( - _::StructReader reader, const _::RawBrandedSchema& schema); - friend kj::String _::enumString(uint16_t value, const _::RawBrandedSchema& schema); -}; - -kj::StringPtr KJ_STRINGIFY(const Schema& schema); - -class Schema::BrandArgumentList { - // A list of generic parameter bindings for parameters of some particular type. Note that since - // parameters on an outer type apply to all inner types as well, a deeply-nested type can have - // multiple BrandArgumentLists that apply to it. - // - // A BrandArgumentList only represents the arguments that the client of the type specified. Since - // new parameters can be added over time, this list may not cover all defined parameters for the - // type. Missing parameters should be treated as AnyPointer. This class's implementation of - // operator[] already does this for you; out-of-bounds access will safely return AnyPointer. - -public: - inline BrandArgumentList(): scopeId(0), size_(0), bindings(nullptr) {} - - inline uint size() const { return size_; } - Type operator[](uint index) const; - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - uint64_t scopeId; - uint size_; - bool isUnbound; - const _::RawBrandedSchema::Binding* bindings; - - inline BrandArgumentList(uint64_t scopeId, bool isUnbound) - : scopeId(scopeId), size_(0), isUnbound(isUnbound), bindings(nullptr) {} - inline BrandArgumentList(uint64_t scopeId, uint size, - const _::RawBrandedSchema::Binding* bindings) - : scopeId(scopeId), size_(size), isUnbound(false), bindings(bindings) {} - - friend class Schema; -}; - -// ------------------------------------------------------------------- - -class StructSchema: public Schema { -public: - inline StructSchema(): Schema(&_::NULL_STRUCT_SCHEMA.defaultBrand) {} - - class Field; - class FieldList; - class FieldSubset; - - FieldList getFields() const; - // List top-level fields of this struct. This list will contain top-level groups (including - // named unions) but not the members of those groups. The list does, however, contain the - // members of the unnamed union, if there is one. - - FieldSubset getUnionFields() const; - // If the field contains an unnamed union, get a list of fields in the union, ordered by - // ordinal. Since discriminant values are assigned sequentially by ordinal, you may index this - // list by discriminant value. - - FieldSubset getNonUnionFields() const; - // Get the fields of this struct which are not in an unnamed union, ordered by ordinal. - - kj::Maybe findFieldByName(kj::StringPtr name) const; - // Find the field with the given name, or return null if there is no such field. If the struct - // contains an unnamed union, then this will find fields of that union in addition to fields - // of the outer struct, since they exist in the same namespace. It will not, however, find - // members of groups (including named unions) -- you must first look up the group itself, - // then dig into its type. - - Field getFieldByName(kj::StringPtr name) const; - // Like findFieldByName() but throws an exception on failure. - - kj::Maybe getFieldByDiscriminant(uint16_t discriminant) const; - // Finds the field whose `discriminantValue` is equal to the given value, or returns null if - // there is no such field. (If the schema does not represent a union or a struct containing - // an unnamed union, then this always returns null.) - -private: - StructSchema(Schema base): Schema(base) {} - template static inline StructSchema fromImpl() { - return StructSchema(Schema(&_::rawBrandedSchema())); - } - friend class Schema; - friend class Type; -}; - -class StructSchema::Field { -public: - Field() = default; - - inline schema::Field::Reader getProto() const { return proto; } - inline StructSchema getContainingStruct() const { return parent; } - - inline uint getIndex() const { return index; } - // Get the index of this field within the containing struct or union. - - Type getType() const; - // Get the type of this field. Note that this is preferred over getProto().getType() as this - // method will apply generics. - - uint32_t getDefaultValueSchemaOffset() const; - // For struct, list, and object fields, returns the offset, in words, within the first segment of - // the struct's schema, where this field's default value pointer is located. The schema is - // always stored as a single-segment unchecked message, which in turn means that the default - // value pointer itself can be treated as the root of an unchecked message -- if you know where - // to find it, which is what this method helps you with. - // - // For blobs, returns the offset of the beginning of the blob's content within the first segment - // of the struct's schema. - // - // This is primarily useful for code generators. The C++ code generator, for example, embeds - // the entire schema as a raw word array within the generated code. Of course, to implement - // field accessors, it needs access to those fields' default values. Embedding separate copies - // of those default values would be redundant since they are already included in the schema, but - // seeking through the schema at runtime to find the default values would be ugly. Instead, - // the code generator can use getDefaultValueSchemaOffset() to find the offset of the default - // value within the schema, and can simply apply that offset at runtime. - // - // If the above does not make sense, you probably don't need this method. - - inline bool operator==(const Field& other) const; - inline bool operator!=(const Field& other) const { return !(*this == other); } - -private: - StructSchema parent; - uint index; - schema::Field::Reader proto; - - inline Field(StructSchema parent, uint index, schema::Field::Reader proto) - : parent(parent), index(index), proto(proto) {} - - friend class StructSchema; -}; - -kj::StringPtr KJ_STRINGIFY(const StructSchema::Field& field); - -class StructSchema::FieldList { -public: - FieldList() = default; // empty list - - inline uint size() const { return list.size(); } - inline Field operator[](uint index) const { return Field(parent, index, list[index]); } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - StructSchema parent; - List::Reader list; - - inline FieldList(StructSchema parent, List::Reader list) - : parent(parent), list(list) {} - - friend class StructSchema; -}; - -class StructSchema::FieldSubset { -public: - FieldSubset() = default; // empty list - - inline uint size() const { return size_; } - inline Field operator[](uint index) const { - return Field(parent, indices[index], list[indices[index]]); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - StructSchema parent; - List::Reader list; - const uint16_t* indices; - uint size_; - - inline FieldSubset(StructSchema parent, List::Reader list, - const uint16_t* indices, uint size) - : parent(parent), list(list), indices(indices), size_(size) {} - - friend class StructSchema; -}; - -// ------------------------------------------------------------------- - -class EnumSchema: public Schema { -public: - inline EnumSchema(): Schema(&_::NULL_ENUM_SCHEMA.defaultBrand) {} - - class Enumerant; - class EnumerantList; - - EnumerantList getEnumerants() const; - - kj::Maybe findEnumerantByName(kj::StringPtr name) const; - - Enumerant getEnumerantByName(kj::StringPtr name) const; - // Like findEnumerantByName() but throws an exception on failure. - -private: - EnumSchema(Schema base): Schema(base) {} - template static inline EnumSchema fromImpl() { - return EnumSchema(Schema(&_::rawBrandedSchema())); - } - friend class Schema; - friend class Type; -}; - -class EnumSchema::Enumerant { -public: - Enumerant() = default; - - inline schema::Enumerant::Reader getProto() const { return proto; } - inline EnumSchema getContainingEnum() const { return parent; } - - inline uint16_t getOrdinal() const { return ordinal; } - inline uint getIndex() const { return ordinal; } - - inline bool operator==(const Enumerant& other) const; - inline bool operator!=(const Enumerant& other) const { return !(*this == other); } - -private: - EnumSchema parent; - uint16_t ordinal; - schema::Enumerant::Reader proto; - - inline Enumerant(EnumSchema parent, uint16_t ordinal, schema::Enumerant::Reader proto) - : parent(parent), ordinal(ordinal), proto(proto) {} - - friend class EnumSchema; -}; - -class EnumSchema::EnumerantList { -public: - EnumerantList() = default; // empty list - - inline uint size() const { return list.size(); } - inline Enumerant operator[](uint index) const { return Enumerant(parent, index, list[index]); } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - EnumSchema parent; - List::Reader list; - - inline EnumerantList(EnumSchema parent, List::Reader list) - : parent(parent), list(list) {} - - friend class EnumSchema; -}; - -// ------------------------------------------------------------------- - -class InterfaceSchema: public Schema { -public: - inline InterfaceSchema(): Schema(&_::NULL_INTERFACE_SCHEMA.defaultBrand) {} - - class Method; - class MethodList; - - MethodList getMethods() const; - - kj::Maybe findMethodByName(kj::StringPtr name) const; - - Method getMethodByName(kj::StringPtr name) const; - // Like findMethodByName() but throws an exception on failure. - - class SuperclassList; - - SuperclassList getSuperclasses() const; - // Get the immediate superclasses of this type, after applying generics. - - bool extends(InterfaceSchema other) const; - // Returns true if `other` is a superclass of this interface (including if `other == *this`). - - kj::Maybe findSuperclass(uint64_t typeId) const; - // Find the superclass of this interface with the given type ID. Returns null if the interface - // extends no such type. - -private: - InterfaceSchema(Schema base): Schema(base) {} - template static inline InterfaceSchema fromImpl() { - return InterfaceSchema(Schema(&_::rawBrandedSchema())); - } - friend class Schema; - friend class Type; - - kj::Maybe findMethodByName(kj::StringPtr name, uint& counter) const; - bool extends(InterfaceSchema other, uint& counter) const; - kj::Maybe findSuperclass(uint64_t typeId, uint& counter) const; - // We protect against malicious schemas with large or cyclic hierarchies by cutting off the - // search when the counter reaches a threshold. -}; - -class InterfaceSchema::Method { -public: - Method() = default; - - inline schema::Method::Reader getProto() const { return proto; } - inline InterfaceSchema getContainingInterface() const { return parent; } - - inline uint16_t getOrdinal() const { return ordinal; } - inline uint getIndex() const { return ordinal; } - - StructSchema getParamType() const; - StructSchema getResultType() const; - // Get the parameter and result types, including substituting generic parameters. - - inline bool operator==(const Method& other) const; - inline bool operator!=(const Method& other) const { return !(*this == other); } - -private: - InterfaceSchema parent; - uint16_t ordinal; - schema::Method::Reader proto; - - inline Method(InterfaceSchema parent, uint16_t ordinal, - schema::Method::Reader proto) - : parent(parent), ordinal(ordinal), proto(proto) {} - - friend class InterfaceSchema; -}; - -class InterfaceSchema::MethodList { -public: - MethodList() = default; // empty list - - inline uint size() const { return list.size(); } - inline Method operator[](uint index) const { return Method(parent, index, list[index]); } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - InterfaceSchema parent; - List::Reader list; - - inline MethodList(InterfaceSchema parent, List::Reader list) - : parent(parent), list(list) {} - - friend class InterfaceSchema; -}; - -class InterfaceSchema::SuperclassList { -public: - SuperclassList() = default; // empty list - - inline uint size() const { return list.size(); } - InterfaceSchema operator[](uint index) const; - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - InterfaceSchema parent; - List::Reader list; - - inline SuperclassList(InterfaceSchema parent, List::Reader list) - : parent(parent), list(list) {} - - friend class InterfaceSchema; -}; - -// ------------------------------------------------------------------- - -class ConstSchema: public Schema { - // Represents a constant declaration. - // - // `ConstSchema` can be implicitly cast to DynamicValue to read its value. - -public: - inline ConstSchema(): Schema(&_::NULL_CONST_SCHEMA.defaultBrand) {} - - template - ReaderFor as() const; - // Read the constant's value. This is a convenience method equivalent to casting the ConstSchema - // to a DynamicValue and then calling its `as()` method. For dependency reasons, this method - // is defined in , which you must #include explicitly. - - uint32_t getValueSchemaOffset() const; - // Much like StructSchema::Field::getDefaultValueSchemaOffset(), if the constant has pointer - // type, this gets the offset from the beginning of the constant's schema node to a pointer - // representing the constant value. - - Type getType() const; - -private: - ConstSchema(Schema base): Schema(base) {} - friend class Schema; -}; - -// ------------------------------------------------------------------- - -class Type { -public: - struct BrandParameter { - uint64_t scopeId; - uint index; - }; - struct ImplicitParameter { - uint index; - }; - - inline Type(); - inline Type(schema::Type::Which primitive); - inline Type(StructSchema schema); - inline Type(EnumSchema schema); - inline Type(InterfaceSchema schema); - inline Type(ListSchema schema); - inline Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind); - inline Type(BrandParameter param); - inline Type(ImplicitParameter param); - - template - inline static Type from(); - - inline schema::Type::Which which() const; - - StructSchema asStruct() const; - EnumSchema asEnum() const; - InterfaceSchema asInterface() const; - ListSchema asList() const; - // Each of these methods may only be called if which() returns the corresponding type. - - kj::Maybe getBrandParameter() const; - // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular - // AnyPointer and not a parameter. - - kj::Maybe getImplicitParameter() const; - // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular - // AnyPointer and not a parameter. "Implicit parameters" refer to type parameters on methods. - - inline schema::Type::AnyPointer::Unconstrained::Which whichAnyPointerKind() const; - // Only callable if which() returns ANY_POINTER. - - inline bool isVoid() const; - inline bool isBool() const; - inline bool isInt8() const; - inline bool isInt16() const; - inline bool isInt32() const; - inline bool isInt64() const; - inline bool isUInt8() const; - inline bool isUInt16() const; - inline bool isUInt32() const; - inline bool isUInt64() const; - inline bool isFloat32() const; - inline bool isFloat64() const; - inline bool isText() const; - inline bool isData() const; - inline bool isList() const; - inline bool isEnum() const; - inline bool isStruct() const; - inline bool isInterface() const; - inline bool isAnyPointer() const; - - bool operator==(const Type& other) const; - inline bool operator!=(const Type& other) const { return !(*this == other); } - - size_t hashCode() const; - - inline Type wrapInList(uint depth = 1) const; - // Return the Type formed by wrapping this type in List() `depth` times. - - inline Type(schema::Type::Which derived, const _::RawBrandedSchema* schema); - // For internal use. - -private: - schema::Type::Which baseType; // type not including applications of List() - uint8_t listDepth; // 0 for T, 1 for List(T), 2 for List(List(T)), ... - - bool isImplicitParam; - // If true, this refers to an implicit method parameter. baseType must be ANY_POINTER, scopeId - // must be zero, and paramIndex indicates the parameter index. - - union { - uint16_t paramIndex; - // If baseType is ANY_POINTER but this Type actually refers to a type parameter, this is the - // index of the parameter among the parameters at its scope, and `scopeId` below is the type ID - // of the scope where the parameter was defined. - - schema::Type::AnyPointer::Unconstrained::Which anyPointerKind; - // If scopeId is zero and isImplicitParam is false. - }; - - union { - const _::RawBrandedSchema* schema; // if type is struct, enum, interface... - uint64_t scopeId; // if type is AnyPointer but it's actually a type parameter... - }; - - Type(schema::Type::Which baseType, uint8_t listDepth, const _::RawBrandedSchema* schema) - : baseType(baseType), listDepth(listDepth), schema(schema) { - KJ_IREQUIRE(baseType != schema::Type::ANY_POINTER); - } - - void requireUsableAs(Type expected) const; - - friend class ListSchema; // only for requireUsableAs() -}; - -// ------------------------------------------------------------------- - -class ListSchema { - // ListSchema is a little different because list types are not described by schema nodes. So, - // ListSchema doesn't subclass Schema. - -public: - ListSchema() = default; - - static ListSchema of(schema::Type::Which primitiveType); - static ListSchema of(StructSchema elementType); - static ListSchema of(EnumSchema elementType); - static ListSchema of(InterfaceSchema elementType); - static ListSchema of(ListSchema elementType); - static ListSchema of(Type elementType); - // Construct the schema for a list of the given type. - - static ListSchema of(schema::Type::Reader elementType, Schema context) - KJ_DEPRECATED("Does not handle generics correctly."); - // DEPRECATED: This method cannot correctly account for generic type parameter bindings that - // may apply to the input type. Instead of using this method, use a method of the Schema API - // that corresponds to the exact kind of dependency. For example, to get a field type, use - // StructSchema::Field::getType(). - // - // Construct from an element type schema. Requires a context which can handle getDependency() - // requests for any type ID found in the schema. - - Type getElementType() const; - - inline schema::Type::Which whichElementType() const; - // Get the element type's "which()". ListSchema does not actually store a schema::Type::Reader - // describing the element type, but if it did, this would be equivalent to calling - // .getBody().which() on that type. - - StructSchema getStructElementType() const; - EnumSchema getEnumElementType() const; - InterfaceSchema getInterfaceElementType() const; - ListSchema getListElementType() const; - // Get the schema for complex element types. Each of these throws an exception if the element - // type is not of the requested kind. - - inline bool operator==(const ListSchema& other) const { return elementType == other.elementType; } - inline bool operator!=(const ListSchema& other) const { return elementType != other.elementType; } - - template - void requireUsableAs() const; - -private: - Type elementType; - - inline explicit ListSchema(Type elementType): elementType(elementType) {} - - template - struct FromImpl; - template static inline ListSchema fromImpl() { - return FromImpl::get(); - } - - void requireUsableAs(ListSchema expected) const; - - friend class Schema; -}; - -// ======================================================================================= -// inline implementation - -template <> inline schema::Type::Which Schema::from() { return schema::Type::VOID; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::BOOL; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::INT8; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::INT16; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::INT32; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::INT64; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT8; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT16; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT32; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT64; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::FLOAT32; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::FLOAT64; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::TEXT; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::DATA; } - -inline Schema Schema::getDependency(uint64_t id) const { - return getDependency(id, 0); -} - -inline bool Schema::isBranded() const { - return raw != &raw->generic->defaultBrand; -} - -inline Schema Schema::getGeneric() const { - return Schema(&raw->generic->defaultBrand); -} - -template -inline void Schema::requireUsableAs() const { - requireUsableAs(&_::rawSchema()); -} - -inline bool StructSchema::Field::operator==(const Field& other) const { - return parent == other.parent && index == other.index; -} -inline bool EnumSchema::Enumerant::operator==(const Enumerant& other) const { - return parent == other.parent && ordinal == other.ordinal; -} -inline bool InterfaceSchema::Method::operator==(const Method& other) const { - return parent == other.parent && ordinal == other.ordinal; -} - -inline ListSchema ListSchema::of(StructSchema elementType) { - return ListSchema(Type(elementType)); -} -inline ListSchema ListSchema::of(EnumSchema elementType) { - return ListSchema(Type(elementType)); -} -inline ListSchema ListSchema::of(InterfaceSchema elementType) { - return ListSchema(Type(elementType)); -} -inline ListSchema ListSchema::of(ListSchema elementType) { - return ListSchema(Type(elementType)); -} -inline ListSchema ListSchema::of(Type elementType) { - return ListSchema(elementType); -} - -inline Type ListSchema::getElementType() const { - return elementType; -} - -inline schema::Type::Which ListSchema::whichElementType() const { - return elementType.which(); -} - -inline StructSchema ListSchema::getStructElementType() const { - return elementType.asStruct(); -} - -inline EnumSchema ListSchema::getEnumElementType() const { - return elementType.asEnum(); -} - -inline InterfaceSchema ListSchema::getInterfaceElementType() const { - return elementType.asInterface(); -} - -inline ListSchema ListSchema::getListElementType() const { - return elementType.asList(); -} - -template -inline void ListSchema::requireUsableAs() const { - static_assert(kind() == Kind::LIST, - "ListSchema::requireUsableAs() requires T is a list type."); - requireUsableAs(Schema::from()); -} - -inline void ListSchema::requireUsableAs(ListSchema expected) const { - elementType.requireUsableAs(expected.elementType); -} - -template -struct ListSchema::FromImpl> { - static inline ListSchema get() { return of(Schema::from()); } -}; - -inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {} -inline Type::Type(schema::Type::Which primitive) - : baseType(primitive), listDepth(0), isImplicitParam(false) { - KJ_IREQUIRE(primitive != schema::Type::STRUCT && - primitive != schema::Type::ENUM && - primitive != schema::Type::INTERFACE && - primitive != schema::Type::LIST); - if (primitive == schema::Type::ANY_POINTER) { - scopeId = 0; - anyPointerKind = schema::Type::AnyPointer::Unconstrained::ANY_KIND; - } else { - schema = nullptr; - } -} -inline Type::Type(schema::Type::Which derived, const _::RawBrandedSchema* schema) - : baseType(derived), listDepth(0), isImplicitParam(false), schema(schema) { - KJ_IREQUIRE(derived == schema::Type::STRUCT || - derived == schema::Type::ENUM || - derived == schema::Type::INTERFACE); -} - -inline Type::Type(StructSchema schema) - : baseType(schema::Type::STRUCT), listDepth(0), schema(schema.raw) {} -inline Type::Type(EnumSchema schema) - : baseType(schema::Type::ENUM), listDepth(0), schema(schema.raw) {} -inline Type::Type(InterfaceSchema schema) - : baseType(schema::Type::INTERFACE), listDepth(0), schema(schema.raw) {} -inline Type::Type(ListSchema schema) - : Type(schema.getElementType()) { ++listDepth; } -inline Type::Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind) - : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), - anyPointerKind(anyPointerKind), scopeId(0) {} -inline Type::Type(BrandParameter param) - : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), - paramIndex(param.index), scopeId(param.scopeId) {} -inline Type::Type(ImplicitParameter param) - : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(true), - paramIndex(param.index), scopeId(0) {} - -inline schema::Type::Which Type::which() const { - return listDepth > 0 ? schema::Type::LIST : baseType; -} - -inline schema::Type::AnyPointer::Unconstrained::Which Type::whichAnyPointerKind() const { - KJ_IREQUIRE(baseType == schema::Type::ANY_POINTER); - return !isImplicitParam && scopeId == 0 ? anyPointerKind - : schema::Type::AnyPointer::Unconstrained::ANY_KIND; -} - -template -inline Type Type::from() { return Type(Schema::from()); } - -inline bool Type::isVoid () const { return baseType == schema::Type::VOID && listDepth == 0; } -inline bool Type::isBool () const { return baseType == schema::Type::BOOL && listDepth == 0; } -inline bool Type::isInt8 () const { return baseType == schema::Type::INT8 && listDepth == 0; } -inline bool Type::isInt16 () const { return baseType == schema::Type::INT16 && listDepth == 0; } -inline bool Type::isInt32 () const { return baseType == schema::Type::INT32 && listDepth == 0; } -inline bool Type::isInt64 () const { return baseType == schema::Type::INT64 && listDepth == 0; } -inline bool Type::isUInt8 () const { return baseType == schema::Type::UINT8 && listDepth == 0; } -inline bool Type::isUInt16 () const { return baseType == schema::Type::UINT16 && listDepth == 0; } -inline bool Type::isUInt32 () const { return baseType == schema::Type::UINT32 && listDepth == 0; } -inline bool Type::isUInt64 () const { return baseType == schema::Type::UINT64 && listDepth == 0; } -inline bool Type::isFloat32() const { return baseType == schema::Type::FLOAT32 && listDepth == 0; } -inline bool Type::isFloat64() const { return baseType == schema::Type::FLOAT64 && listDepth == 0; } -inline bool Type::isText () const { return baseType == schema::Type::TEXT && listDepth == 0; } -inline bool Type::isData () const { return baseType == schema::Type::DATA && listDepth == 0; } -inline bool Type::isList () const { return listDepth > 0; } -inline bool Type::isEnum () const { return baseType == schema::Type::ENUM && listDepth == 0; } -inline bool Type::isStruct () const { return baseType == schema::Type::STRUCT && listDepth == 0; } -inline bool Type::isInterface() const { - return baseType == schema::Type::INTERFACE && listDepth == 0; -} -inline bool Type::isAnyPointer() const { - return baseType == schema::Type::ANY_POINTER && listDepth == 0; -} - -inline Type Type::wrapInList(uint depth) const { - Type result = *this; - result.listDepth += depth; - return result; -} - -} // namespace capnp - -#endif // CAPNP_SCHEMA_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. + +#ifndef CAPNP_SCHEMA_H_ +#define CAPNP_SCHEMA_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#if CAPNP_LITE +#error "Reflection APIs, including this header, are not available in lite mode." +#endif + +#include + +namespace capnp { + +class Schema; +class StructSchema; +class EnumSchema; +class InterfaceSchema; +class ConstSchema; +class ListSchema; +class Type; + +template ()> struct SchemaType_ { typedef Schema Type; }; +template struct SchemaType_ { typedef schema::Type::Which Type; }; +template struct SchemaType_ { typedef schema::Type::Which Type; }; +template struct SchemaType_ { typedef EnumSchema Type; }; +template struct SchemaType_ { typedef StructSchema Type; }; +template struct SchemaType_ { typedef InterfaceSchema Type; }; +template struct SchemaType_ { typedef ListSchema Type; }; + +template +using SchemaType = typename SchemaType_::Type; +// SchemaType is the type of T's schema, e.g. StructSchema if T is a struct. + +namespace _ { // private +extern const RawSchema NULL_SCHEMA; +extern const RawSchema NULL_STRUCT_SCHEMA; +extern const RawSchema NULL_ENUM_SCHEMA; +extern const RawSchema NULL_INTERFACE_SCHEMA; +extern const RawSchema NULL_CONST_SCHEMA; +// The schema types default to these null (empty) schemas in case of error, especially when +// exceptions are disabled. +} // namespace _ (private) + +class Schema { + // Convenience wrapper around capnp::schema::Node. + +public: + inline Schema(): raw(&_::NULL_SCHEMA.defaultBrand) {} + + template + static inline SchemaType from() { return SchemaType::template fromImpl(); } + // Get the Schema for a particular compiled-in type. + + schema::Node::Reader getProto() const; + // Get the underlying Cap'n Proto representation of the schema node. (Note that this accessor + // has performance comparable to accessors of struct-typed fields on Reader classes.) + + kj::ArrayPtr asUncheckedMessage() const; + // Get the encoded schema node content as a single message segment. It is safe to read as an + // unchecked message. + + Schema getDependency(uint64_t id) const KJ_DEPRECATED("Does not handle generics correctly."); + // DEPRECATED: This method cannot correctly account for generic type parameter bindings that + // may apply to the dependency. Instead of using this method, use a method of the Schema API + // that corresponds to the exact kind of dependency. For example, to get a field type, use + // StructSchema::Field::getType(). + // + // Gets the Schema for one of this Schema's dependencies. For example, if this Schema is for a + // struct, you could look up the schema for one of its fields' types. Throws an exception if this + // schema doesn't actually depend on the given id. + // + // Note that not all type IDs found in the schema node are considered "dependencies" -- only the + // ones that are needed to implement the dynamic API are. That includes: + // - Field types. + // - Group types. + // - scopeId for group nodes, but NOT otherwise. + // - Method parameter and return types. + // + // The following are NOT considered dependencies: + // - Nested nodes. + // - scopeId for a non-group node. + // - Annotations. + // + // To obtain schemas for those, you would need a SchemaLoader. + + bool isBranded() const; + // Returns true if this schema represents a non-default parameterization of this type. + + Schema getGeneric() const; + // Get the version of this schema with any brands removed. + + class BrandArgumentList; + BrandArgumentList getBrandArgumentsAtScope(uint64_t scopeId) const; + // Gets the values bound to the brand parameters at the given scope. + + StructSchema asStruct() const; + EnumSchema asEnum() const; + InterfaceSchema asInterface() const; + ConstSchema asConst() const; + // Cast the Schema to a specific type. Throws an exception if the type doesn't match. Use + // getProto() to determine type, e.g. getProto().isStruct(). + + inline bool operator==(const Schema& other) const { return raw == other.raw; } + inline bool operator!=(const Schema& other) const { return raw != other.raw; } + // Determine whether two Schemas are wrapping the exact same underlying data, by identity. If + // you want to check if two Schemas represent the same type (but possibly different versions of + // it), compare their IDs instead. + + template + void requireUsableAs() const; + // Throws an exception if a value with this Schema cannot safely be cast to a native value of + // the given type. This passes if either: + // - *this == from() + // - This schema was loaded with SchemaLoader, the type ID matches typeId(), and + // loadCompiledTypeAndDependencies() was called on the SchemaLoader. + + kj::StringPtr getShortDisplayName() const; + // Get the short version of the node's display name. + +private: + const _::RawBrandedSchema* raw; + + inline explicit Schema(const _::RawBrandedSchema* raw): raw(raw) { + KJ_IREQUIRE(raw->lazyInitializer == nullptr, + "Must call ensureInitialized() on RawSchema before constructing Schema."); + } + + template static inline Schema fromImpl() { + return Schema(&_::rawSchema()); + } + + void requireUsableAs(const _::RawSchema* expected) const; + + uint32_t getSchemaOffset(const schema::Value::Reader& value) const; + + Type getBrandBinding(uint64_t scopeId, uint index) const; + // Look up the binding for a brand parameter used by this Schema. Returns `AnyPointer` if the + // parameter is not bound. + // + // TODO(someday): Public interface for iterating over all bindings? + + Schema getDependency(uint64_t id, uint location) const; + // Look up schema for a particular dependency of this schema. `location` is the dependency + // location number as defined in _::RawBrandedSchema. + + Type interpretType(schema::Type::Reader proto, uint location) const; + // Interpret a schema::Type in the given location within the schema, compiling it into a + // Type object. + + friend class StructSchema; + friend class EnumSchema; + friend class InterfaceSchema; + friend class ConstSchema; + friend class ListSchema; + friend class SchemaLoader; + friend class Type; + friend kj::StringTree _::structString( + _::StructReader reader, const _::RawBrandedSchema& schema); + friend kj::String _::enumString(uint16_t value, const _::RawBrandedSchema& schema); +}; + +kj::StringPtr KJ_STRINGIFY(const Schema& schema); + +class Schema::BrandArgumentList { + // A list of generic parameter bindings for parameters of some particular type. Note that since + // parameters on an outer type apply to all inner types as well, a deeply-nested type can have + // multiple BrandArgumentLists that apply to it. + // + // A BrandArgumentList only represents the arguments that the client of the type specified. Since + // new parameters can be added over time, this list may not cover all defined parameters for the + // type. Missing parameters should be treated as AnyPointer. This class's implementation of + // operator[] already does this for you; out-of-bounds access will safely return AnyPointer. + +public: + inline BrandArgumentList(): scopeId(0), size_(0), bindings(nullptr) {} + + inline uint size() const { return size_; } + Type operator[](uint index) const; + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + uint64_t scopeId; + uint size_; + bool isUnbound; + const _::RawBrandedSchema::Binding* bindings; + + inline BrandArgumentList(uint64_t scopeId, bool isUnbound) + : scopeId(scopeId), size_(0), isUnbound(isUnbound), bindings(nullptr) {} + inline BrandArgumentList(uint64_t scopeId, uint size, + const _::RawBrandedSchema::Binding* bindings) + : scopeId(scopeId), size_(size), isUnbound(false), bindings(bindings) {} + + friend class Schema; +}; + +// ------------------------------------------------------------------- + +class StructSchema: public Schema { +public: + inline StructSchema(): Schema(&_::NULL_STRUCT_SCHEMA.defaultBrand) {} + + class Field; + class FieldList; + class FieldSubset; + + FieldList getFields() const; + // List top-level fields of this struct. This list will contain top-level groups (including + // named unions) but not the members of those groups. The list does, however, contain the + // members of the unnamed union, if there is one. + + FieldSubset getUnionFields() const; + // If the field contains an unnamed union, get a list of fields in the union, ordered by + // ordinal. Since discriminant values are assigned sequentially by ordinal, you may index this + // list by discriminant value. + + FieldSubset getNonUnionFields() const; + // Get the fields of this struct which are not in an unnamed union, ordered by ordinal. + + kj::Maybe findFieldByName(kj::StringPtr name) const; + // Find the field with the given name, or return null if there is no such field. If the struct + // contains an unnamed union, then this will find fields of that union in addition to fields + // of the outer struct, since they exist in the same namespace. It will not, however, find + // members of groups (including named unions) -- you must first look up the group itself, + // then dig into its type. + + Field getFieldByName(kj::StringPtr name) const; + // Like findFieldByName() but throws an exception on failure. + + kj::Maybe getFieldByDiscriminant(uint16_t discriminant) const; + // Finds the field whose `discriminantValue` is equal to the given value, or returns null if + // there is no such field. (If the schema does not represent a union or a struct containing + // an unnamed union, then this always returns null.) + +private: + StructSchema(Schema base): Schema(base) {} + template static inline StructSchema fromImpl() { + return StructSchema(Schema(&_::rawBrandedSchema())); + } + friend class Schema; + friend class Type; +}; + +class StructSchema::Field { +public: + Field() = default; + + inline schema::Field::Reader getProto() const { return proto; } + inline StructSchema getContainingStruct() const { return parent; } + + inline uint getIndex() const { return index; } + // Get the index of this field within the containing struct or union. + + Type getType() const; + // Get the type of this field. Note that this is preferred over getProto().getType() as this + // method will apply generics. + + uint32_t getDefaultValueSchemaOffset() const; + // For struct, list, and object fields, returns the offset, in words, within the first segment of + // the struct's schema, where this field's default value pointer is located. The schema is + // always stored as a single-segment unchecked message, which in turn means that the default + // value pointer itself can be treated as the root of an unchecked message -- if you know where + // to find it, which is what this method helps you with. + // + // For blobs, returns the offset of the beginning of the blob's content within the first segment + // of the struct's schema. + // + // This is primarily useful for code generators. The C++ code generator, for example, embeds + // the entire schema as a raw word array within the generated code. Of course, to implement + // field accessors, it needs access to those fields' default values. Embedding separate copies + // of those default values would be redundant since they are already included in the schema, but + // seeking through the schema at runtime to find the default values would be ugly. Instead, + // the code generator can use getDefaultValueSchemaOffset() to find the offset of the default + // value within the schema, and can simply apply that offset at runtime. + // + // If the above does not make sense, you probably don't need this method. + + inline bool operator==(const Field& other) const; + inline bool operator!=(const Field& other) const { return !(*this == other); } + +private: + StructSchema parent; + uint index; + schema::Field::Reader proto; + + inline Field(StructSchema parent, uint index, schema::Field::Reader proto) + : parent(parent), index(index), proto(proto) {} + + friend class StructSchema; +}; + +kj::StringPtr KJ_STRINGIFY(const StructSchema::Field& field); + +class StructSchema::FieldList { +public: + FieldList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Field operator[](uint index) const { return Field(parent, index, list[index]); } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + StructSchema parent; + List::Reader list; + + inline FieldList(StructSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class StructSchema; +}; + +class StructSchema::FieldSubset { +public: + FieldSubset() = default; // empty list + + inline uint size() const { return size_; } + inline Field operator[](uint index) const { + return Field(parent, indices[index], list[indices[index]]); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + StructSchema parent; + List::Reader list; + const uint16_t* indices; + uint size_; + + inline FieldSubset(StructSchema parent, List::Reader list, + const uint16_t* indices, uint size) + : parent(parent), list(list), indices(indices), size_(size) {} + + friend class StructSchema; +}; + +// ------------------------------------------------------------------- + +class EnumSchema: public Schema { +public: + inline EnumSchema(): Schema(&_::NULL_ENUM_SCHEMA.defaultBrand) {} + + class Enumerant; + class EnumerantList; + + EnumerantList getEnumerants() const; + + kj::Maybe findEnumerantByName(kj::StringPtr name) const; + + Enumerant getEnumerantByName(kj::StringPtr name) const; + // Like findEnumerantByName() but throws an exception on failure. + +private: + EnumSchema(Schema base): Schema(base) {} + template static inline EnumSchema fromImpl() { + return EnumSchema(Schema(&_::rawBrandedSchema())); + } + friend class Schema; + friend class Type; +}; + +class EnumSchema::Enumerant { +public: + Enumerant() = default; + + inline schema::Enumerant::Reader getProto() const { return proto; } + inline EnumSchema getContainingEnum() const { return parent; } + + inline uint16_t getOrdinal() const { return ordinal; } + inline uint getIndex() const { return ordinal; } + + inline bool operator==(const Enumerant& other) const; + inline bool operator!=(const Enumerant& other) const { return !(*this == other); } + +private: + EnumSchema parent; + uint16_t ordinal; + schema::Enumerant::Reader proto; + + inline Enumerant(EnumSchema parent, uint16_t ordinal, schema::Enumerant::Reader proto) + : parent(parent), ordinal(ordinal), proto(proto) {} + + friend class EnumSchema; +}; + +class EnumSchema::EnumerantList { +public: + EnumerantList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Enumerant operator[](uint index) const { return Enumerant(parent, index, list[index]); } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + EnumSchema parent; + List::Reader list; + + inline EnumerantList(EnumSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class EnumSchema; +}; + +// ------------------------------------------------------------------- + +class InterfaceSchema: public Schema { +public: + inline InterfaceSchema(): Schema(&_::NULL_INTERFACE_SCHEMA.defaultBrand) {} + + class Method; + class MethodList; + + MethodList getMethods() const; + + kj::Maybe findMethodByName(kj::StringPtr name) const; + + Method getMethodByName(kj::StringPtr name) const; + // Like findMethodByName() but throws an exception on failure. + + class SuperclassList; + + SuperclassList getSuperclasses() const; + // Get the immediate superclasses of this type, after applying generics. + + bool extends(InterfaceSchema other) const; + // Returns true if `other` is a superclass of this interface (including if `other == *this`). + + kj::Maybe findSuperclass(uint64_t typeId) const; + // Find the superclass of this interface with the given type ID. Returns null if the interface + // extends no such type. + +private: + InterfaceSchema(Schema base): Schema(base) {} + template static inline InterfaceSchema fromImpl() { + return InterfaceSchema(Schema(&_::rawBrandedSchema())); + } + friend class Schema; + friend class Type; + + kj::Maybe findMethodByName(kj::StringPtr name, uint& counter) const; + bool extends(InterfaceSchema other, uint& counter) const; + kj::Maybe findSuperclass(uint64_t typeId, uint& counter) const; + // We protect against malicious schemas with large or cyclic hierarchies by cutting off the + // search when the counter reaches a threshold. +}; + +class InterfaceSchema::Method { +public: + Method() = default; + + inline schema::Method::Reader getProto() const { return proto; } + inline InterfaceSchema getContainingInterface() const { return parent; } + + inline uint16_t getOrdinal() const { return ordinal; } + inline uint getIndex() const { return ordinal; } + + StructSchema getParamType() const; + StructSchema getResultType() const; + // Get the parameter and result types, including substituting generic parameters. + + inline bool operator==(const Method& other) const; + inline bool operator!=(const Method& other) const { return !(*this == other); } + +private: + InterfaceSchema parent; + uint16_t ordinal; + schema::Method::Reader proto; + + inline Method(InterfaceSchema parent, uint16_t ordinal, + schema::Method::Reader proto) + : parent(parent), ordinal(ordinal), proto(proto) {} + + friend class InterfaceSchema; +}; + +class InterfaceSchema::MethodList { +public: + MethodList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Method operator[](uint index) const { return Method(parent, index, list[index]); } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + InterfaceSchema parent; + List::Reader list; + + inline MethodList(InterfaceSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class InterfaceSchema; +}; + +class InterfaceSchema::SuperclassList { +public: + SuperclassList() = default; // empty list + + inline uint size() const { return list.size(); } + InterfaceSchema operator[](uint index) const; + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + InterfaceSchema parent; + List::Reader list; + + inline SuperclassList(InterfaceSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class InterfaceSchema; +}; + +// ------------------------------------------------------------------- + +class ConstSchema: public Schema { + // Represents a constant declaration. + // + // `ConstSchema` can be implicitly cast to DynamicValue to read its value. + +public: + inline ConstSchema(): Schema(&_::NULL_CONST_SCHEMA.defaultBrand) {} + + template + ReaderFor as() const; + // Read the constant's value. This is a convenience method equivalent to casting the ConstSchema + // to a DynamicValue and then calling its `as()` method. For dependency reasons, this method + // is defined in , which you must #include explicitly. + + uint32_t getValueSchemaOffset() const; + // Much like StructSchema::Field::getDefaultValueSchemaOffset(), if the constant has pointer + // type, this gets the offset from the beginning of the constant's schema node to a pointer + // representing the constant value. + + Type getType() const; + +private: + ConstSchema(Schema base): Schema(base) {} + friend class Schema; +}; + +// ------------------------------------------------------------------- + +class Type { +public: + struct BrandParameter { + uint64_t scopeId; + uint index; + }; + struct ImplicitParameter { + uint index; + }; + + inline Type(); + inline Type(schema::Type::Which primitive); + inline Type(StructSchema schema); + inline Type(EnumSchema schema); + inline Type(InterfaceSchema schema); + inline Type(ListSchema schema); + inline Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind); + inline Type(BrandParameter param); + inline Type(ImplicitParameter param); + + template + inline static Type from(); + + inline schema::Type::Which which() const; + + StructSchema asStruct() const; + EnumSchema asEnum() const; + InterfaceSchema asInterface() const; + ListSchema asList() const; + // Each of these methods may only be called if which() returns the corresponding type. + + kj::Maybe getBrandParameter() const; + // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular + // AnyPointer and not a parameter. + + kj::Maybe getImplicitParameter() const; + // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular + // AnyPointer and not a parameter. "Implicit parameters" refer to type parameters on methods. + + inline schema::Type::AnyPointer::Unconstrained::Which whichAnyPointerKind() const; + // Only callable if which() returns ANY_POINTER. + + inline bool isVoid() const; + inline bool isBool() const; + inline bool isInt8() const; + inline bool isInt16() const; + inline bool isInt32() const; + inline bool isInt64() const; + inline bool isUInt8() const; + inline bool isUInt16() const; + inline bool isUInt32() const; + inline bool isUInt64() const; + inline bool isFloat32() const; + inline bool isFloat64() const; + inline bool isText() const; + inline bool isData() const; + inline bool isList() const; + inline bool isEnum() const; + inline bool isStruct() const; + inline bool isInterface() const; + inline bool isAnyPointer() const; + + bool operator==(const Type& other) const; + inline bool operator!=(const Type& other) const { return !(*this == other); } + + size_t hashCode() const; + + inline Type wrapInList(uint depth = 1) const; + // Return the Type formed by wrapping this type in List() `depth` times. + + inline Type(schema::Type::Which derived, const _::RawBrandedSchema* schema); + // For internal use. + +private: + schema::Type::Which baseType; // type not including applications of List() + uint8_t listDepth; // 0 for T, 1 for List(T), 2 for List(List(T)), ... + + bool isImplicitParam; + // If true, this refers to an implicit method parameter. baseType must be ANY_POINTER, scopeId + // must be zero, and paramIndex indicates the parameter index. + + union { + uint16_t paramIndex; + // If baseType is ANY_POINTER but this Type actually refers to a type parameter, this is the + // index of the parameter among the parameters at its scope, and `scopeId` below is the type ID + // of the scope where the parameter was defined. + + schema::Type::AnyPointer::Unconstrained::Which anyPointerKind; + // If scopeId is zero and isImplicitParam is false. + }; + + union { + const _::RawBrandedSchema* schema; // if type is struct, enum, interface... + uint64_t scopeId; // if type is AnyPointer but it's actually a type parameter... + }; + + Type(schema::Type::Which baseType, uint8_t listDepth, const _::RawBrandedSchema* schema) + : baseType(baseType), listDepth(listDepth), schema(schema) { + KJ_IREQUIRE(baseType != schema::Type::ANY_POINTER); + } + + void requireUsableAs(Type expected) const; + + friend class ListSchema; // only for requireUsableAs() +}; + +// ------------------------------------------------------------------- + +class ListSchema { + // ListSchema is a little different because list types are not described by schema nodes. So, + // ListSchema doesn't subclass Schema. + +public: + ListSchema() = default; + + static ListSchema of(schema::Type::Which primitiveType); + static ListSchema of(StructSchema elementType); + static ListSchema of(EnumSchema elementType); + static ListSchema of(InterfaceSchema elementType); + static ListSchema of(ListSchema elementType); + static ListSchema of(Type elementType); + // Construct the schema for a list of the given type. + + static ListSchema of(schema::Type::Reader elementType, Schema context) + KJ_DEPRECATED("Does not handle generics correctly."); + // DEPRECATED: This method cannot correctly account for generic type parameter bindings that + // may apply to the input type. Instead of using this method, use a method of the Schema API + // that corresponds to the exact kind of dependency. For example, to get a field type, use + // StructSchema::Field::getType(). + // + // Construct from an element type schema. Requires a context which can handle getDependency() + // requests for any type ID found in the schema. + + Type getElementType() const; + + inline schema::Type::Which whichElementType() const; + // Get the element type's "which()". ListSchema does not actually store a schema::Type::Reader + // describing the element type, but if it did, this would be equivalent to calling + // .getBody().which() on that type. + + StructSchema getStructElementType() const; + EnumSchema getEnumElementType() const; + InterfaceSchema getInterfaceElementType() const; + ListSchema getListElementType() const; + // Get the schema for complex element types. Each of these throws an exception if the element + // type is not of the requested kind. + + inline bool operator==(const ListSchema& other) const { return elementType == other.elementType; } + inline bool operator!=(const ListSchema& other) const { return elementType != other.elementType; } + + template + void requireUsableAs() const; + +private: + Type elementType; + + inline explicit ListSchema(Type elementType): elementType(elementType) {} + + template + struct FromImpl; + template static inline ListSchema fromImpl() { + return FromImpl::get(); + } + + void requireUsableAs(ListSchema expected) const; + + friend class Schema; +}; + +// ======================================================================================= +// inline implementation + +template <> inline schema::Type::Which Schema::from() { return schema::Type::VOID; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::BOOL; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::INT8; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::INT16; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::INT32; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::INT64; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT8; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT16; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT32; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT64; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::FLOAT32; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::FLOAT64; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::TEXT; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::DATA; } + +inline Schema Schema::getDependency(uint64_t id) const { + return getDependency(id, 0); +} + +inline bool Schema::isBranded() const { + return raw != &raw->generic->defaultBrand; +} + +inline Schema Schema::getGeneric() const { + return Schema(&raw->generic->defaultBrand); +} + +template +inline void Schema::requireUsableAs() const { + requireUsableAs(&_::rawSchema()); +} + +inline bool StructSchema::Field::operator==(const Field& other) const { + return parent == other.parent && index == other.index; +} +inline bool EnumSchema::Enumerant::operator==(const Enumerant& other) const { + return parent == other.parent && ordinal == other.ordinal; +} +inline bool InterfaceSchema::Method::operator==(const Method& other) const { + return parent == other.parent && ordinal == other.ordinal; +} + +inline ListSchema ListSchema::of(StructSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(EnumSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(InterfaceSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(ListSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(Type elementType) { + return ListSchema(elementType); +} + +inline Type ListSchema::getElementType() const { + return elementType; +} + +inline schema::Type::Which ListSchema::whichElementType() const { + return elementType.which(); +} + +inline StructSchema ListSchema::getStructElementType() const { + return elementType.asStruct(); +} + +inline EnumSchema ListSchema::getEnumElementType() const { + return elementType.asEnum(); +} + +inline InterfaceSchema ListSchema::getInterfaceElementType() const { + return elementType.asInterface(); +} + +inline ListSchema ListSchema::getListElementType() const { + return elementType.asList(); +} + +template +inline void ListSchema::requireUsableAs() const { + static_assert(kind() == Kind::LIST, + "ListSchema::requireUsableAs() requires T is a list type."); + requireUsableAs(Schema::from()); +} + +inline void ListSchema::requireUsableAs(ListSchema expected) const { + elementType.requireUsableAs(expected.elementType); +} + +template +struct ListSchema::FromImpl> { + static inline ListSchema get() { return of(Schema::from()); } +}; + +inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {} +inline Type::Type(schema::Type::Which primitive) + : baseType(primitive), listDepth(0), isImplicitParam(false) { + KJ_IREQUIRE(primitive != schema::Type::STRUCT && + primitive != schema::Type::ENUM && + primitive != schema::Type::INTERFACE && + primitive != schema::Type::LIST); + if (primitive == schema::Type::ANY_POINTER) { + scopeId = 0; + anyPointerKind = schema::Type::AnyPointer::Unconstrained::ANY_KIND; + } else { + schema = nullptr; + } +} +inline Type::Type(schema::Type::Which derived, const _::RawBrandedSchema* schema) + : baseType(derived), listDepth(0), isImplicitParam(false), schema(schema) { + KJ_IREQUIRE(derived == schema::Type::STRUCT || + derived == schema::Type::ENUM || + derived == schema::Type::INTERFACE); +} + +inline Type::Type(StructSchema schema) + : baseType(schema::Type::STRUCT), listDepth(0), schema(schema.raw) {} +inline Type::Type(EnumSchema schema) + : baseType(schema::Type::ENUM), listDepth(0), schema(schema.raw) {} +inline Type::Type(InterfaceSchema schema) + : baseType(schema::Type::INTERFACE), listDepth(0), schema(schema.raw) {} +inline Type::Type(ListSchema schema) + : Type(schema.getElementType()) { ++listDepth; } +inline Type::Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), + anyPointerKind(anyPointerKind), scopeId(0) {} +inline Type::Type(BrandParameter param) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), + paramIndex(param.index), scopeId(param.scopeId) {} +inline Type::Type(ImplicitParameter param) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(true), + paramIndex(param.index), scopeId(0) {} + +inline schema::Type::Which Type::which() const { + return listDepth > 0 ? schema::Type::LIST : baseType; +} + +inline schema::Type::AnyPointer::Unconstrained::Which Type::whichAnyPointerKind() const { + KJ_IREQUIRE(baseType == schema::Type::ANY_POINTER); + return !isImplicitParam && scopeId == 0 ? anyPointerKind + : schema::Type::AnyPointer::Unconstrained::ANY_KIND; +} + +template +inline Type Type::from() { return Type(Schema::from()); } + +inline bool Type::isVoid () const { return baseType == schema::Type::VOID && listDepth == 0; } +inline bool Type::isBool () const { return baseType == schema::Type::BOOL && listDepth == 0; } +inline bool Type::isInt8 () const { return baseType == schema::Type::INT8 && listDepth == 0; } +inline bool Type::isInt16 () const { return baseType == schema::Type::INT16 && listDepth == 0; } +inline bool Type::isInt32 () const { return baseType == schema::Type::INT32 && listDepth == 0; } +inline bool Type::isInt64 () const { return baseType == schema::Type::INT64 && listDepth == 0; } +inline bool Type::isUInt8 () const { return baseType == schema::Type::UINT8 && listDepth == 0; } +inline bool Type::isUInt16 () const { return baseType == schema::Type::UINT16 && listDepth == 0; } +inline bool Type::isUInt32 () const { return baseType == schema::Type::UINT32 && listDepth == 0; } +inline bool Type::isUInt64 () const { return baseType == schema::Type::UINT64 && listDepth == 0; } +inline bool Type::isFloat32() const { return baseType == schema::Type::FLOAT32 && listDepth == 0; } +inline bool Type::isFloat64() const { return baseType == schema::Type::FLOAT64 && listDepth == 0; } +inline bool Type::isText () const { return baseType == schema::Type::TEXT && listDepth == 0; } +inline bool Type::isData () const { return baseType == schema::Type::DATA && listDepth == 0; } +inline bool Type::isList () const { return listDepth > 0; } +inline bool Type::isEnum () const { return baseType == schema::Type::ENUM && listDepth == 0; } +inline bool Type::isStruct () const { return baseType == schema::Type::STRUCT && listDepth == 0; } +inline bool Type::isInterface() const { + return baseType == schema::Type::INTERFACE && listDepth == 0; +} +inline bool Type::isAnyPointer() const { + return baseType == schema::Type::ANY_POINTER && listDepth == 0; +} + +inline Type Type::wrapInList(uint depth) const { + Type result = *this; + result.listDepth += depth; + return result; +} + +} // namespace capnp + +#endif // CAPNP_SCHEMA_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/serialize-async.h --- a/win32-mingw/include/capnp/serialize-async.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/serialize-async.h Tue May 23 09:16:54 2017 +0100 @@ -1,64 +1,64 @@ -// 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. - -#ifndef CAPNP_SERIALIZE_ASYNC_H_ -#define CAPNP_SERIALIZE_ASYNC_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include "message.h" - -namespace capnp { - -kj::Promise> readMessage( - kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); -// Read a message asynchronously. -// -// `input` must remain valid until the returned promise resolves (or is canceled). -// -// `scratchSpace`, if provided, must remain valid until the returned MessageReader is destroyed. - -kj::Promise>> tryReadMessage( - kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); -// Like `readMessage` but returns null on EOF. - -kj::Promise writeMessage(kj::AsyncOutputStream& output, - kj::ArrayPtr> segments) - KJ_WARN_UNUSED_RESULT; -kj::Promise writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) - KJ_WARN_UNUSED_RESULT; -// Write asynchronously. The parameters must remain valid until the returned promise resolves. - -// ======================================================================================= -// inline implementation details - -inline kj::Promise writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) { - return writeMessage(output, builder.getSegmentsForOutput()); -} - -} // namespace capnp - -#endif // CAPNP_SERIALIZE_ASYNC_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. + +#ifndef CAPNP_SERIALIZE_ASYNC_H_ +#define CAPNP_SERIALIZE_ASYNC_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include +#include "message.h" + +namespace capnp { + +kj::Promise> readMessage( + kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); +// Read a message asynchronously. +// +// `input` must remain valid until the returned promise resolves (or is canceled). +// +// `scratchSpace`, if provided, must remain valid until the returned MessageReader is destroyed. + +kj::Promise>> tryReadMessage( + kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); +// Like `readMessage` but returns null on EOF. + +kj::Promise writeMessage(kj::AsyncOutputStream& output, + kj::ArrayPtr> segments) + KJ_WARN_UNUSED_RESULT; +kj::Promise writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) + KJ_WARN_UNUSED_RESULT; +// Write asynchronously. The parameters must remain valid until the returned promise resolves. + +// ======================================================================================= +// inline implementation details + +inline kj::Promise writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) { + return writeMessage(output, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +#endif // CAPNP_SERIALIZE_ASYNC_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/serialize-packed.h --- a/win32-mingw/include/capnp/serialize-packed.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/serialize-packed.h Tue May 23 09:16:54 2017 +0100 @@ -1,130 +1,130 @@ -// 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. - -#ifndef CAPNP_SERIALIZE_PACKED_H_ -#define CAPNP_SERIALIZE_PACKED_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "serialize.h" - -namespace capnp { - -namespace _ { // private - -class PackedInputStream: public kj::InputStream { - // An input stream that unpacks packed data with a picky constraint: The caller must read data - // in the exact same size and sequence as the data was written to PackedOutputStream. - -public: - explicit PackedInputStream(kj::BufferedInputStream& inner); - KJ_DISALLOW_COPY(PackedInputStream); - ~PackedInputStream() noexcept(false); - - // implements InputStream ------------------------------------------ - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - void skip(size_t bytes) override; - -private: - kj::BufferedInputStream& inner; -}; - -class PackedOutputStream: public kj::OutputStream { -public: - explicit PackedOutputStream(kj::BufferedOutputStream& inner); - KJ_DISALLOW_COPY(PackedOutputStream); - ~PackedOutputStream() noexcept(false); - - // implements OutputStream ----------------------------------------- - void write(const void* buffer, size_t bytes) override; - -private: - kj::BufferedOutputStream& inner; -}; - -} // namespace _ (private) - -class PackedMessageReader: private _::PackedInputStream, public InputStreamMessageReader { -public: - PackedMessageReader(kj::BufferedInputStream& inputStream, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); - KJ_DISALLOW_COPY(PackedMessageReader); - ~PackedMessageReader() noexcept(false); -}; - -class PackedFdMessageReader: private kj::FdInputStream, private kj::BufferedInputStreamWrapper, - public PackedMessageReader { -public: - PackedFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); - // Read message from a file descriptor, without taking ownership of the descriptor. - // Note that if you want to reuse the descriptor after the reader is destroyed, you'll need to - // seek it, since otherwise the position is unspecified. - - PackedFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); - // Read a message from a file descriptor, taking ownership of the descriptor. - - KJ_DISALLOW_COPY(PackedFdMessageReader); - - ~PackedFdMessageReader() noexcept(false); -}; - -void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder); -void writePackedMessage(kj::BufferedOutputStream& output, - kj::ArrayPtr> segments); -// Write a packed message to a buffered output stream. - -void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder); -void writePackedMessage(kj::OutputStream& output, - kj::ArrayPtr> segments); -// Write a packed message to an unbuffered output stream. If you intend to write multiple messages -// in succession, consider wrapping your output in a buffered stream in order to reduce system -// call overhead. - -void writePackedMessageToFd(int fd, MessageBuilder& builder); -void writePackedMessageToFd(int fd, kj::ArrayPtr> segments); -// Write a single packed message to the file descriptor. - -size_t computeUnpackedSizeInWords(kj::ArrayPtr packedBytes); -// Computes the number of words to which the given packed bytes will unpack. Not intended for use -// in performance-sensitive situations. - -// ======================================================================================= -// inline stuff - -inline void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder) { - writePackedMessage(output, builder.getSegmentsForOutput()); -} - -inline void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder) { - writePackedMessage(output, builder.getSegmentsForOutput()); -} - -inline void writePackedMessageToFd(int fd, MessageBuilder& builder) { - writePackedMessageToFd(fd, builder.getSegmentsForOutput()); -} - -} // namespace capnp - -#endif // CAPNP_SERIALIZE_PACKED_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. + +#ifndef CAPNP_SERIALIZE_PACKED_H_ +#define CAPNP_SERIALIZE_PACKED_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "serialize.h" + +namespace capnp { + +namespace _ { // private + +class PackedInputStream: public kj::InputStream { + // An input stream that unpacks packed data with a picky constraint: The caller must read data + // in the exact same size and sequence as the data was written to PackedOutputStream. + +public: + explicit PackedInputStream(kj::BufferedInputStream& inner); + KJ_DISALLOW_COPY(PackedInputStream); + ~PackedInputStream() noexcept(false); + + // implements InputStream ------------------------------------------ + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + kj::BufferedInputStream& inner; +}; + +class PackedOutputStream: public kj::OutputStream { +public: + explicit PackedOutputStream(kj::BufferedOutputStream& inner); + KJ_DISALLOW_COPY(PackedOutputStream); + ~PackedOutputStream() noexcept(false); + + // implements OutputStream ----------------------------------------- + void write(const void* buffer, size_t bytes) override; + +private: + kj::BufferedOutputStream& inner; +}; + +} // namespace _ (private) + +class PackedMessageReader: private _::PackedInputStream, public InputStreamMessageReader { +public: + PackedMessageReader(kj::BufferedInputStream& inputStream, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + KJ_DISALLOW_COPY(PackedMessageReader); + ~PackedMessageReader() noexcept(false); +}; + +class PackedFdMessageReader: private kj::FdInputStream, private kj::BufferedInputStreamWrapper, + public PackedMessageReader { +public: + PackedFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + // Read message from a file descriptor, without taking ownership of the descriptor. + // Note that if you want to reuse the descriptor after the reader is destroyed, you'll need to + // seek it, since otherwise the position is unspecified. + + PackedFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + // Read a message from a file descriptor, taking ownership of the descriptor. + + KJ_DISALLOW_COPY(PackedFdMessageReader); + + ~PackedFdMessageReader() noexcept(false); +}; + +void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder); +void writePackedMessage(kj::BufferedOutputStream& output, + kj::ArrayPtr> segments); +// Write a packed message to a buffered output stream. + +void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder); +void writePackedMessage(kj::OutputStream& output, + kj::ArrayPtr> segments); +// Write a packed message to an unbuffered output stream. If you intend to write multiple messages +// in succession, consider wrapping your output in a buffered stream in order to reduce system +// call overhead. + +void writePackedMessageToFd(int fd, MessageBuilder& builder); +void writePackedMessageToFd(int fd, kj::ArrayPtr> segments); +// Write a single packed message to the file descriptor. + +size_t computeUnpackedSizeInWords(kj::ArrayPtr packedBytes); +// Computes the number of words to which the given packed bytes will unpack. Not intended for use +// in performance-sensitive situations. + +// ======================================================================================= +// inline stuff + +inline void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder) { + writePackedMessage(output, builder.getSegmentsForOutput()); +} + +inline void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder) { + writePackedMessage(output, builder.getSegmentsForOutput()); +} + +inline void writePackedMessageToFd(int fd, MessageBuilder& builder) { + writePackedMessageToFd(fd, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +#endif // CAPNP_SERIALIZE_PACKED_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/serialize-text.h --- a/win32-mingw/include/capnp/serialize-text.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/serialize-text.h Tue May 23 09:16:54 2017 +0100 @@ -1,96 +1,96 @@ -// Copyright (c) 2015 Philip Quinn. -// 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. - -#ifndef CAPNP_SERIALIZE_TEXT_H_ -#define CAPNP_SERIALIZE_TEXT_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include "dynamic.h" -#include "orphan.h" -#include "schema.h" - -namespace capnp { - -class TextCodec { - // Reads and writes Cap'n Proto objects in a plain text format (as used in the schema - // language for constants, and read/written by the 'decode' and 'encode' commands of - // the capnp tool). - // - // This format is useful for debugging or human input, but it is not a robust alternative - // to the binary format. Changes to a schema's types or names that are permitted in a - // schema's binary evolution will likely break messages stored in this format. - // - // Note that definitions or references (to constants, other fields, or files) are not - // permitted in this format. To evaluate declarations with the full expressiveness of the - // schema language, see `capnp::SchemaParser`. - // - // Requires linking with the capnpc library. - -public: - TextCodec(); - ~TextCodec() noexcept(true); - - void setPrettyPrint(bool enabled); - // If enabled, pads the output of `encode()` with spaces and newlines to make it more - // human-readable. - - template - kj::String encode(T&& value) const; - kj::String encode(DynamicValue::Reader value) const; - // Encode any Cap'n Proto value. - - template - Orphan decode(kj::StringPtr input, Orphanage orphanage) const; - // Decode a text message into a Cap'n Proto object of type T, allocated in the given - // orphanage. Any errors parsing the input or assigning the fields of T are thrown as - // exceptions. - - void decode(kj::StringPtr input, DynamicStruct::Builder output) const; - // Decode a text message for a struct into the given builder. Any errors parsing the - // input or assigning the fields of the output are thrown as exceptions. - - // TODO(someday): expose some control over the error handling? -private: - Orphan decode(kj::StringPtr input, Type type, Orphanage orphanage) const; - - bool prettyPrint; -}; - -// ======================================================================================= -// inline stuff - -template -inline kj::String TextCodec::encode(T&& value) const { - return encode(DynamicValue::Reader(ReaderFor>(kj::fwd(value)))); -} - -template -inline Orphan TextCodec::decode(kj::StringPtr input, Orphanage orphanage) const { - return decode(input, Type::from(), orphanage).template releaseAs(); -} - -} // namespace capnp - -#endif // CAPNP_SERIALIZE_TEXT_H_ +// Copyright (c) 2015 Philip Quinn. +// 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. + +#ifndef CAPNP_SERIALIZE_TEXT_H_ +#define CAPNP_SERIALIZE_TEXT_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include +#include "dynamic.h" +#include "orphan.h" +#include "schema.h" + +namespace capnp { + +class TextCodec { + // Reads and writes Cap'n Proto objects in a plain text format (as used in the schema + // language for constants, and read/written by the 'decode' and 'encode' commands of + // the capnp tool). + // + // This format is useful for debugging or human input, but it is not a robust alternative + // to the binary format. Changes to a schema's types or names that are permitted in a + // schema's binary evolution will likely break messages stored in this format. + // + // Note that definitions or references (to constants, other fields, or files) are not + // permitted in this format. To evaluate declarations with the full expressiveness of the + // schema language, see `capnp::SchemaParser`. + // + // Requires linking with the capnpc library. + +public: + TextCodec(); + ~TextCodec() noexcept(true); + + void setPrettyPrint(bool enabled); + // If enabled, pads the output of `encode()` with spaces and newlines to make it more + // human-readable. + + template + kj::String encode(T&& value) const; + kj::String encode(DynamicValue::Reader value) const; + // Encode any Cap'n Proto value. + + template + Orphan decode(kj::StringPtr input, Orphanage orphanage) const; + // Decode a text message into a Cap'n Proto object of type T, allocated in the given + // orphanage. Any errors parsing the input or assigning the fields of T are thrown as + // exceptions. + + void decode(kj::StringPtr input, DynamicStruct::Builder output) const; + // Decode a text message for a struct into the given builder. Any errors parsing the + // input or assigning the fields of the output are thrown as exceptions. + + // TODO(someday): expose some control over the error handling? +private: + Orphan decode(kj::StringPtr input, Type type, Orphanage orphanage) const; + + bool prettyPrint; +}; + +// ======================================================================================= +// inline stuff + +template +inline kj::String TextCodec::encode(T&& value) const { + return encode(DynamicValue::Reader(ReaderFor>(kj::fwd(value)))); +} + +template +inline Orphan TextCodec::decode(kj::StringPtr input, Orphanage orphanage) const { + return decode(input, Type::from(), orphanage).template releaseAs(); +} + +} // namespace capnp + +#endif // CAPNP_SERIALIZE_TEXT_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/serialize.h --- a/win32-mingw/include/capnp/serialize.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/serialize.h Tue May 23 09:16:54 2017 +0100 @@ -1,237 +1,237 @@ -// 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 implements a simple serialization format for Cap'n Proto messages. The format -// is as follows: -// -// * 32-bit little-endian segment count (4 bytes). -// * 32-bit little-endian size of each segment (4*(segment count) bytes). -// * Padding so that subsequent data is 64-bit-aligned (0 or 4 bytes). (I.e., if there are an even -// number of segments, there are 4 bytes of zeros here, otherwise there is no padding.) -// * Data from each segment, in order (8*sum(segment sizes) bytes) -// -// This format has some important properties: -// - It is self-delimiting, so multiple messages may be written to a stream without any external -// delimiter. -// - The total size and position of each segment can be determined by reading only the first part -// of the message, allowing lazy and random-access reading of the segment data. -// - A message is always at least 8 bytes. -// - A single-segment message can be read entirely in two system calls with no buffering. -// - A multi-segment message can be read entirely in three system calls with no buffering. -// - The format is appropriate for mmap()ing since all data is aligned. - -#ifndef CAPNP_SERIALIZE_H_ -#define CAPNP_SERIALIZE_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "message.h" -#include - -namespace capnp { - -class FlatArrayMessageReader: public MessageReader { - // Parses a message from a flat array. Note that it makes sense to use this together with mmap() - // for extremely fast parsing. - -public: - FlatArrayMessageReader(kj::ArrayPtr array, ReaderOptions options = ReaderOptions()); - // The array must remain valid until the MessageReader is destroyed. - - kj::ArrayPtr getSegment(uint id) override; - - const word* getEnd() const { return end; } - // Get a pointer just past the end of the message as determined by reading the message header. - // This could actually be before the end of the input array. This pointer is useful e.g. if - // you know that the input array has extra stuff appended after the message and you want to - // get at it. - -private: - // Optimize for single-segment case. - kj::ArrayPtr segment0; - kj::Array> moreSegments; - const word* end; -}; - -kj::ArrayPtr initMessageBuilderFromFlatArrayCopy( - kj::ArrayPtr array, MessageBuilder& target, - ReaderOptions options = ReaderOptions()); -// Convenience function which reads a message using `FlatArrayMessageReader` then copies the -// content into the target `MessageBuilder`, verifying that the message structure is valid -// (although not necessarily that it matches the desired schema). -// -// Returns an ArrayPtr containing any words left over in the array after consuming the whole -// message. This is useful when reading multiple messages that have been concatenated. See also -// FlatArrayMessageReader::getEnd(). -// -// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one -// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not -// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) - -kj::Array messageToFlatArray(MessageBuilder& builder); -// Constructs a flat array containing the entire content of the given message. -// -// To output the message as bytes, use `.asBytes()` on the returned word array. Keep in mind that -// `asBytes()` returns an ArrayPtr, so you have to save the Array as well to prevent it from being -// deleted. For example: -// -// kj::Array words = messageToFlatArray(myMessage); -// kj::ArrayPtr bytes = words.asBytes(); -// write(fd, bytes.begin(), bytes.size()); - -kj::Array messageToFlatArray(kj::ArrayPtr> segments); -// Version of messageToFlatArray that takes a raw segment array. - -size_t computeSerializedSizeInWords(MessageBuilder& builder); -// Returns the size, in words, that will be needed to serialize the message, including the header. - -size_t computeSerializedSizeInWords(kj::ArrayPtr> segments); -// Version of computeSerializedSizeInWords that takes a raw segment array. - -size_t expectedSizeInWordsFromPrefix(kj::ArrayPtr messagePrefix); -// Given a prefix of a serialized message, try to determine the expected total size of the message, -// in words. The returned size is based on the information known so far; it may be an underestimate -// if the prefix doesn't contain the full segment table. -// -// If the returned value is greater than `messagePrefix.size()`, then the message is not yet -// complete and the app cannot parse it yet. If the returned value is less than or equal to -// `messagePrefix.size()`, then the returned value is the exact total size of the message; any -// remaining bytes are part of the next message. -// -// This function is useful when reading messages from a stream in an asynchronous way, but when -// using the full KJ async infrastructure would be too difficult. Each time bytes are received, -// use this function to determine if an entire message is ready to be parsed. - -// ======================================================================================= - -class InputStreamMessageReader: public MessageReader { - // A MessageReader that reads from an abstract kj::InputStream. See also StreamFdMessageReader - // for a subclass specific to file descriptors. - -public: - InputStreamMessageReader(kj::InputStream& inputStream, - ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); - ~InputStreamMessageReader() noexcept(false); - - // implements MessageReader ---------------------------------------- - kj::ArrayPtr getSegment(uint id) override; - -private: - kj::InputStream& inputStream; - byte* readPos; - - // Optimize for single-segment case. - kj::ArrayPtr segment0; - kj::Array> moreSegments; - - kj::Array ownedSpace; - // Only if scratchSpace wasn't big enough. - - kj::UnwindDetector unwindDetector; -}; - -void readMessageCopy(kj::InputStream& input, MessageBuilder& target, - ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); -// Convenience function which reads a message using `InputStreamMessageReader` then copies the -// content into the target `MessageBuilder`, verifying that the message structure is valid -// (although not necessarily that it matches the desired schema). -// -// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one -// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not -// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) - -void writeMessage(kj::OutputStream& output, MessageBuilder& builder); -// Write the message to the given output stream. - -void writeMessage(kj::OutputStream& output, kj::ArrayPtr> segments); -// Write the segment array to the given output stream. - -// ======================================================================================= -// Specializations for reading from / writing to file descriptors. - -class StreamFdMessageReader: private kj::FdInputStream, public InputStreamMessageReader { - // A MessageReader that reads from a steam-based file descriptor. - -public: - StreamFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr) - : FdInputStream(fd), InputStreamMessageReader(*this, options, scratchSpace) {} - // Read message from a file descriptor, without taking ownership of the descriptor. - - StreamFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr) - : FdInputStream(kj::mv(fd)), InputStreamMessageReader(*this, options, scratchSpace) {} - // Read a message from a file descriptor, taking ownership of the descriptor. - - ~StreamFdMessageReader() noexcept(false); -}; - -void readMessageCopyFromFd(int fd, MessageBuilder& target, - ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); -// Convenience function which reads a message using `StreamFdMessageReader` then copies the -// content into the target `MessageBuilder`, verifying that the message structure is valid -// (although not necessarily that it matches the desired schema). -// -// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one -// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not -// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) - -void writeMessageToFd(int fd, MessageBuilder& builder); -// Write the message to the given file descriptor. -// -// This function throws an exception on any I/O error. If your code is not exception-safe, be sure -// you catch this exception at the call site. If throwing an exception is not acceptable, you -// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). - -void writeMessageToFd(int fd, kj::ArrayPtr> segments); -// Write the segment array to the given file descriptor. -// -// This function throws an exception on any I/O error. If your code is not exception-safe, be sure -// you catch this exception at the call site. If throwing an exception is not acceptable, you -// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). - -// ======================================================================================= -// inline stuff - -inline kj::Array messageToFlatArray(MessageBuilder& builder) { - return messageToFlatArray(builder.getSegmentsForOutput()); -} - -inline size_t computeSerializedSizeInWords(MessageBuilder& builder) { - return computeSerializedSizeInWords(builder.getSegmentsForOutput()); -} - -inline void writeMessage(kj::OutputStream& output, MessageBuilder& builder) { - writeMessage(output, builder.getSegmentsForOutput()); -} - -inline void writeMessageToFd(int fd, MessageBuilder& builder) { - writeMessageToFd(fd, builder.getSegmentsForOutput()); -} - -} // namespace capnp - -#endif // SERIALIZE_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 implements a simple serialization format for Cap'n Proto messages. The format +// is as follows: +// +// * 32-bit little-endian segment count (4 bytes). +// * 32-bit little-endian size of each segment (4*(segment count) bytes). +// * Padding so that subsequent data is 64-bit-aligned (0 or 4 bytes). (I.e., if there are an even +// number of segments, there are 4 bytes of zeros here, otherwise there is no padding.) +// * Data from each segment, in order (8*sum(segment sizes) bytes) +// +// This format has some important properties: +// - It is self-delimiting, so multiple messages may be written to a stream without any external +// delimiter. +// - The total size and position of each segment can be determined by reading only the first part +// of the message, allowing lazy and random-access reading of the segment data. +// - A message is always at least 8 bytes. +// - A single-segment message can be read entirely in two system calls with no buffering. +// - A multi-segment message can be read entirely in three system calls with no buffering. +// - The format is appropriate for mmap()ing since all data is aligned. + +#ifndef CAPNP_SERIALIZE_H_ +#define CAPNP_SERIALIZE_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "message.h" +#include + +namespace capnp { + +class FlatArrayMessageReader: public MessageReader { + // Parses a message from a flat array. Note that it makes sense to use this together with mmap() + // for extremely fast parsing. + +public: + FlatArrayMessageReader(kj::ArrayPtr array, ReaderOptions options = ReaderOptions()); + // The array must remain valid until the MessageReader is destroyed. + + kj::ArrayPtr getSegment(uint id) override; + + const word* getEnd() const { return end; } + // Get a pointer just past the end of the message as determined by reading the message header. + // This could actually be before the end of the input array. This pointer is useful e.g. if + // you know that the input array has extra stuff appended after the message and you want to + // get at it. + +private: + // Optimize for single-segment case. + kj::ArrayPtr segment0; + kj::Array> moreSegments; + const word* end; +}; + +kj::ArrayPtr initMessageBuilderFromFlatArrayCopy( + kj::ArrayPtr array, MessageBuilder& target, + ReaderOptions options = ReaderOptions()); +// Convenience function which reads a message using `FlatArrayMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// Returns an ArrayPtr containing any words left over in the array after consuming the whole +// message. This is useful when reading multiple messages that have been concatenated. See also +// FlatArrayMessageReader::getEnd(). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +kj::Array messageToFlatArray(MessageBuilder& builder); +// Constructs a flat array containing the entire content of the given message. +// +// To output the message as bytes, use `.asBytes()` on the returned word array. Keep in mind that +// `asBytes()` returns an ArrayPtr, so you have to save the Array as well to prevent it from being +// deleted. For example: +// +// kj::Array words = messageToFlatArray(myMessage); +// kj::ArrayPtr bytes = words.asBytes(); +// write(fd, bytes.begin(), bytes.size()); + +kj::Array messageToFlatArray(kj::ArrayPtr> segments); +// Version of messageToFlatArray that takes a raw segment array. + +size_t computeSerializedSizeInWords(MessageBuilder& builder); +// Returns the size, in words, that will be needed to serialize the message, including the header. + +size_t computeSerializedSizeInWords(kj::ArrayPtr> segments); +// Version of computeSerializedSizeInWords that takes a raw segment array. + +size_t expectedSizeInWordsFromPrefix(kj::ArrayPtr messagePrefix); +// Given a prefix of a serialized message, try to determine the expected total size of the message, +// in words. The returned size is based on the information known so far; it may be an underestimate +// if the prefix doesn't contain the full segment table. +// +// If the returned value is greater than `messagePrefix.size()`, then the message is not yet +// complete and the app cannot parse it yet. If the returned value is less than or equal to +// `messagePrefix.size()`, then the returned value is the exact total size of the message; any +// remaining bytes are part of the next message. +// +// This function is useful when reading messages from a stream in an asynchronous way, but when +// using the full KJ async infrastructure would be too difficult. Each time bytes are received, +// use this function to determine if an entire message is ready to be parsed. + +// ======================================================================================= + +class InputStreamMessageReader: public MessageReader { + // A MessageReader that reads from an abstract kj::InputStream. See also StreamFdMessageReader + // for a subclass specific to file descriptors. + +public: + InputStreamMessageReader(kj::InputStream& inputStream, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + ~InputStreamMessageReader() noexcept(false); + + // implements MessageReader ---------------------------------------- + kj::ArrayPtr getSegment(uint id) override; + +private: + kj::InputStream& inputStream; + byte* readPos; + + // Optimize for single-segment case. + kj::ArrayPtr segment0; + kj::Array> moreSegments; + + kj::Array ownedSpace; + // Only if scratchSpace wasn't big enough. + + kj::UnwindDetector unwindDetector; +}; + +void readMessageCopy(kj::InputStream& input, MessageBuilder& target, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); +// Convenience function which reads a message using `InputStreamMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +void writeMessage(kj::OutputStream& output, MessageBuilder& builder); +// Write the message to the given output stream. + +void writeMessage(kj::OutputStream& output, kj::ArrayPtr> segments); +// Write the segment array to the given output stream. + +// ======================================================================================= +// Specializations for reading from / writing to file descriptors. + +class StreamFdMessageReader: private kj::FdInputStream, public InputStreamMessageReader { + // A MessageReader that reads from a steam-based file descriptor. + +public: + StreamFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr) + : FdInputStream(fd), InputStreamMessageReader(*this, options, scratchSpace) {} + // Read message from a file descriptor, without taking ownership of the descriptor. + + StreamFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr) + : FdInputStream(kj::mv(fd)), InputStreamMessageReader(*this, options, scratchSpace) {} + // Read a message from a file descriptor, taking ownership of the descriptor. + + ~StreamFdMessageReader() noexcept(false); +}; + +void readMessageCopyFromFd(int fd, MessageBuilder& target, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); +// Convenience function which reads a message using `StreamFdMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +void writeMessageToFd(int fd, MessageBuilder& builder); +// Write the message to the given file descriptor. +// +// This function throws an exception on any I/O error. If your code is not exception-safe, be sure +// you catch this exception at the call site. If throwing an exception is not acceptable, you +// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). + +void writeMessageToFd(int fd, kj::ArrayPtr> segments); +// Write the segment array to the given file descriptor. +// +// This function throws an exception on any I/O error. If your code is not exception-safe, be sure +// you catch this exception at the call site. If throwing an exception is not acceptable, you +// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). + +// ======================================================================================= +// inline stuff + +inline kj::Array messageToFlatArray(MessageBuilder& builder) { + return messageToFlatArray(builder.getSegmentsForOutput()); +} + +inline size_t computeSerializedSizeInWords(MessageBuilder& builder) { + return computeSerializedSizeInWords(builder.getSegmentsForOutput()); +} + +inline void writeMessage(kj::OutputStream& output, MessageBuilder& builder) { + writeMessage(output, builder.getSegmentsForOutput()); +} + +inline void writeMessageToFd(int fd, MessageBuilder& builder) { + writeMessageToFd(fd, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +#endif // SERIALIZE_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/capnp/test-util.h --- a/win32-mingw/include/capnp/test-util.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/capnp/test-util.h Tue May 23 09:16:54 2017 +0100 @@ -1,323 +1,312 @@ -// 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. - -#ifndef CAPNP_TEST_UTIL_H_ -#define CAPNP_TEST_UTIL_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include -#include "blob.h" -#include - -#if !CAPNP_LITE -#include "dynamic.h" -#endif // !CAPNP_LITE - -#if KJ_NO_EXCEPTIONS -#undef EXPECT_ANY_THROW -#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".") -#endif - -#define EXPECT_NONFATAL_FAILURE(code) \ - EXPECT_TRUE(kj::runCatchingExceptions([&]() { code; }) != nullptr); - -#ifdef KJ_DEBUG -#define EXPECT_DEBUG_ANY_THROW EXPECT_ANY_THROW -#else -#define EXPECT_DEBUG_ANY_THROW(EXP) -#endif - -// TODO(cleanup): Auto-generate stringification functions for union discriminants. -namespace capnproto_test { -namespace capnp { -namespace test { -inline kj::String KJ_STRINGIFY(TestUnion::Union0::Which which) { - return kj::str(static_cast(which)); -} -inline kj::String KJ_STRINGIFY(TestUnion::Union1::Which which) { - return kj::str(static_cast(which)); -} -inline kj::String KJ_STRINGIFY(TestUnion::Union2::Which which) { - return kj::str(static_cast(which)); -} -inline kj::String KJ_STRINGIFY(TestUnion::Union3::Which which) { - return kj::str(static_cast(which)); -} -inline kj::String KJ_STRINGIFY(TestUnnamedUnion::Which which) { - return kj::str(static_cast(which)); -} -inline kj::String KJ_STRINGIFY(TestGroups::Groups::Which which) { - return kj::str(static_cast(which)); -} -inline kj::String KJ_STRINGIFY(TestInterleavedGroups::Group1::Which which) { - return kj::str(static_cast(which)); -} -} // namespace test -} // namespace capnp -} // namespace capnproto_test - -namespace capnp { -namespace _ { // private - -inline Data::Reader data(const char* str) { - return Data::Reader(reinterpret_cast(str), strlen(str)); -} - -namespace test = capnproto_test::capnp::test; - -// We don't use "using namespace" to pull these in because then things would still compile -// correctly if they were generated in the global namespace. -using ::capnproto_test::capnp::test::TestAllTypes; -using ::capnproto_test::capnp::test::TestDefaults; -using ::capnproto_test::capnp::test::TestEnum; -using ::capnproto_test::capnp::test::TestUnion; -using ::capnproto_test::capnp::test::TestUnionDefaults; -using ::capnproto_test::capnp::test::TestNestedTypes; -using ::capnproto_test::capnp::test::TestUsing; -using ::capnproto_test::capnp::test::TestListDefaults; - -void initTestMessage(TestAllTypes::Builder builder); -void initTestMessage(TestDefaults::Builder builder); -void initTestMessage(TestListDefaults::Builder builder); - -void checkTestMessage(TestAllTypes::Builder builder); -void checkTestMessage(TestDefaults::Builder builder); -void checkTestMessage(TestListDefaults::Builder builder); - -void checkTestMessage(TestAllTypes::Reader reader); -void checkTestMessage(TestDefaults::Reader reader); -void checkTestMessage(TestListDefaults::Reader reader); - -void checkTestMessageAllZero(TestAllTypes::Builder builder); -void checkTestMessageAllZero(TestAllTypes::Reader reader); - -#if !CAPNP_LITE -void initDynamicTestMessage(DynamicStruct::Builder builder); -void initDynamicTestLists(DynamicStruct::Builder builder); -void checkDynamicTestMessage(DynamicStruct::Builder builder); -void checkDynamicTestLists(DynamicStruct::Builder builder); -void checkDynamicTestMessage(DynamicStruct::Reader reader); -void checkDynamicTestLists(DynamicStruct::Reader reader); -void checkDynamicTestMessageAllZero(DynamicStruct::Builder builder); -void checkDynamicTestMessageAllZero(DynamicStruct::Reader reader); -#endif // !CAPNP_LITE - -template -inline void checkElement(T a, T b) { - EXPECT_EQ(a, b); -} - -template <> -inline void checkElement(float a, float b) { - EXPECT_FLOAT_EQ(a, b); -} - -template <> -inline void checkElement(double a, double b) { - EXPECT_DOUBLE_EQ(a, b); -} - -template -void checkList(T reader, std::initializer_list expected) { - ASSERT_EQ(expected.size(), reader.size()); - for (uint i = 0; i < expected.size(); i++) { - checkElement(expected.begin()[i], reader[i]); - } -} - -template -void checkList(T reader, std::initializer_list expected) { - ASSERT_EQ(expected.size(), reader.size()); - for (uint i = 0; i < expected.size(); i++) { - checkElement(expected.begin()[i], reader[i]); - } -} - -inline void checkList(List::Reader reader, - std::initializer_list expectedData, - std::initializer_list expectedPointers) { - ASSERT_EQ(expectedData.size(), reader.size()); - for (uint i = 0; i < expectedData.size(); i++) { - EXPECT_EQ(expectedData.begin()[i], reader[i].getOld1()); - EXPECT_EQ(expectedPointers.begin()[i], reader[i].getOld2()); - } -} - -// Hack because as<>() is a template-parameter-dependent lookup everywhere below... -#define as template as - -template void expectPrimitiveEq(T a, T b) { EXPECT_EQ(a, b); } -inline void expectPrimitiveEq(float a, float b) { EXPECT_FLOAT_EQ(a, b); } -inline void expectPrimitiveEq(double a, double b) { EXPECT_DOUBLE_EQ(a, b); } -inline void expectPrimitiveEq(Text::Reader a, Text::Builder b) { EXPECT_EQ(a, b); } -inline void expectPrimitiveEq(Data::Reader a, Data::Builder b) { EXPECT_EQ(a, b); } - -#if !CAPNP_LITE -template -void checkList(T reader, std::initializer_list> expected) { - auto list = reader.as(); - ASSERT_EQ(expected.size(), list.size()); - for (uint i = 0; i < expected.size(); i++) { - expectPrimitiveEq(expected.begin()[i], list[i].as()); - } - - auto typed = reader.as>(); - ASSERT_EQ(expected.size(), typed.size()); - for (uint i = 0; i < expected.size(); i++) { - expectPrimitiveEq(expected.begin()[i], typed[i]); - } -} -#endif // !CAPNP_LITE - -#undef as - -// ======================================================================================= -// Interface implementations. - -#if !CAPNP_LITE - -class TestInterfaceImpl final: public test::TestInterface::Server { -public: - TestInterfaceImpl(int& callCount); - - kj::Promise foo(FooContext context) override; - - kj::Promise baz(BazContext context) override; - -private: - int& callCount; -}; - -class TestExtendsImpl final: public test::TestExtends2::Server { -public: - TestExtendsImpl(int& callCount); - - kj::Promise foo(FooContext context) override; - - kj::Promise grault(GraultContext context) override; - -private: - int& callCount; -}; - -class TestPipelineImpl final: public test::TestPipeline::Server { -public: - TestPipelineImpl(int& callCount); - - kj::Promise getCap(GetCapContext context) override; - -private: - int& callCount; -}; - -class TestCallOrderImpl final: public test::TestCallOrder::Server { -public: - kj::Promise getCallSequence(GetCallSequenceContext context) override; - -private: - uint count = 0; -}; - -class TestTailCallerImpl final: public test::TestTailCaller::Server { -public: - TestTailCallerImpl(int& callCount); - - kj::Promise foo(FooContext context) override; - -private: - int& callCount; -}; - -class TestTailCalleeImpl final: public test::TestTailCallee::Server { -public: - TestTailCalleeImpl(int& callCount); - - kj::Promise foo(FooContext context) override; - -private: - int& callCount; -}; - -class TestMoreStuffImpl final: public test::TestMoreStuff::Server { -public: - TestMoreStuffImpl(int& callCount, int& handleCount); - - kj::Promise getCallSequence(GetCallSequenceContext context) override; - - kj::Promise callFoo(CallFooContext context) override; - - kj::Promise callFooWhenResolved(CallFooWhenResolvedContext context) override; - - kj::Promise neverReturn(NeverReturnContext context) override; - - kj::Promise hold(HoldContext context) override; - - kj::Promise callHeld(CallHeldContext context) override; - - kj::Promise getHeld(GetHeldContext context) override; - - kj::Promise echo(EchoContext context) override; - - kj::Promise expectCancel(ExpectCancelContext context) override; - - kj::Promise getHandle(GetHandleContext context) override; - - kj::Promise getNull(GetNullContext context) override; - -private: - int& callCount; - int& handleCount; - test::TestInterface::Client clientToHold = nullptr; - - kj::Promise loop(uint depth, test::TestInterface::Client cap, ExpectCancelContext context); -}; - -class TestCapDestructor final: public test::TestInterface::Server { - // Implementation of TestInterface that notifies when it is destroyed. - -public: - TestCapDestructor(kj::Own>&& fulfiller) - : fulfiller(kj::mv(fulfiller)), impl(dummy) {} - - ~TestCapDestructor() { - fulfiller->fulfill(); - } - - kj::Promise foo(FooContext context) { - return impl.foo(context); - } - -private: - kj::Own> fulfiller; - int dummy = 0; - TestInterfaceImpl impl; -}; - -#endif // !CAPNP_LITE - -} // namespace _ (private) -} // namespace capnp - -#endif // TEST_UTIL_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. + +#ifndef CAPNP_TEST_UTIL_H_ +#define CAPNP_TEST_UTIL_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include +#include +#include "blob.h" +#include + +#if !CAPNP_LITE +#include "dynamic.h" +#endif // !CAPNP_LITE + +// TODO(cleanup): Auto-generate stringification functions for union discriminants. +namespace capnproto_test { +namespace capnp { +namespace test { +inline kj::String KJ_STRINGIFY(TestUnion::Union0::Which which) { + return kj::str(static_cast(which)); +} +inline kj::String KJ_STRINGIFY(TestUnion::Union1::Which which) { + return kj::str(static_cast(which)); +} +inline kj::String KJ_STRINGIFY(TestUnion::Union2::Which which) { + return kj::str(static_cast(which)); +} +inline kj::String KJ_STRINGIFY(TestUnion::Union3::Which which) { + return kj::str(static_cast(which)); +} +inline kj::String KJ_STRINGIFY(TestUnnamedUnion::Which which) { + return kj::str(static_cast(which)); +} +inline kj::String KJ_STRINGIFY(TestGroups::Groups::Which which) { + return kj::str(static_cast(which)); +} +inline kj::String KJ_STRINGIFY(TestInterleavedGroups::Group1::Which which) { + return kj::str(static_cast(which)); +} +} // namespace test +} // namespace capnp +} // namespace capnproto_test + +namespace capnp { +namespace _ { // private + +inline Data::Reader data(const char* str) { + return Data::Reader(reinterpret_cast(str), strlen(str)); +} + +namespace test = capnproto_test::capnp::test; + +// We don't use "using namespace" to pull these in because then things would still compile +// correctly if they were generated in the global namespace. +using ::capnproto_test::capnp::test::TestAllTypes; +using ::capnproto_test::capnp::test::TestDefaults; +using ::capnproto_test::capnp::test::TestEnum; +using ::capnproto_test::capnp::test::TestUnion; +using ::capnproto_test::capnp::test::TestUnionDefaults; +using ::capnproto_test::capnp::test::TestNestedTypes; +using ::capnproto_test::capnp::test::TestUsing; +using ::capnproto_test::capnp::test::TestListDefaults; + +void initTestMessage(TestAllTypes::Builder builder); +void initTestMessage(TestDefaults::Builder builder); +void initTestMessage(TestListDefaults::Builder builder); + +void checkTestMessage(TestAllTypes::Builder builder); +void checkTestMessage(TestDefaults::Builder builder); +void checkTestMessage(TestListDefaults::Builder builder); + +void checkTestMessage(TestAllTypes::Reader reader); +void checkTestMessage(TestDefaults::Reader reader); +void checkTestMessage(TestListDefaults::Reader reader); + +void checkTestMessageAllZero(TestAllTypes::Builder builder); +void checkTestMessageAllZero(TestAllTypes::Reader reader); + +#if !CAPNP_LITE +void initDynamicTestMessage(DynamicStruct::Builder builder); +void initDynamicTestLists(DynamicStruct::Builder builder); +void checkDynamicTestMessage(DynamicStruct::Builder builder); +void checkDynamicTestLists(DynamicStruct::Builder builder); +void checkDynamicTestMessage(DynamicStruct::Reader reader); +void checkDynamicTestLists(DynamicStruct::Reader reader); +void checkDynamicTestMessageAllZero(DynamicStruct::Builder builder); +void checkDynamicTestMessageAllZero(DynamicStruct::Reader reader); +#endif // !CAPNP_LITE + +template +inline void checkElement(T a, T b) { + EXPECT_EQ(a, b); +} + +template <> +inline void checkElement(float a, float b) { + EXPECT_FLOAT_EQ(a, b); +} + +template <> +inline void checkElement(double a, double b) { + EXPECT_DOUBLE_EQ(a, b); +} + +template +void checkList(T reader, std::initializer_list expected) { + ASSERT_EQ(expected.size(), reader.size()); + for (uint i = 0; i < expected.size(); i++) { + checkElement(expected.begin()[i], reader[i]); + } +} + +template +void checkList(T reader, std::initializer_list expected) { + ASSERT_EQ(expected.size(), reader.size()); + for (uint i = 0; i < expected.size(); i++) { + checkElement(expected.begin()[i], reader[i]); + } +} + +inline void checkList(List::Reader reader, + std::initializer_list expectedData, + std::initializer_list expectedPointers) { + ASSERT_EQ(expectedData.size(), reader.size()); + for (uint i = 0; i < expectedData.size(); i++) { + EXPECT_EQ(expectedData.begin()[i], reader[i].getOld1()); + EXPECT_EQ(expectedPointers.begin()[i], reader[i].getOld2()); + } +} + +// Hack because as<>() is a template-parameter-dependent lookup everywhere below... +#define as template as + +template void expectPrimitiveEq(T a, T b) { EXPECT_EQ(a, b); } +inline void expectPrimitiveEq(float a, float b) { EXPECT_FLOAT_EQ(a, b); } +inline void expectPrimitiveEq(double a, double b) { EXPECT_DOUBLE_EQ(a, b); } +inline void expectPrimitiveEq(Text::Reader a, Text::Builder b) { EXPECT_EQ(a, b); } +inline void expectPrimitiveEq(Data::Reader a, Data::Builder b) { EXPECT_EQ(a, b); } + +#if !CAPNP_LITE +template +void checkList(T reader, std::initializer_list> expected) { + auto list = reader.as(); + ASSERT_EQ(expected.size(), list.size()); + for (uint i = 0; i < expected.size(); i++) { + expectPrimitiveEq(expected.begin()[i], list[i].as()); + } + + auto typed = reader.as>(); + ASSERT_EQ(expected.size(), typed.size()); + for (uint i = 0; i < expected.size(); i++) { + expectPrimitiveEq(expected.begin()[i], typed[i]); + } +} +#endif // !CAPNP_LITE + +#undef as + +// ======================================================================================= +// Interface implementations. + +#if !CAPNP_LITE + +class TestInterfaceImpl final: public test::TestInterface::Server { +public: + TestInterfaceImpl(int& callCount); + + kj::Promise foo(FooContext context) override; + + kj::Promise baz(BazContext context) override; + +private: + int& callCount; +}; + +class TestExtendsImpl final: public test::TestExtends2::Server { +public: + TestExtendsImpl(int& callCount); + + kj::Promise foo(FooContext context) override; + + kj::Promise grault(GraultContext context) override; + +private: + int& callCount; +}; + +class TestPipelineImpl final: public test::TestPipeline::Server { +public: + TestPipelineImpl(int& callCount); + + kj::Promise getCap(GetCapContext context) override; + kj::Promise getAnyCap(GetAnyCapContext context) override; + +private: + int& callCount; +}; + +class TestCallOrderImpl final: public test::TestCallOrder::Server { +public: + kj::Promise getCallSequence(GetCallSequenceContext context) override; + +private: + uint count = 0; +}; + +class TestTailCallerImpl final: public test::TestTailCaller::Server { +public: + TestTailCallerImpl(int& callCount); + + kj::Promise foo(FooContext context) override; + +private: + int& callCount; +}; + +class TestTailCalleeImpl final: public test::TestTailCallee::Server { +public: + TestTailCalleeImpl(int& callCount); + + kj::Promise foo(FooContext context) override; + +private: + int& callCount; +}; + +class TestMoreStuffImpl final: public test::TestMoreStuff::Server { +public: + TestMoreStuffImpl(int& callCount, int& handleCount); + + kj::Promise getCallSequence(GetCallSequenceContext context) override; + + kj::Promise callFoo(CallFooContext context) override; + + kj::Promise callFooWhenResolved(CallFooWhenResolvedContext context) override; + + kj::Promise neverReturn(NeverReturnContext context) override; + + kj::Promise hold(HoldContext context) override; + + kj::Promise callHeld(CallHeldContext context) override; + + kj::Promise getHeld(GetHeldContext context) override; + + kj::Promise echo(EchoContext context) override; + + kj::Promise expectCancel(ExpectCancelContext context) override; + + kj::Promise getHandle(GetHandleContext context) override; + + kj::Promise getNull(GetNullContext context) override; + + kj::Promise getEnormousString(GetEnormousStringContext context) override; + +private: + int& callCount; + int& handleCount; + test::TestInterface::Client clientToHold = nullptr; + + kj::Promise loop(uint depth, test::TestInterface::Client cap, ExpectCancelContext context); +}; + +class TestCapDestructor final: public test::TestInterface::Server { + // Implementation of TestInterface that notifies when it is destroyed. + +public: + TestCapDestructor(kj::Own>&& fulfiller) + : fulfiller(kj::mv(fulfiller)), impl(dummy) {} + + ~TestCapDestructor() { + fulfiller->fulfill(); + } + + kj::Promise foo(FooContext context) { + return impl.foo(context); + } + +private: + kj::Own> fulfiller; + int dummy = 0; + TestInterfaceImpl impl; +}; + +#endif // !CAPNP_LITE + +} // namespace _ (private) +} // namespace capnp + +#endif // TEST_UTIL_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/arena.h --- a/win32-mingw/include/kj/arena.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/arena.h Tue May 23 09:16:54 2017 +0100 @@ -1,213 +1,213 @@ -// 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. - -#ifndef KJ_ARENA_H_ -#define KJ_ARENA_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "memory.h" -#include "array.h" -#include "string.h" - -namespace kj { - -class Arena { - // A class which allows several objects to be allocated in contiguous chunks of memory, then - // frees them all at once. - // - // Allocating from the same Arena in multiple threads concurrently is NOT safe, because making - // it safe would require atomic operations that would slow down allocation even when - // single-threaded. If you need to use arena allocation in a multithreaded context, consider - // allocating thread-local arenas. - -public: - explicit Arena(size_t chunkSizeHint = 1024); - // Create an Arena. `chunkSizeHint` hints at where to start when allocating chunks, but is only - // a hint -- the Arena will, for example, allocate progressively larger chunks as time goes on, - // in order to reduce overall allocation overhead. - - explicit Arena(ArrayPtr scratch); - // Allocates from the given scratch space first, only resorting to the heap when it runs out. - - KJ_DISALLOW_COPY(Arena); - ~Arena() noexcept(false); - - template - T& allocate(Params&&... params); - template - ArrayPtr allocateArray(size_t size); - // Allocate an object or array of type T. If T has a non-trivial destructor, that destructor - // will be run during the Arena's destructor. Such destructors are run in opposite order of - // allocation. Note that these methods must maintain a list of destructors to call, which has - // overhead, but this overhead only applies if T has a non-trivial destructor. - - template - Own allocateOwn(Params&&... params); - template - Array allocateOwnArray(size_t size); - template - ArrayBuilder allocateOwnArrayBuilder(size_t capacity); - // Allocate an object or array of type T. Destructors are executed when the returned Own - // or Array goes out-of-scope, which must happen before the Arena is destroyed. This variant - // is useful when you need to control when the destructor is called. This variant also avoids - // the need for the Arena itself to keep track of destructors to call later, which may make it - // slightly more efficient. - - template - inline T& copy(T&& value) { return allocate>(kj::fwd(value)); } - // Allocate a copy of the given value in the arena. This is just a shortcut for calling the - // type's copy (or move) constructor. - - StringPtr copyString(StringPtr content); - // Make a copy of the given string inside the arena, and return a pointer to the copy. - -private: - struct ChunkHeader { - ChunkHeader* next; - byte* pos; // first unallocated byte in this chunk - byte* end; // end of this chunk - }; - struct ObjectHeader { - void (*destructor)(void*); - ObjectHeader* next; - }; - - size_t nextChunkSize; - ChunkHeader* chunkList = nullptr; - ObjectHeader* objectList = nullptr; - - ChunkHeader* currentChunk = nullptr; - - void cleanup(); - // Run all destructors, leaving the above pointers null. If a destructor throws, the State is - // left in a consistent state, such that if cleanup() is called again, it will pick up where - // it left off. - - void* allocateBytes(size_t amount, uint alignment, bool hasDisposer); - // Allocate the given number of bytes. `hasDisposer` must be true if `setDisposer()` may be - // called on this pointer later. - - void* allocateBytesInternal(size_t amount, uint alignment); - // Try to allocate the given number of bytes without taking a lock. Fails if and only if there - // is no space left in the current chunk. - - void setDestructor(void* ptr, void (*destructor)(void*)); - // Schedule the given destructor to be executed when the Arena is destroyed. `ptr` must be a - // pointer previously returned by an `allocateBytes()` call for which `hasDisposer` was true. - - template - static void destroyArray(void* pointer) { - size_t elementCount = *reinterpret_cast(pointer); - constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); - DestructorOnlyArrayDisposer::instance.disposeImpl( - reinterpret_cast(pointer) + prefixSize, - sizeof(T), elementCount, elementCount, &destroyObject); - } - - template - static void destroyObject(void* pointer) { - dtor(*reinterpret_cast(pointer)); - } -}; - -// ======================================================================================= -// Inline implementation details - -template -T& Arena::allocate(Params&&... params) { - T& result = *reinterpret_cast(allocateBytes( - sizeof(T), alignof(T), !__has_trivial_destructor(T))); - if (!__has_trivial_constructor(T) || sizeof...(Params) > 0) { - ctor(result, kj::fwd(params)...); - } - if (!__has_trivial_destructor(T)) { - setDestructor(&result, &destroyObject); - } - return result; -} - -template -ArrayPtr Arena::allocateArray(size_t size) { - if (__has_trivial_destructor(T)) { - ArrayPtr result = - arrayPtr(reinterpret_cast(allocateBytes( - sizeof(T) * size, alignof(T), false)), size); - if (!__has_trivial_constructor(T)) { - for (size_t i = 0; i < size; i++) { - ctor(result[i]); - } - } - return result; - } else { - // Allocate with a 64-bit prefix in which we store the array size. - constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); - void* base = allocateBytes(sizeof(T) * size + prefixSize, alignof(T), true); - size_t& tag = *reinterpret_cast(base); - ArrayPtr result = - arrayPtr(reinterpret_cast(reinterpret_cast(base) + prefixSize), size); - setDestructor(base, &destroyArray); - - if (__has_trivial_constructor(T)) { - tag = size; - } else { - // In case of constructor exceptions, we need the tag to end up storing the number of objects - // that were successfully constructed, so that they'll be properly destroyed. - tag = 0; - for (size_t i = 0; i < size; i++) { - ctor(result[i]); - tag = i + 1; - } - } - return result; - } -} - -template -Own Arena::allocateOwn(Params&&... params) { - T& result = *reinterpret_cast(allocateBytes(sizeof(T), alignof(T), false)); - if (!__has_trivial_constructor(T) || sizeof...(Params) > 0) { - ctor(result, kj::fwd(params)...); - } - return Own(&result, DestructorOnlyDisposer::instance); -} - -template -Array Arena::allocateOwnArray(size_t size) { - ArrayBuilder result = allocateOwnArrayBuilder(size); - for (size_t i = 0; i < size; i++) { - result.add(); - } - return result.finish(); -} - -template -ArrayBuilder Arena::allocateOwnArrayBuilder(size_t capacity) { - return ArrayBuilder( - reinterpret_cast(allocateBytes(sizeof(T) * capacity, alignof(T), false)), - capacity, DestructorOnlyArrayDisposer::instance); -} - -} // namespace kj - -#endif // KJ_ARENA_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. + +#ifndef KJ_ARENA_H_ +#define KJ_ARENA_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "memory.h" +#include "array.h" +#include "string.h" + +namespace kj { + +class Arena { + // A class which allows several objects to be allocated in contiguous chunks of memory, then + // frees them all at once. + // + // Allocating from the same Arena in multiple threads concurrently is NOT safe, because making + // it safe would require atomic operations that would slow down allocation even when + // single-threaded. If you need to use arena allocation in a multithreaded context, consider + // allocating thread-local arenas. + +public: + explicit Arena(size_t chunkSizeHint = 1024); + // Create an Arena. `chunkSizeHint` hints at where to start when allocating chunks, but is only + // a hint -- the Arena will, for example, allocate progressively larger chunks as time goes on, + // in order to reduce overall allocation overhead. + + explicit Arena(ArrayPtr scratch); + // Allocates from the given scratch space first, only resorting to the heap when it runs out. + + KJ_DISALLOW_COPY(Arena); + ~Arena() noexcept(false); + + template + T& allocate(Params&&... params); + template + ArrayPtr allocateArray(size_t size); + // Allocate an object or array of type T. If T has a non-trivial destructor, that destructor + // will be run during the Arena's destructor. Such destructors are run in opposite order of + // allocation. Note that these methods must maintain a list of destructors to call, which has + // overhead, but this overhead only applies if T has a non-trivial destructor. + + template + Own allocateOwn(Params&&... params); + template + Array allocateOwnArray(size_t size); + template + ArrayBuilder allocateOwnArrayBuilder(size_t capacity); + // Allocate an object or array of type T. Destructors are executed when the returned Own + // or Array goes out-of-scope, which must happen before the Arena is destroyed. This variant + // is useful when you need to control when the destructor is called. This variant also avoids + // the need for the Arena itself to keep track of destructors to call later, which may make it + // slightly more efficient. + + template + inline T& copy(T&& value) { return allocate>(kj::fwd(value)); } + // Allocate a copy of the given value in the arena. This is just a shortcut for calling the + // type's copy (or move) constructor. + + StringPtr copyString(StringPtr content); + // Make a copy of the given string inside the arena, and return a pointer to the copy. + +private: + struct ChunkHeader { + ChunkHeader* next; + byte* pos; // first unallocated byte in this chunk + byte* end; // end of this chunk + }; + struct ObjectHeader { + void (*destructor)(void*); + ObjectHeader* next; + }; + + size_t nextChunkSize; + ChunkHeader* chunkList = nullptr; + ObjectHeader* objectList = nullptr; + + ChunkHeader* currentChunk = nullptr; + + void cleanup(); + // Run all destructors, leaving the above pointers null. If a destructor throws, the State is + // left in a consistent state, such that if cleanup() is called again, it will pick up where + // it left off. + + void* allocateBytes(size_t amount, uint alignment, bool hasDisposer); + // Allocate the given number of bytes. `hasDisposer` must be true if `setDisposer()` may be + // called on this pointer later. + + void* allocateBytesInternal(size_t amount, uint alignment); + // Try to allocate the given number of bytes without taking a lock. Fails if and only if there + // is no space left in the current chunk. + + void setDestructor(void* ptr, void (*destructor)(void*)); + // Schedule the given destructor to be executed when the Arena is destroyed. `ptr` must be a + // pointer previously returned by an `allocateBytes()` call for which `hasDisposer` was true. + + template + static void destroyArray(void* pointer) { + size_t elementCount = *reinterpret_cast(pointer); + constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); + DestructorOnlyArrayDisposer::instance.disposeImpl( + reinterpret_cast(pointer) + prefixSize, + sizeof(T), elementCount, elementCount, &destroyObject); + } + + template + static void destroyObject(void* pointer) { + dtor(*reinterpret_cast(pointer)); + } +}; + +// ======================================================================================= +// Inline implementation details + +template +T& Arena::allocate(Params&&... params) { + T& result = *reinterpret_cast(allocateBytes( + sizeof(T), alignof(T), !__has_trivial_destructor(T))); + if (!__has_trivial_constructor(T) || sizeof...(Params) > 0) { + ctor(result, kj::fwd(params)...); + } + if (!__has_trivial_destructor(T)) { + setDestructor(&result, &destroyObject); + } + return result; +} + +template +ArrayPtr Arena::allocateArray(size_t size) { + if (__has_trivial_destructor(T)) { + ArrayPtr result = + arrayPtr(reinterpret_cast(allocateBytes( + sizeof(T) * size, alignof(T), false)), size); + if (!__has_trivial_constructor(T)) { + for (size_t i = 0; i < size; i++) { + ctor(result[i]); + } + } + return result; + } else { + // Allocate with a 64-bit prefix in which we store the array size. + constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); + void* base = allocateBytes(sizeof(T) * size + prefixSize, alignof(T), true); + size_t& tag = *reinterpret_cast(base); + ArrayPtr result = + arrayPtr(reinterpret_cast(reinterpret_cast(base) + prefixSize), size); + setDestructor(base, &destroyArray); + + if (__has_trivial_constructor(T)) { + tag = size; + } else { + // In case of constructor exceptions, we need the tag to end up storing the number of objects + // that were successfully constructed, so that they'll be properly destroyed. + tag = 0; + for (size_t i = 0; i < size; i++) { + ctor(result[i]); + tag = i + 1; + } + } + return result; + } +} + +template +Own Arena::allocateOwn(Params&&... params) { + T& result = *reinterpret_cast(allocateBytes(sizeof(T), alignof(T), false)); + if (!__has_trivial_constructor(T) || sizeof...(Params) > 0) { + ctor(result, kj::fwd(params)...); + } + return Own(&result, DestructorOnlyDisposer::instance); +} + +template +Array Arena::allocateOwnArray(size_t size) { + ArrayBuilder result = allocateOwnArrayBuilder(size); + for (size_t i = 0; i < size; i++) { + result.add(); + } + return result.finish(); +} + +template +ArrayBuilder Arena::allocateOwnArrayBuilder(size_t capacity) { + return ArrayBuilder( + reinterpret_cast(allocateBytes(sizeof(T) * capacity, alignof(T), false)), + capacity, DestructorOnlyArrayDisposer::instance); +} + +} // namespace kj + +#endif // KJ_ARENA_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/array.h --- a/win32-mingw/include/kj/array.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/array.h Tue May 23 09:16:54 2017 +0100 @@ -1,723 +1,813 @@ -// 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. - -#ifndef KJ_ARRAY_H_ -#define KJ_ARRAY_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" -#include -#include - -namespace kj { - -// ======================================================================================= -// ArrayDisposer -- Implementation details. - -class ArrayDisposer { - // Much like Disposer from memory.h. - -protected: - // Do not declare a destructor, as doing so will force a global initializer for - // HeapArrayDisposer::instance. - - virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, - size_t capacity, void (*destroyElement)(void*)) const = 0; - // Disposes of the array. `destroyElement` invokes the destructor of each element, or is nullptr - // if the elements have trivial destructors. `capacity` is the amount of space that was - // allocated while `elementCount` is the number of elements that were actually constructed; - // these are always the same number for Array but may be different when using ArrayBuilder. - -public: - - template - void dispose(T* firstElement, size_t elementCount, size_t capacity) const; - // Helper wrapper around disposeImpl(). - // - // Callers must not call dispose() on the same array twice, even if the first call throws - // an exception. - -private: - template - struct Dispose_; -}; - -class ExceptionSafeArrayUtil { - // Utility class that assists in constructing or destroying elements of an array, where the - // constructor or destructor could throw exceptions. In case of an exception, - // ExceptionSafeArrayUtil's destructor will call destructors on all elements that have been - // constructed but not destroyed. Remember that destructors that throw exceptions are required - // to use UnwindDetector to detect unwind and avoid exceptions in this case. Therefore, no more - // than one exception will be thrown (and the program will not terminate). - -public: - inline ExceptionSafeArrayUtil(void* ptr, size_t elementSize, size_t constructedElementCount, - void (*destroyElement)(void*)) - : pos(reinterpret_cast(ptr) + elementSize * constructedElementCount), - elementSize(elementSize), constructedElementCount(constructedElementCount), - destroyElement(destroyElement) {} - KJ_DISALLOW_COPY(ExceptionSafeArrayUtil); - - inline ~ExceptionSafeArrayUtil() noexcept(false) { - if (constructedElementCount > 0) destroyAll(); - } - - void construct(size_t count, void (*constructElement)(void*)); - // Construct the given number of elements. - - void destroyAll(); - // Destroy all elements. Call this immediately before ExceptionSafeArrayUtil goes out-of-scope - // to ensure that one element throwing an exception does not prevent the others from being - // destroyed. - - void release() { constructedElementCount = 0; } - // Prevent ExceptionSafeArrayUtil's destructor from destroying the constructed elements. - // Call this after you've successfully finished constructing. - -private: - byte* pos; - size_t elementSize; - size_t constructedElementCount; - void (*destroyElement)(void*); -}; - -class DestructorOnlyArrayDisposer: public ArrayDisposer { -public: - static const DestructorOnlyArrayDisposer instance; - - void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, - size_t capacity, void (*destroyElement)(void*)) const override; -}; - -class NullArrayDisposer: public ArrayDisposer { - // An ArrayDisposer that does nothing. Can be used to construct a fake Arrays that doesn't - // actually own its content. - -public: - static const NullArrayDisposer instance; - - void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, - size_t capacity, void (*destroyElement)(void*)) const override; -}; - -// ======================================================================================= -// Array - -template -class Array { - // An owned array which will automatically be disposed of (using an ArrayDisposer) in the - // destructor. Can be moved, but not copied. Much like Own, but for arrays rather than - // single objects. - -public: - inline Array(): ptr(nullptr), size_(0), disposer(nullptr) {} - inline Array(decltype(nullptr)): ptr(nullptr), size_(0), disposer(nullptr) {} - inline Array(Array&& other) noexcept - : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { - other.ptr = nullptr; - other.size_ = 0; - } - inline Array(Array>&& other) noexcept - : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { - other.ptr = nullptr; - other.size_ = 0; - } - inline Array(T* firstElement, size_t size, const ArrayDisposer& disposer) - : ptr(firstElement), size_(size), disposer(&disposer) {} - - KJ_DISALLOW_COPY(Array); - inline ~Array() noexcept { dispose(); } - - inline operator ArrayPtr() { - return ArrayPtr(ptr, size_); - } - inline operator ArrayPtr() const { - return ArrayPtr(ptr, size_); - } - inline ArrayPtr asPtr() { - return ArrayPtr(ptr, size_); - } - inline ArrayPtr asPtr() const { - return ArrayPtr(ptr, size_); - } - - inline size_t size() const { return size_; } - inline T& operator[](size_t index) const { - KJ_IREQUIRE(index < size_, "Out-of-bounds Array access."); - return ptr[index]; - } - - inline const T* begin() const { return ptr; } - inline const T* end() const { return ptr + size_; } - inline const T& front() const { return *ptr; } - inline const T& back() const { return *(ptr + size_ - 1); } - inline T* begin() { return ptr; } - inline T* end() { return ptr + size_; } - inline T& front() { return *ptr; } - inline T& back() { return *(ptr + size_ - 1); } - - inline ArrayPtr slice(size_t start, size_t end) { - KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); - return ArrayPtr(ptr + start, end - start); - } - inline ArrayPtr slice(size_t start, size_t end) const { - KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); - return ArrayPtr(ptr + start, end - start); - } - - inline ArrayPtr asBytes() const { return asPtr().asBytes(); } - inline ArrayPtr> asBytes() { return asPtr().asBytes(); } - inline ArrayPtr asChars() const { return asPtr().asChars(); } - inline ArrayPtr> asChars() { return asPtr().asChars(); } - - inline Array> releaseAsBytes() { - // Like asBytes() but transfers ownership. - static_assert(sizeof(T) == sizeof(byte), - "releaseAsBytes() only possible on arrays with byte-size elements (e.g. chars)."); - Array> result( - reinterpret_cast*>(ptr), size_, *disposer); - ptr = nullptr; - size_ = 0; - return result; - } - inline Array> releaseAsChars() { - // Like asChars() but transfers ownership. - static_assert(sizeof(T) == sizeof(PropagateConst), - "releaseAsChars() only possible on arrays with char-size elements (e.g. bytes)."); - Array> result( - reinterpret_cast*>(ptr), size_, *disposer); - ptr = nullptr; - size_ = 0; - return result; - } - - inline bool operator==(decltype(nullptr)) const { return size_ == 0; } - inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } - - inline Array& operator=(decltype(nullptr)) { - dispose(); - return *this; - } - - inline Array& operator=(Array&& other) { - dispose(); - ptr = other.ptr; - size_ = other.size_; - disposer = other.disposer; - other.ptr = nullptr; - other.size_ = 0; - return *this; - } - -private: - T* ptr; - size_t size_; - const ArrayDisposer* disposer; - - inline void dispose() { - // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly - // dispose again. - T* ptrCopy = ptr; - size_t sizeCopy = size_; - if (ptrCopy != nullptr) { - ptr = nullptr; - size_ = 0; - disposer->dispose(ptrCopy, sizeCopy, sizeCopy); - } - } - - template - friend class Array; -}; - -namespace _ { // private - -class HeapArrayDisposer final: public ArrayDisposer { -public: - template - static T* allocate(size_t count); - template - static T* allocateUninitialized(size_t count); - - static const HeapArrayDisposer instance; - -private: - static void* allocateImpl(size_t elementSize, size_t elementCount, size_t capacity, - void (*constructElement)(void*), void (*destroyElement)(void*)); - // Allocates and constructs the array. Both function pointers are null if the constructor is - // trivial, otherwise destroyElement is null if the constructor doesn't throw. - - virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, - size_t capacity, void (*destroyElement)(void*)) const override; - - template - struct Allocate_; -}; - -} // namespace _ (private) - -template -inline Array heapArray(size_t size) { - // Much like `heap()` from memory.h, allocates a new array on the heap. - - return Array(_::HeapArrayDisposer::allocate(size), size, - _::HeapArrayDisposer::instance); -} - -template Array heapArray(const T* content, size_t size); -template Array heapArray(ArrayPtr content); -template Array heapArray(ArrayPtr content); -template Array heapArray(Iterator begin, Iterator end); -template Array heapArray(std::initializer_list init); -// Allocate a heap array containing a copy of the given content. - -template -Array heapArrayFromIterable(Container&& a) { return heapArray(a.begin(), a.end()); } -template -Array heapArrayFromIterable(Array&& a) { return mv(a); } - -// ======================================================================================= -// ArrayBuilder - -template -class ArrayBuilder { - // Class which lets you build an Array specifying the exact constructor arguments for each - // element, rather than starting by default-constructing them. - -public: - ArrayBuilder(): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} - ArrayBuilder(decltype(nullptr)): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} - explicit ArrayBuilder(RemoveConst* firstElement, size_t capacity, - const ArrayDisposer& disposer) - : ptr(firstElement), pos(firstElement), endPtr(firstElement + capacity), - disposer(&disposer) {} - ArrayBuilder(ArrayBuilder&& other) - : ptr(other.ptr), pos(other.pos), endPtr(other.endPtr), disposer(other.disposer) { - other.ptr = nullptr; - other.pos = nullptr; - other.endPtr = nullptr; - } - KJ_DISALLOW_COPY(ArrayBuilder); - inline ~ArrayBuilder() noexcept(false) { dispose(); } - - inline operator ArrayPtr() { - return arrayPtr(ptr, pos); - } - inline operator ArrayPtr() const { - return arrayPtr(ptr, pos); - } - inline ArrayPtr asPtr() { - return arrayPtr(ptr, pos); - } - inline ArrayPtr asPtr() const { - return arrayPtr(ptr, pos); - } - - inline size_t size() const { return pos - ptr; } - inline size_t capacity() const { return endPtr - ptr; } - inline T& operator[](size_t index) const { - KJ_IREQUIRE(index < implicitCast(pos - ptr), "Out-of-bounds Array access."); - return ptr[index]; - } - - inline const T* begin() const { return ptr; } - inline const T* end() const { return pos; } - inline const T& front() const { return *ptr; } - inline const T& back() const { return *(pos - 1); } - inline T* begin() { return ptr; } - inline T* end() { return pos; } - inline T& front() { return *ptr; } - inline T& back() { return *(pos - 1); } - - ArrayBuilder& operator=(ArrayBuilder&& other) { - dispose(); - ptr = other.ptr; - pos = other.pos; - endPtr = other.endPtr; - disposer = other.disposer; - other.ptr = nullptr; - other.pos = nullptr; - other.endPtr = nullptr; - return *this; - } - ArrayBuilder& operator=(decltype(nullptr)) { - dispose(); - return *this; - } - - template - T& add(Params&&... params) { - KJ_IREQUIRE(pos < endPtr, "Added too many elements to ArrayBuilder."); - ctor(*pos, kj::fwd(params)...); - return *pos++; - } - - template - void addAll(Container&& container) { - addAll(container.begin(), container.end()); - } - - template - void addAll(Iterator start, Iterator end); - - void removeLast() { - KJ_IREQUIRE(pos > ptr, "No elements present to remove."); - kj::dtor(*--pos); - } - - Array finish() { - // We could safely remove this check if we assume that the disposer implementation doesn't - // need to know the original capacity, as is thes case with HeapArrayDisposer since it uses - // operator new() or if we created a custom disposer for ArrayBuilder which stores the capacity - // in a prefix. But that would make it hard to write cleverer heap allocators, and anyway this - // check might catch bugs. Probably people should use Vector if they want to build arrays - // without knowing the final size in advance. - KJ_IREQUIRE(pos == endPtr, "ArrayBuilder::finish() called prematurely."); - Array result(reinterpret_cast(ptr), pos - ptr, *disposer); - ptr = nullptr; - pos = nullptr; - endPtr = nullptr; - return result; - } - - inline bool isFull() const { - return pos == endPtr; - } - -private: - T* ptr; - RemoveConst* pos; - T* endPtr; - const ArrayDisposer* disposer; - - inline void dispose() { - // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly - // dispose again. - T* ptrCopy = ptr; - T* posCopy = pos; - T* endCopy = endPtr; - if (ptrCopy != nullptr) { - ptr = nullptr; - pos = nullptr; - endPtr = nullptr; - disposer->dispose(ptrCopy, posCopy - ptrCopy, endCopy - ptrCopy); - } - } -}; - -template -inline ArrayBuilder heapArrayBuilder(size_t size) { - // Like `heapArray()` but does not default-construct the elements. You must construct them - // manually by calling `add()`. - - return ArrayBuilder(_::HeapArrayDisposer::allocateUninitialized>(size), - size, _::HeapArrayDisposer::instance); -} - -// ======================================================================================= -// Inline Arrays - -template -class FixedArray { - // A fixed-width array whose storage is allocated inline rather than on the heap. - -public: - inline size_t size() const { return fixedSize; } - inline T* begin() { return content; } - inline T* end() { return content + fixedSize; } - inline const T* begin() const { return content; } - inline const T* end() const { return content + fixedSize; } - - inline operator ArrayPtr() { - return arrayPtr(content, fixedSize); - } - inline operator ArrayPtr() const { - return arrayPtr(content, fixedSize); - } - - inline T& operator[](size_t index) { return content[index]; } - inline const T& operator[](size_t index) const { return content[index]; } - -private: - T content[fixedSize]; -}; - -template -class CappedArray { - // Like `FixedArray` but can be dynamically resized as long as the size does not exceed the limit - // specified by the template parameter. - // - // TODO(someday): Don't construct elements past currentSize? - -public: - inline KJ_CONSTEXPR() CappedArray(): currentSize(fixedSize) {} - inline explicit constexpr CappedArray(size_t s): currentSize(s) {} - - inline size_t size() const { return currentSize; } - inline void setSize(size_t s) { KJ_IREQUIRE(s <= fixedSize); currentSize = s; } - inline T* begin() { return content; } - inline T* end() { return content + currentSize; } - inline const T* begin() const { return content; } - inline const T* end() const { return content + currentSize; } - - inline operator ArrayPtr() { - return arrayPtr(content, currentSize); - } - inline operator ArrayPtr() const { - return arrayPtr(content, currentSize); - } - - inline T& operator[](size_t index) { return content[index]; } - inline const T& operator[](size_t index) const { return content[index]; } - -private: - size_t currentSize; - T content[fixedSize]; -}; - -// ======================================================================================= -// KJ_MAP - -#define KJ_MAP(elementName, array) \ - ::kj::_::Mapper(array) * [&](decltype(*(array).begin()) elementName) -// Applies some function to every element of an array, returning an Array of the results, with -// nice syntax. Example: -// -// StringPtr foo = "abcd"; -// Array bar = KJ_MAP(c, foo) -> char { return c + 1; }; -// KJ_ASSERT(str(bar) == "bcde"); - -namespace _ { // private - -template -struct Mapper { - T array; - Mapper(T&& array): array(kj::fwd(array)) {} - template - auto operator*(Func&& func) -> Array { - auto builder = heapArrayBuilder(array.size()); - for (auto iter = array.begin(); iter != array.end(); ++iter) { - builder.add(func(*iter)); - } - return builder.finish(); - } -}; - -} // namespace _ (private) - -// ======================================================================================= -// Inline implementation details - -template -struct ArrayDisposer::Dispose_ { - static void dispose(T* firstElement, size_t elementCount, size_t capacity, - const ArrayDisposer& disposer) { - disposer.disposeImpl(const_cast*>(firstElement), - sizeof(T), elementCount, capacity, nullptr); - } -}; -template -struct ArrayDisposer::Dispose_ { - static void destruct(void* ptr) { - kj::dtor(*reinterpret_cast(ptr)); - } - - static void dispose(T* firstElement, size_t elementCount, size_t capacity, - const ArrayDisposer& disposer) { - disposer.disposeImpl(firstElement, sizeof(T), elementCount, capacity, &destruct); - } -}; - -template -void ArrayDisposer::dispose(T* firstElement, size_t elementCount, size_t capacity) const { - Dispose_::dispose(firstElement, elementCount, capacity, *this); -} - -namespace _ { // private - -template -struct HeapArrayDisposer::Allocate_ { - static T* allocate(size_t elementCount, size_t capacity) { - return reinterpret_cast(allocateImpl( - sizeof(T), elementCount, capacity, nullptr, nullptr)); - } -}; -template -struct HeapArrayDisposer::Allocate_ { - static void construct(void* ptr) { - kj::ctor(*reinterpret_cast(ptr)); - } - static T* allocate(size_t elementCount, size_t capacity) { - return reinterpret_cast(allocateImpl( - sizeof(T), elementCount, capacity, &construct, nullptr)); - } -}; -template -struct HeapArrayDisposer::Allocate_ { - static void construct(void* ptr) { - kj::ctor(*reinterpret_cast(ptr)); - } - static void destruct(void* ptr) { - kj::dtor(*reinterpret_cast(ptr)); - } - static T* allocate(size_t elementCount, size_t capacity) { - return reinterpret_cast(allocateImpl( - sizeof(T), elementCount, capacity, &construct, &destruct)); - } -}; - -template -T* HeapArrayDisposer::allocate(size_t count) { - return Allocate_::allocate(count, count); -} - -template -T* HeapArrayDisposer::allocateUninitialized(size_t count) { - return Allocate_::allocate(0, count); -} - -template ()> -struct CopyConstructArray_; - -template -struct CopyConstructArray_ { - static inline T* apply(T* __restrict__ pos, T* start, T* end) { - memcpy(pos, start, reinterpret_cast(end) - reinterpret_cast(start)); - return pos + (end - start); - } -}; - -template -struct CopyConstructArray_ { - static inline T* apply(T* __restrict__ pos, const T* start, const T* end) { - memcpy(pos, start, reinterpret_cast(end) - reinterpret_cast(start)); - return pos + (end - start); - } -}; - -template -struct CopyConstructArray_ { - static inline T* apply(T* __restrict__ pos, Iterator start, Iterator end) { - // Since both the copy constructor and assignment operator are trivial, we know that assignment - // is equivalent to copy-constructing. So we can make this case somewhat easier for the - // compiler to optimize. - while (start != end) { - *pos++ = *start++; - } - return pos; - } -}; - -template -struct CopyConstructArray_ { - struct ExceptionGuard { - T* start; - T* pos; - inline explicit ExceptionGuard(T* pos): start(pos), pos(pos) {} - ~ExceptionGuard() noexcept(false) { - while (pos > start) { - dtor(*--pos); - } - } - }; - - static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { - // Verify that T can be *implicitly* constructed from the source values. - if (false) implicitCast(*start); - - if (noexcept(T(*start))) { - while (start != end) { - ctor(*pos++, *start++); - } - return pos; - } else { - // Crap. This is complicated. - ExceptionGuard guard(pos); - while (start != end) { - ctor(*guard.pos, *start++); - ++guard.pos; - } - guard.start = guard.pos; - return guard.pos; - } - } -}; - -template -inline T* copyConstructArray(T* dst, Iterator start, Iterator end) { - return CopyConstructArray_>::apply(dst, start, end); -} - -} // namespace _ (private) - -template -template -void ArrayBuilder::addAll(Iterator start, Iterator end) { - pos = _::copyConstructArray(pos, start, end); -} - -template -Array heapArray(const T* content, size_t size) { - ArrayBuilder builder = heapArrayBuilder(size); - builder.addAll(content, content + size); - return builder.finish(); -} - -template -Array heapArray(T* content, size_t size) { - ArrayBuilder builder = heapArrayBuilder(size); - builder.addAll(content, content + size); - return builder.finish(); -} - -template -Array heapArray(ArrayPtr content) { - ArrayBuilder builder = heapArrayBuilder(content.size()); - builder.addAll(content); - return builder.finish(); -} - -template -Array heapArray(ArrayPtr content) { - ArrayBuilder builder = heapArrayBuilder(content.size()); - builder.addAll(content); - return builder.finish(); -} - -template Array -heapArray(Iterator begin, Iterator end) { - ArrayBuilder builder = heapArrayBuilder(end - begin); - builder.addAll(begin, end); - return builder.finish(); -} - -template -inline Array heapArray(std::initializer_list init) { - return heapArray(init.begin(), init.end()); -} - -} // namespace kj - -#endif // KJ_ARRAY_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. + +#ifndef KJ_ARRAY_H_ +#define KJ_ARRAY_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" +#include +#include + +namespace kj { + +// ======================================================================================= +// ArrayDisposer -- Implementation details. + +class ArrayDisposer { + // Much like Disposer from memory.h. + +protected: + // Do not declare a destructor, as doing so will force a global initializer for + // HeapArrayDisposer::instance. + + virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const = 0; + // Disposes of the array. `destroyElement` invokes the destructor of each element, or is nullptr + // if the elements have trivial destructors. `capacity` is the amount of space that was + // allocated while `elementCount` is the number of elements that were actually constructed; + // these are always the same number for Array but may be different when using ArrayBuilder. + +public: + + template + void dispose(T* firstElement, size_t elementCount, size_t capacity) const; + // Helper wrapper around disposeImpl(). + // + // Callers must not call dispose() on the same array twice, even if the first call throws + // an exception. + +private: + template + struct Dispose_; +}; + +class ExceptionSafeArrayUtil { + // Utility class that assists in constructing or destroying elements of an array, where the + // constructor or destructor could throw exceptions. In case of an exception, + // ExceptionSafeArrayUtil's destructor will call destructors on all elements that have been + // constructed but not destroyed. Remember that destructors that throw exceptions are required + // to use UnwindDetector to detect unwind and avoid exceptions in this case. Therefore, no more + // than one exception will be thrown (and the program will not terminate). + +public: + inline ExceptionSafeArrayUtil(void* ptr, size_t elementSize, size_t constructedElementCount, + void (*destroyElement)(void*)) + : pos(reinterpret_cast(ptr) + elementSize * constructedElementCount), + elementSize(elementSize), constructedElementCount(constructedElementCount), + destroyElement(destroyElement) {} + KJ_DISALLOW_COPY(ExceptionSafeArrayUtil); + + inline ~ExceptionSafeArrayUtil() noexcept(false) { + if (constructedElementCount > 0) destroyAll(); + } + + void construct(size_t count, void (*constructElement)(void*)); + // Construct the given number of elements. + + void destroyAll(); + // Destroy all elements. Call this immediately before ExceptionSafeArrayUtil goes out-of-scope + // to ensure that one element throwing an exception does not prevent the others from being + // destroyed. + + void release() { constructedElementCount = 0; } + // Prevent ExceptionSafeArrayUtil's destructor from destroying the constructed elements. + // Call this after you've successfully finished constructing. + +private: + byte* pos; + size_t elementSize; + size_t constructedElementCount; + void (*destroyElement)(void*); +}; + +class DestructorOnlyArrayDisposer: public ArrayDisposer { +public: + static const DestructorOnlyArrayDisposer instance; + + void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; +}; + +class NullArrayDisposer: public ArrayDisposer { + // An ArrayDisposer that does nothing. Can be used to construct a fake Arrays that doesn't + // actually own its content. + +public: + static const NullArrayDisposer instance; + + void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; +}; + +// ======================================================================================= +// Array + +template +class Array { + // An owned array which will automatically be disposed of (using an ArrayDisposer) in the + // destructor. Can be moved, but not copied. Much like Own, but for arrays rather than + // single objects. + +public: + inline Array(): ptr(nullptr), size_(0), disposer(nullptr) {} + inline Array(decltype(nullptr)): ptr(nullptr), size_(0), disposer(nullptr) {} + inline Array(Array&& other) noexcept + : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { + other.ptr = nullptr; + other.size_ = 0; + } + inline Array(Array>&& other) noexcept + : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { + other.ptr = nullptr; + other.size_ = 0; + } + inline Array(T* firstElement, size_t size, const ArrayDisposer& disposer) + : ptr(firstElement), size_(size), disposer(&disposer) {} + + KJ_DISALLOW_COPY(Array); + inline ~Array() noexcept { dispose(); } + + inline operator ArrayPtr() { + return ArrayPtr(ptr, size_); + } + inline operator ArrayPtr() const { + return ArrayPtr(ptr, size_); + } + inline ArrayPtr asPtr() { + return ArrayPtr(ptr, size_); + } + inline ArrayPtr asPtr() const { + return ArrayPtr(ptr, size_); + } + + inline size_t size() const { return size_; } + inline T& operator[](size_t index) const { + KJ_IREQUIRE(index < size_, "Out-of-bounds Array access."); + return ptr[index]; + } + + inline const T* begin() const { return ptr; } + inline const T* end() const { return ptr + size_; } + inline const T& front() const { return *ptr; } + inline const T& back() const { return *(ptr + size_ - 1); } + inline T* begin() { return ptr; } + inline T* end() { return ptr + size_; } + inline T& front() { return *ptr; } + inline T& back() { return *(ptr + size_ - 1); } + + inline ArrayPtr slice(size_t start, size_t end) { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); + return ArrayPtr(ptr + start, end - start); + } + inline ArrayPtr slice(size_t start, size_t end) const { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); + return ArrayPtr(ptr + start, end - start); + } + + inline ArrayPtr asBytes() const { return asPtr().asBytes(); } + inline ArrayPtr> asBytes() { return asPtr().asBytes(); } + inline ArrayPtr asChars() const { return asPtr().asChars(); } + inline ArrayPtr> asChars() { return asPtr().asChars(); } + + inline Array> releaseAsBytes() { + // Like asBytes() but transfers ownership. + static_assert(sizeof(T) == sizeof(byte), + "releaseAsBytes() only possible on arrays with byte-size elements (e.g. chars)."); + Array> result( + reinterpret_cast*>(ptr), size_, *disposer); + ptr = nullptr; + size_ = 0; + return result; + } + inline Array> releaseAsChars() { + // Like asChars() but transfers ownership. + static_assert(sizeof(T) == sizeof(PropagateConst), + "releaseAsChars() only possible on arrays with char-size elements (e.g. bytes)."); + Array> result( + reinterpret_cast*>(ptr), size_, *disposer); + ptr = nullptr; + size_ = 0; + return result; + } + + inline bool operator==(decltype(nullptr)) const { return size_ == 0; } + inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } + + inline Array& operator=(decltype(nullptr)) { + dispose(); + return *this; + } + + inline Array& operator=(Array&& other) { + dispose(); + ptr = other.ptr; + size_ = other.size_; + disposer = other.disposer; + other.ptr = nullptr; + other.size_ = 0; + return *this; + } + +private: + T* ptr; + size_t size_; + const ArrayDisposer* disposer; + + inline void dispose() { + // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly + // dispose again. + T* ptrCopy = ptr; + size_t sizeCopy = size_; + if (ptrCopy != nullptr) { + ptr = nullptr; + size_ = 0; + disposer->dispose(ptrCopy, sizeCopy, sizeCopy); + } + } + + template + friend class Array; +}; + +static_assert(!canMemcpy>(), "canMemcpy<>() is broken"); + +namespace _ { // private + +class HeapArrayDisposer final: public ArrayDisposer { +public: + template + static T* allocate(size_t count); + template + static T* allocateUninitialized(size_t count); + + static const HeapArrayDisposer instance; + +private: + static void* allocateImpl(size_t elementSize, size_t elementCount, size_t capacity, + void (*constructElement)(void*), void (*destroyElement)(void*)); + // Allocates and constructs the array. Both function pointers are null if the constructor is + // trivial, otherwise destroyElement is null if the constructor doesn't throw. + + virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; + + template + struct Allocate_; +}; + +} // namespace _ (private) + +template +inline Array heapArray(size_t size) { + // Much like `heap()` from memory.h, allocates a new array on the heap. + + return Array(_::HeapArrayDisposer::allocate(size), size, + _::HeapArrayDisposer::instance); +} + +template Array heapArray(const T* content, size_t size); +template Array heapArray(ArrayPtr content); +template Array heapArray(ArrayPtr content); +template Array heapArray(Iterator begin, Iterator end); +template Array heapArray(std::initializer_list init); +// Allocate a heap array containing a copy of the given content. + +template +Array heapArrayFromIterable(Container&& a) { return heapArray(a.begin(), a.end()); } +template +Array heapArrayFromIterable(Array&& a) { return mv(a); } + +// ======================================================================================= +// ArrayBuilder + +template +class ArrayBuilder { + // Class which lets you build an Array specifying the exact constructor arguments for each + // element, rather than starting by default-constructing them. + +public: + ArrayBuilder(): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} + ArrayBuilder(decltype(nullptr)): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} + explicit ArrayBuilder(RemoveConst* firstElement, size_t capacity, + const ArrayDisposer& disposer) + : ptr(firstElement), pos(firstElement), endPtr(firstElement + capacity), + disposer(&disposer) {} + ArrayBuilder(ArrayBuilder&& other) + : ptr(other.ptr), pos(other.pos), endPtr(other.endPtr), disposer(other.disposer) { + other.ptr = nullptr; + other.pos = nullptr; + other.endPtr = nullptr; + } + KJ_DISALLOW_COPY(ArrayBuilder); + inline ~ArrayBuilder() noexcept(false) { dispose(); } + + inline operator ArrayPtr() { + return arrayPtr(ptr, pos); + } + inline operator ArrayPtr() const { + return arrayPtr(ptr, pos); + } + inline ArrayPtr asPtr() { + return arrayPtr(ptr, pos); + } + inline ArrayPtr asPtr() const { + return arrayPtr(ptr, pos); + } + + inline size_t size() const { return pos - ptr; } + inline size_t capacity() const { return endPtr - ptr; } + inline T& operator[](size_t index) const { + KJ_IREQUIRE(index < implicitCast(pos - ptr), "Out-of-bounds Array access."); + return ptr[index]; + } + + inline const T* begin() const { return ptr; } + inline const T* end() const { return pos; } + inline const T& front() const { return *ptr; } + inline const T& back() const { return *(pos - 1); } + inline T* begin() { return ptr; } + inline T* end() { return pos; } + inline T& front() { return *ptr; } + inline T& back() { return *(pos - 1); } + + ArrayBuilder& operator=(ArrayBuilder&& other) { + dispose(); + ptr = other.ptr; + pos = other.pos; + endPtr = other.endPtr; + disposer = other.disposer; + other.ptr = nullptr; + other.pos = nullptr; + other.endPtr = nullptr; + return *this; + } + ArrayBuilder& operator=(decltype(nullptr)) { + dispose(); + return *this; + } + + template + T& add(Params&&... params) { + KJ_IREQUIRE(pos < endPtr, "Added too many elements to ArrayBuilder."); + ctor(*pos, kj::fwd(params)...); + return *pos++; + } + + template + void addAll(Container&& container) { + addAll()>( + container.begin(), container.end()); + } + + template + void addAll(Iterator start, Iterator end); + + void removeLast() { + KJ_IREQUIRE(pos > ptr, "No elements present to remove."); + kj::dtor(*--pos); + } + + void truncate(size_t size) { + KJ_IREQUIRE(size <= this->size(), "can't use truncate() to expand"); + + T* target = ptr + size; + if (__has_trivial_destructor(T)) { + pos = target; + } else { + while (pos > target) { + kj::dtor(*--pos); + } + } + } + + void resize(size_t size) { + KJ_IREQUIRE(size <= capacity(), "can't resize past capacity"); + + T* target = ptr + size; + if (target > pos) { + // expand + if (__has_trivial_constructor(T)) { + pos = target; + } else { + while (pos < target) { + kj::ctor(*pos++); + } + } + } else { + // truncate + if (__has_trivial_destructor(T)) { + pos = target; + } else { + while (pos > target) { + kj::dtor(*--pos); + } + } + } + } + + Array finish() { + // We could safely remove this check if we assume that the disposer implementation doesn't + // need to know the original capacity, as is thes case with HeapArrayDisposer since it uses + // operator new() or if we created a custom disposer for ArrayBuilder which stores the capacity + // in a prefix. But that would make it hard to write cleverer heap allocators, and anyway this + // check might catch bugs. Probably people should use Vector if they want to build arrays + // without knowing the final size in advance. + KJ_IREQUIRE(pos == endPtr, "ArrayBuilder::finish() called prematurely."); + Array result(reinterpret_cast(ptr), pos - ptr, *disposer); + ptr = nullptr; + pos = nullptr; + endPtr = nullptr; + return result; + } + + inline bool isFull() const { + return pos == endPtr; + } + +private: + T* ptr; + RemoveConst* pos; + T* endPtr; + const ArrayDisposer* disposer; + + inline void dispose() { + // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly + // dispose again. + T* ptrCopy = ptr; + T* posCopy = pos; + T* endCopy = endPtr; + if (ptrCopy != nullptr) { + ptr = nullptr; + pos = nullptr; + endPtr = nullptr; + disposer->dispose(ptrCopy, posCopy - ptrCopy, endCopy - ptrCopy); + } + } +}; + +template +inline ArrayBuilder heapArrayBuilder(size_t size) { + // Like `heapArray()` but does not default-construct the elements. You must construct them + // manually by calling `add()`. + + return ArrayBuilder(_::HeapArrayDisposer::allocateUninitialized>(size), + size, _::HeapArrayDisposer::instance); +} + +// ======================================================================================= +// Inline Arrays + +template +class FixedArray { + // A fixed-width array whose storage is allocated inline rather than on the heap. + +public: + inline size_t size() const { return fixedSize; } + inline T* begin() { return content; } + inline T* end() { return content + fixedSize; } + inline const T* begin() const { return content; } + inline const T* end() const { return content + fixedSize; } + + inline operator ArrayPtr() { + return arrayPtr(content, fixedSize); + } + inline operator ArrayPtr() const { + return arrayPtr(content, fixedSize); + } + + inline T& operator[](size_t index) { return content[index]; } + inline const T& operator[](size_t index) const { return content[index]; } + +private: + T content[fixedSize]; +}; + +template +class CappedArray { + // Like `FixedArray` but can be dynamically resized as long as the size does not exceed the limit + // specified by the template parameter. + // + // TODO(someday): Don't construct elements past currentSize? + +public: + inline KJ_CONSTEXPR() CappedArray(): currentSize(fixedSize) {} + inline explicit constexpr CappedArray(size_t s): currentSize(s) {} + + inline size_t size() const { return currentSize; } + inline void setSize(size_t s) { KJ_IREQUIRE(s <= fixedSize); currentSize = s; } + inline T* begin() { return content; } + inline T* end() { return content + currentSize; } + inline const T* begin() const { return content; } + inline const T* end() const { return content + currentSize; } + + inline operator ArrayPtr() { + return arrayPtr(content, currentSize); + } + inline operator ArrayPtr() const { + return arrayPtr(content, currentSize); + } + + inline T& operator[](size_t index) { return content[index]; } + inline const T& operator[](size_t index) const { return content[index]; } + +private: + size_t currentSize; + T content[fixedSize]; +}; + +// ======================================================================================= +// KJ_MAP + +#define KJ_MAP(elementName, array) \ + ::kj::_::Mapper(array) * \ + [&](typename ::kj::_::Mapper::Element elementName) +// Applies some function to every element of an array, returning an Array of the results, with +// nice syntax. Example: +// +// StringPtr foo = "abcd"; +// Array bar = KJ_MAP(c, foo) -> char { return c + 1; }; +// KJ_ASSERT(str(bar) == "bcde"); + +namespace _ { // private + +template +struct Mapper { + T array; + Mapper(T&& array): array(kj::fwd(array)) {} + template + auto operator*(Func&& func) -> Array { + auto builder = heapArrayBuilder(array.size()); + for (auto iter = array.begin(); iter != array.end(); ++iter) { + builder.add(func(*iter)); + } + return builder.finish(); + } + typedef decltype(*kj::instance().begin()) Element; +}; + +template +struct Mapper { + T* array; + Mapper(T* array): array(array) {} + template + auto operator*(Func&& func) -> Array { + auto builder = heapArrayBuilder(s); + for (size_t i = 0; i < s; i++) { + builder.add(func(array[i])); + } + return builder.finish(); + } + typedef decltype(*array)& Element; +}; + +} // namespace _ (private) + +// ======================================================================================= +// Inline implementation details + +template +struct ArrayDisposer::Dispose_ { + static void dispose(T* firstElement, size_t elementCount, size_t capacity, + const ArrayDisposer& disposer) { + disposer.disposeImpl(const_cast*>(firstElement), + sizeof(T), elementCount, capacity, nullptr); + } +}; +template +struct ArrayDisposer::Dispose_ { + static void destruct(void* ptr) { + kj::dtor(*reinterpret_cast(ptr)); + } + + static void dispose(T* firstElement, size_t elementCount, size_t capacity, + const ArrayDisposer& disposer) { + disposer.disposeImpl(firstElement, sizeof(T), elementCount, capacity, &destruct); + } +}; + +template +void ArrayDisposer::dispose(T* firstElement, size_t elementCount, size_t capacity) const { + Dispose_::dispose(firstElement, elementCount, capacity, *this); +} + +namespace _ { // private + +template +struct HeapArrayDisposer::Allocate_ { + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast(allocateImpl( + sizeof(T), elementCount, capacity, nullptr, nullptr)); + } +}; +template +struct HeapArrayDisposer::Allocate_ { + static void construct(void* ptr) { + kj::ctor(*reinterpret_cast(ptr)); + } + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast(allocateImpl( + sizeof(T), elementCount, capacity, &construct, nullptr)); + } +}; +template +struct HeapArrayDisposer::Allocate_ { + static void construct(void* ptr) { + kj::ctor(*reinterpret_cast(ptr)); + } + static void destruct(void* ptr) { + kj::dtor(*reinterpret_cast(ptr)); + } + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast(allocateImpl( + sizeof(T), elementCount, capacity, &construct, &destruct)); + } +}; + +template +T* HeapArrayDisposer::allocate(size_t count) { + return Allocate_::allocate(count, count); +} + +template +T* HeapArrayDisposer::allocateUninitialized(size_t count) { + return Allocate_::allocate(0, count); +} + +template ()> +struct CopyConstructArray_; + +template +struct CopyConstructArray_ { + static inline T* apply(T* __restrict__ pos, T* start, T* end) { + memcpy(pos, start, reinterpret_cast(end) - reinterpret_cast(start)); + return pos + (end - start); + } +}; + +template +struct CopyConstructArray_ { + static inline T* apply(T* __restrict__ pos, const T* start, const T* end) { + memcpy(pos, start, reinterpret_cast(end) - reinterpret_cast(start)); + return pos + (end - start); + } +}; + +template +struct CopyConstructArray_ { + static inline T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Since both the copy constructor and assignment operator are trivial, we know that assignment + // is equivalent to copy-constructing. So we can make this case somewhat easier for the + // compiler to optimize. + while (start != end) { + *pos++ = *start++; + } + return pos; + } +}; + +template +struct CopyConstructArray_ { + struct ExceptionGuard { + T* start; + T* pos; + inline explicit ExceptionGuard(T* pos): start(pos), pos(pos) {} + ~ExceptionGuard() noexcept(false) { + while (pos > start) { + dtor(*--pos); + } + } + }; + + static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Verify that T can be *implicitly* constructed from the source values. + if (false) implicitCast(*start); + + if (noexcept(T(*start))) { + while (start != end) { + ctor(*pos++, *start++); + } + return pos; + } else { + // Crap. This is complicated. + ExceptionGuard guard(pos); + while (start != end) { + ctor(*guard.pos, *start++); + ++guard.pos; + } + guard.start = guard.pos; + return guard.pos; + } + } +}; + +template +struct CopyConstructArray_ { + // Actually move-construct. + + struct ExceptionGuard { + T* start; + T* pos; + inline explicit ExceptionGuard(T* pos): start(pos), pos(pos) {} + ~ExceptionGuard() noexcept(false) { + while (pos > start) { + dtor(*--pos); + } + } + }; + + static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Verify that T can be *implicitly* constructed from the source values. + if (false) implicitCast(kj::mv(*start)); + + if (noexcept(T(kj::mv(*start)))) { + while (start != end) { + ctor(*pos++, kj::mv(*start++)); + } + return pos; + } else { + // Crap. This is complicated. + ExceptionGuard guard(pos); + while (start != end) { + ctor(*guard.pos, kj::mv(*start++)); + ++guard.pos; + } + guard.start = guard.pos; + return guard.pos; + } + } +}; + +} // namespace _ (private) + +template +template +void ArrayBuilder::addAll(Iterator start, Iterator end) { + pos = _::CopyConstructArray_, Decay, move>::apply(pos, start, end); +} + +template +Array heapArray(const T* content, size_t size) { + ArrayBuilder builder = heapArrayBuilder(size); + builder.addAll(content, content + size); + return builder.finish(); +} + +template +Array heapArray(T* content, size_t size) { + ArrayBuilder builder = heapArrayBuilder(size); + builder.addAll(content, content + size); + return builder.finish(); +} + +template +Array heapArray(ArrayPtr content) { + ArrayBuilder builder = heapArrayBuilder(content.size()); + builder.addAll(content); + return builder.finish(); +} + +template +Array heapArray(ArrayPtr content) { + ArrayBuilder builder = heapArrayBuilder(content.size()); + builder.addAll(content); + return builder.finish(); +} + +template Array +heapArray(Iterator begin, Iterator end) { + ArrayBuilder builder = heapArrayBuilder(end - begin); + builder.addAll(begin, end); + return builder.finish(); +} + +template +inline Array heapArray(std::initializer_list init) { + return heapArray(init.begin(), init.end()); +} + +} // namespace kj + +#endif // KJ_ARRAY_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/async-inl.h --- a/win32-mingw/include/kj/async-inl.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/async-inl.h Tue May 23 09:16:54 2017 +0100 @@ -1,1085 +1,1112 @@ -// 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 extended inline implementation details that are required along with async.h. -// We move this all into a separate file to make async.h more readable. -// -// Non-inline declarations here are defined in async.c++. - -#ifndef KJ_ASYNC_H_ -#error "Do not include this directly; include kj/async.h." -#include "async.h" // help IDE parse this file -#endif - -#ifndef KJ_ASYNC_INL_H_ -#define KJ_ASYNC_INL_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -namespace kj { -namespace _ { // private - -template -class ExceptionOr; - -class ExceptionOrValue { -public: - ExceptionOrValue(bool, Exception&& exception): exception(kj::mv(exception)) {} - KJ_DISALLOW_COPY(ExceptionOrValue); - - void addException(Exception&& exception) { - if (this->exception == nullptr) { - this->exception = kj::mv(exception); - } - } - - template - ExceptionOr& as() { return *static_cast*>(this); } - template - const ExceptionOr& as() const { return *static_cast*>(this); } - - Maybe exception; - -protected: - // Allow subclasses to have move constructor / assignment. - ExceptionOrValue() = default; - ExceptionOrValue(ExceptionOrValue&& other) = default; - ExceptionOrValue& operator=(ExceptionOrValue&& other) = default; -}; - -template -class ExceptionOr: public ExceptionOrValue { -public: - ExceptionOr() = default; - ExceptionOr(T&& value): value(kj::mv(value)) {} - ExceptionOr(bool, Exception&& exception): ExceptionOrValue(false, kj::mv(exception)) {} - ExceptionOr(ExceptionOr&&) = default; - ExceptionOr& operator=(ExceptionOr&&) = default; - - Maybe value; -}; - -class Event { - // An event waiting to be executed. Not for direct use by applications -- promises use this - // internally. - -public: - Event(); - ~Event() noexcept(false); - KJ_DISALLOW_COPY(Event); - - void armDepthFirst(); - // Enqueue this event so that `fire()` will be called from the event loop soon. - // - // Events scheduled in this way are executed in depth-first order: if an event callback arms - // more events, those events are placed at the front of the queue (in the order in which they - // were armed), so that they run immediately after the first event's callback returns. - // - // Depth-first event scheduling is appropriate for events that represent simple continuations - // of a previous event that should be globbed together for performance. Depth-first scheduling - // can lead to starvation, so any long-running task must occasionally yield with - // `armBreadthFirst()`. (Promise::then() uses depth-first whereas evalLater() uses - // breadth-first.) - // - // To use breadth-first scheduling instead, use `armBreadthFirst()`. - - void armBreadthFirst(); - // Like `armDepthFirst()` except that the event is placed at the end of the queue. - - kj::String trace(); - // Dump debug info about this event. - - virtual _::PromiseNode* getInnerForTrace(); - // If this event wraps a PromiseNode, get that node. Used for debug tracing. - // Default implementation returns nullptr. - -protected: - virtual Maybe> fire() = 0; - // Fire the event. Possibly returns a pointer to itself, which will be discarded by the - // caller. This is the only way that an event can delete itself as a result of firing, as - // doing so from within fire() will throw an exception. - -private: - friend class kj::EventLoop; - EventLoop& loop; - Event* next; - Event** prev; - bool firing = false; -}; - -class PromiseNode { - // A Promise contains a chain of PromiseNodes tracking the pending transformations. - // - // To reduce generated code bloat, PromiseNode is not a template. Instead, it makes very hacky - // use of pointers to ExceptionOrValue which actually point to ExceptionOr, but are only - // so down-cast in the few places that really need to be templated. Luckily this is all - // internal implementation details. - -public: - virtual void onReady(Event& event) noexcept = 0; - // Arms the given event when ready. - - virtual void setSelfPointer(Own* selfPtr) noexcept; - // Tells the node that `selfPtr` is the pointer that owns this node, and will continue to own - // this node until it is destroyed or setSelfPointer() is called again. ChainPromiseNode uses - // this to shorten redundant chains. The default implementation does nothing; only - // ChainPromiseNode should implement this. - - virtual void get(ExceptionOrValue& output) noexcept = 0; - // Get the result. `output` points to an ExceptionOr into which the result will be written. - // Can only be called once, and only after the node is ready. Must be called directly from the - // event loop, with no application code on the stack. - - virtual PromiseNode* getInnerForTrace(); - // If this node wraps some other PromiseNode, get the wrapped node. Used for debug tracing. - // Default implementation returns nullptr. - -protected: - class OnReadyEvent { - // Helper class for implementing onReady(). - - public: - void init(Event& newEvent); - // Returns true if arm() was already called. - - void arm(); - // Arms the event if init() has already been called and makes future calls to init() return - // true. - - private: - Event* event = nullptr; - }; -}; - -// ------------------------------------------------------------------- - -class ImmediatePromiseNodeBase: public PromiseNode { -public: - ImmediatePromiseNodeBase(); - ~ImmediatePromiseNodeBase() noexcept(false); - - void onReady(Event& event) noexcept override; -}; - -template -class ImmediatePromiseNode final: public ImmediatePromiseNodeBase { - // A promise that has already been resolved to an immediate value or exception. - -public: - ImmediatePromiseNode(ExceptionOr&& result): result(kj::mv(result)) {} - - void get(ExceptionOrValue& output) noexcept override { - output.as() = kj::mv(result); - } - -private: - ExceptionOr result; -}; - -class ImmediateBrokenPromiseNode final: public ImmediatePromiseNodeBase { -public: - ImmediateBrokenPromiseNode(Exception&& exception); - - void get(ExceptionOrValue& output) noexcept override; - -private: - Exception exception; -}; - -// ------------------------------------------------------------------- - -class AttachmentPromiseNodeBase: public PromiseNode { -public: - AttachmentPromiseNodeBase(Own&& dependency); - - void onReady(Event& event) noexcept override; - void get(ExceptionOrValue& output) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - Own dependency; - - void dropDependency(); - - template - friend class AttachmentPromiseNode; -}; - -template -class AttachmentPromiseNode final: public AttachmentPromiseNodeBase { - // A PromiseNode that holds on to some object (usually, an Own, but could be any movable - // object) until the promise resolves. - -public: - AttachmentPromiseNode(Own&& dependency, Attachment&& attachment) - : AttachmentPromiseNodeBase(kj::mv(dependency)), - attachment(kj::mv(attachment)) {} - - ~AttachmentPromiseNode() noexcept(false) { - // We need to make sure the dependency is deleted before we delete the attachment because the - // dependency may be using the attachment. - dropDependency(); - } - -private: - Attachment attachment; -}; - -// ------------------------------------------------------------------- - -class PtmfHelper { - // This class is a private helper for GetFunctorStartAddress. The class represents the internal - // representation of a pointer-to-member-function. - - template - friend struct GetFunctorStartAddress; - -#if __GNUG__ - void* ptr; - ptrdiff_t adj; - // Layout of a pointer-to-member-function used by GCC and compatible compilers. -#else -#error "TODO(port): PTMF instruction address extraction" -#endif - -#define BODY \ - PtmfHelper result; \ - static_assert(sizeof(p) == sizeof(result), "unknown ptmf layout"); \ - memcpy(&result, &p, sizeof(result)); \ - return result - - template - static PtmfHelper from(F p) { BODY; } - // Create a PtmfHelper from some arbitrary pointer-to-member-function which is not - // overloaded nor a template. In this case the compiler is able to deduce the full function - // signature directly given the name since there is only one function with that name. - - template - static PtmfHelper from(R (C::*p)(NoInfer

...)) { BODY; } - template - static PtmfHelper from(R (C::*p)(NoInfer

...) const) { BODY; } - // Create a PtmfHelper from some poniter-to-member-function which is a template. In this case - // the function must match exactly the containing type C, return type R, and parameter types P... - // GetFunctorStartAddress normally specifies exactly the correct C and R, but can only make a - // guess at P. Luckily, if the function parameters are template parameters then it's not - // necessary to be precise about P. -#undef BODY - - void* apply(void* obj) { -#if defined(__arm__) || defined(__mips__) || defined(__aarch64__) - if (adj & 1) { - ptrdiff_t voff = (ptrdiff_t)ptr; -#else - ptrdiff_t voff = (ptrdiff_t)ptr; - if (voff & 1) { - voff &= ~1; -#endif - return *(void**)(*(char**)obj + voff); - } else { - return ptr; - } - } -}; - -template -struct GetFunctorStartAddress { - // Given a functor (any object defining operator()), return the start address of the function, - // suitable for passing to addr2line to obtain a source file/line for debugging purposes. - // - // This turns out to be incredibly hard to implement in the presence of overloaded or templated - // functors. Therefore, we impose these specific restrictions, specific to our use case: - // - Overloading is not allowed, but templating is. (Generally we only intend to support lambdas - // anyway.) - // - The template parameters to GetFunctorStartAddress specify a hint as to the expected - // parameter types. If the functor is templated, its parameters must match exactly these types. - // (If it's not templated, ParamTypes are ignored.) - - template - static void* apply(Func&& func) { - typedef decltype(func(instance()...)) ReturnType; - return PtmfHelper::from, ParamTypes...>( - &Decay::operator()).apply(&func); - } -}; - -template <> -struct GetFunctorStartAddress: public GetFunctorStartAddress<> {}; -// Hack for TransformPromiseNode use case: an input type of `Void` indicates that the function -// actually has no parameters. - -class TransformPromiseNodeBase: public PromiseNode { -public: - TransformPromiseNodeBase(Own&& dependency, void* continuationTracePtr); - - void onReady(Event& event) noexcept override; - void get(ExceptionOrValue& output) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - Own dependency; - void* continuationTracePtr; - - void dropDependency(); - void getDepResult(ExceptionOrValue& output); - - virtual void getImpl(ExceptionOrValue& output) = 0; - - template - friend class TransformPromiseNode; -}; - -template -class TransformPromiseNode final: public TransformPromiseNodeBase { - // A PromiseNode that transforms the result of another PromiseNode through an application-provided - // function (implements `then()`). - -public: - TransformPromiseNode(Own&& dependency, Func&& func, ErrorFunc&& errorHandler) - : TransformPromiseNodeBase(kj::mv(dependency), - GetFunctorStartAddress::apply(func)), - func(kj::fwd(func)), errorHandler(kj::fwd(errorHandler)) {} - - ~TransformPromiseNode() noexcept(false) { - // We need to make sure the dependency is deleted before we delete the continuations because it - // is a common pattern for the continuations to hold ownership of objects that might be in-use - // by the dependency. - dropDependency(); - } - -private: - Func func; - ErrorFunc errorHandler; - - void getImpl(ExceptionOrValue& output) override { - ExceptionOr depResult; - getDepResult(depResult); - KJ_IF_MAYBE(depException, depResult.exception) { - output.as() = handle( - MaybeVoidCaller>>::apply( - errorHandler, kj::mv(*depException))); - } else KJ_IF_MAYBE(depValue, depResult.value) { - output.as() = handle(MaybeVoidCaller::apply(func, kj::mv(*depValue))); - } - } - - ExceptionOr handle(T&& value) { - return kj::mv(value); - } - ExceptionOr handle(PropagateException::Bottom&& value) { - return ExceptionOr(false, value.asException()); - } -}; - -// ------------------------------------------------------------------- - -class ForkHubBase; - -class ForkBranchBase: public PromiseNode { -public: - ForkBranchBase(Own&& hub); - ~ForkBranchBase() noexcept(false); - - void hubReady() noexcept; - // Called by the hub to indicate that it is ready. - - // implements PromiseNode ------------------------------------------ - void onReady(Event& event) noexcept override; - PromiseNode* getInnerForTrace() override; - -protected: - inline ExceptionOrValue& getHubResultRef(); - - void releaseHub(ExceptionOrValue& output); - // Release the hub. If an exception is thrown, add it to `output`. - -private: - OnReadyEvent onReadyEvent; - - Own hub; - ForkBranchBase* next = nullptr; - ForkBranchBase** prevPtr = nullptr; - - friend class ForkHubBase; -}; - -template T copyOrAddRef(T& t) { return t; } -template Own copyOrAddRef(Own& t) { return t->addRef(); } - -template -class ForkBranch final: public ForkBranchBase { - // A PromiseNode that implements one branch of a fork -- i.e. one of the branches that receives - // a const reference. - -public: - ForkBranch(Own&& hub): ForkBranchBase(kj::mv(hub)) {} - - void get(ExceptionOrValue& output) noexcept override { - ExceptionOr& hubResult = getHubResultRef().template as(); - KJ_IF_MAYBE(value, hubResult.value) { - output.as().value = copyOrAddRef(*value); - } else { - output.as().value = nullptr; - } - output.exception = hubResult.exception; - releaseHub(output); - } -}; - -template -class SplitBranch final: public ForkBranchBase { - // A PromiseNode that implements one branch of a fork -- i.e. one of the branches that receives - // a const reference. - -public: - SplitBranch(Own&& hub): ForkBranchBase(kj::mv(hub)) {} - - typedef kj::Decay(kj::instance()))> Element; - - void get(ExceptionOrValue& output) noexcept override { - ExceptionOr& hubResult = getHubResultRef().template as(); - KJ_IF_MAYBE(value, hubResult.value) { - output.as().value = kj::mv(kj::get(*value)); - } else { - output.as().value = nullptr; - } - output.exception = hubResult.exception; - releaseHub(output); - } -}; - -// ------------------------------------------------------------------- - -class ForkHubBase: public Refcounted, protected Event { -public: - ForkHubBase(Own&& inner, ExceptionOrValue& resultRef); - - inline ExceptionOrValue& getResultRef() { return resultRef; } - -private: - Own inner; - ExceptionOrValue& resultRef; - - ForkBranchBase* headBranch = nullptr; - ForkBranchBase** tailBranch = &headBranch; - // Tail becomes null once the inner promise is ready and all branches have been notified. - - Maybe> fire() override; - _::PromiseNode* getInnerForTrace() override; - - friend class ForkBranchBase; -}; - -template -class ForkHub final: public ForkHubBase { - // A PromiseNode that implements the hub of a fork. The first call to Promise::fork() replaces - // the promise's outer node with a ForkHub, and subsequent calls add branches to that hub (if - // possible). - -public: - ForkHub(Own&& inner): ForkHubBase(kj::mv(inner), result) {} - - Promise<_::UnfixVoid> addBranch() { - return Promise<_::UnfixVoid>(false, kj::heap>(addRef(*this))); - } - - _::SplitTuplePromise split() { - return splitImpl(MakeIndexes()>()); - } - -private: - ExceptionOr result; - - template - _::SplitTuplePromise splitImpl(Indexes) { - return kj::tuple(addSplit()...); - } - - template - Promise::Element>> addSplit() { - return Promise::Element>>( - false, maybeChain(kj::heap>(addRef(*this)), - implicitCast::Element*>(nullptr))); - } -}; - -inline ExceptionOrValue& ForkBranchBase::getHubResultRef() { - return hub->getResultRef(); -} - -// ------------------------------------------------------------------- - -class ChainPromiseNode final: public PromiseNode, public Event { - // Promise node which reduces Promise> to Promise. - // - // `Event` is only a public base class because otherwise we can't cast Own to - // Own. Ugh, templates and private... - -public: - explicit ChainPromiseNode(Own inner); - ~ChainPromiseNode() noexcept(false); - - void onReady(Event& event) noexcept override; - void setSelfPointer(Own* selfPtr) noexcept override; - void get(ExceptionOrValue& output) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - enum State { - STEP1, - STEP2 - }; - - State state; - - Own inner; - // In STEP1, a PromiseNode for a Promise. - // In STEP2, a PromiseNode for a T. - - Event* onReadyEvent = nullptr; - Own* selfPtr = nullptr; - - Maybe> fire() override; -}; - -template -Own maybeChain(Own&& node, Promise*) { - return heap(kj::mv(node)); -} - -template -Own&& maybeChain(Own&& node, T*) { - return kj::mv(node); -} - -// ------------------------------------------------------------------- - -class ExclusiveJoinPromiseNode final: public PromiseNode { -public: - ExclusiveJoinPromiseNode(Own left, Own right); - ~ExclusiveJoinPromiseNode() noexcept(false); - - void onReady(Event& event) noexcept override; - void get(ExceptionOrValue& output) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - class Branch: public Event { - public: - Branch(ExclusiveJoinPromiseNode& joinNode, Own dependency); - ~Branch() noexcept(false); - - bool get(ExceptionOrValue& output); - // Returns true if this is the side that finished. - - Maybe> fire() override; - _::PromiseNode* getInnerForTrace() override; - - private: - ExclusiveJoinPromiseNode& joinNode; - Own dependency; - }; - - Branch left; - Branch right; - OnReadyEvent onReadyEvent; -}; - -// ------------------------------------------------------------------- - -class ArrayJoinPromiseNodeBase: public PromiseNode { -public: - ArrayJoinPromiseNodeBase(Array> promises, - ExceptionOrValue* resultParts, size_t partSize); - ~ArrayJoinPromiseNodeBase() noexcept(false); - - void onReady(Event& event) noexcept override final; - void get(ExceptionOrValue& output) noexcept override final; - PromiseNode* getInnerForTrace() override final; - -protected: - virtual void getNoError(ExceptionOrValue& output) noexcept = 0; - // Called to compile the result only in the case where there were no errors. - -private: - uint countLeft; - OnReadyEvent onReadyEvent; - - class Branch final: public Event { - public: - Branch(ArrayJoinPromiseNodeBase& joinNode, Own dependency, - ExceptionOrValue& output); - ~Branch() noexcept(false); - - Maybe> fire() override; - _::PromiseNode* getInnerForTrace() override; - - Maybe getPart(); - // Calls dependency->get(output). If there was an exception, return it. - - private: - ArrayJoinPromiseNodeBase& joinNode; - Own dependency; - ExceptionOrValue& output; - }; - - Array branches; -}; - -template -class ArrayJoinPromiseNode final: public ArrayJoinPromiseNodeBase { -public: - ArrayJoinPromiseNode(Array> promises, - Array> resultParts) - : ArrayJoinPromiseNodeBase(kj::mv(promises), resultParts.begin(), sizeof(ExceptionOr)), - resultParts(kj::mv(resultParts)) {} - -protected: - void getNoError(ExceptionOrValue& output) noexcept override { - auto builder = heapArrayBuilder(resultParts.size()); - for (auto& part: resultParts) { - KJ_IASSERT(part.value != nullptr, - "Bug in KJ promise framework: Promise result had neither value no exception."); - builder.add(kj::mv(*_::readMaybe(part.value))); - } - output.as>() = builder.finish(); - } - -private: - Array> resultParts; -}; - -template <> -class ArrayJoinPromiseNode final: public ArrayJoinPromiseNodeBase { -public: - ArrayJoinPromiseNode(Array> promises, - Array> resultParts); - ~ArrayJoinPromiseNode(); - -protected: - void getNoError(ExceptionOrValue& output) noexcept override; - -private: - Array> resultParts; -}; - -// ------------------------------------------------------------------- - -class EagerPromiseNodeBase: public PromiseNode, protected Event { - // A PromiseNode that eagerly evaluates its dependency even if its dependent does not eagerly - // evaluate it. - -public: - EagerPromiseNodeBase(Own&& dependency, ExceptionOrValue& resultRef); - - void onReady(Event& event) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - Own dependency; - OnReadyEvent onReadyEvent; - - ExceptionOrValue& resultRef; - - Maybe> fire() override; -}; - -template -class EagerPromiseNode final: public EagerPromiseNodeBase { -public: - EagerPromiseNode(Own&& dependency) - : EagerPromiseNodeBase(kj::mv(dependency), result) {} - - void get(ExceptionOrValue& output) noexcept override { - output.as() = kj::mv(result); - } - -private: - ExceptionOr result; -}; - -template -Own spark(Own&& node) { - // Forces evaluation of the given node to begin as soon as possible, even if no one is waiting - // on it. - return heap>(kj::mv(node)); -} - -// ------------------------------------------------------------------- - -class AdapterPromiseNodeBase: public PromiseNode { -public: - void onReady(Event& event) noexcept override; - -protected: - inline void setReady() { - onReadyEvent.arm(); - } - -private: - OnReadyEvent onReadyEvent; -}; - -template -class AdapterPromiseNode final: public AdapterPromiseNodeBase, - private PromiseFulfiller> { - // A PromiseNode that wraps a PromiseAdapter. - -public: - template - AdapterPromiseNode(Params&&... params) - : adapter(static_cast>&>(*this), kj::fwd(params)...) {} - - void get(ExceptionOrValue& output) noexcept override { - KJ_IREQUIRE(!isWaiting()); - output.as() = kj::mv(result); - } - -private: - ExceptionOr result; - bool waiting = true; - Adapter adapter; - - void fulfill(T&& value) override { - if (waiting) { - waiting = false; - result = ExceptionOr(kj::mv(value)); - setReady(); - } - } - - void reject(Exception&& exception) override { - if (waiting) { - waiting = false; - result = ExceptionOr(false, kj::mv(exception)); - setReady(); - } - } - - bool isWaiting() override { - return waiting; - } -}; - -} // namespace _ (private) - -// ======================================================================================= - -template -Promise::Promise(_::FixVoid value) - : PromiseBase(heap<_::ImmediatePromiseNode<_::FixVoid>>(kj::mv(value))) {} - -template -Promise::Promise(kj::Exception&& exception) - : PromiseBase(heap<_::ImmediateBrokenPromiseNode>(kj::mv(exception))) {} - -template -template -PromiseForResult Promise::then(Func&& func, ErrorFunc&& errorHandler) { - typedef _::FixVoid<_::ReturnType> ResultT; - - Own<_::PromiseNode> intermediate = - heap<_::TransformPromiseNode, Func, ErrorFunc>>( - kj::mv(node), kj::fwd(func), kj::fwd(errorHandler)); - return PromiseForResult(false, - _::maybeChain(kj::mv(intermediate), implicitCast(nullptr))); -} - -namespace _ { // private - -template -struct IdentityFunc { - inline T operator()(T&& value) const { - return kj::mv(value); - } -}; -template -struct IdentityFunc> { - inline Promise operator()(T&& value) const { - return kj::mv(value); - } -}; -template <> -struct IdentityFunc { - inline void operator()() const {} -}; -template <> -struct IdentityFunc> { - Promise operator()() const; - // This can't be inline because it will make the translation unit depend on kj-async. Awkwardly, - // Cap'n Proto relies on being able to include this header without creating such a link-time - // dependency. -}; - -} // namespace _ (private) - -template -template -Promise Promise::catch_(ErrorFunc&& errorHandler) { - // then()'s ErrorFunc can only return a Promise if Func also returns a Promise. In this case, - // Func is being filled in automatically. We want to make sure ErrorFunc can return a Promise, - // but we don't want the extra overhead of promise chaining if ErrorFunc doesn't actually - // return a promise. So we make our Func return match ErrorFunc. - return then(_::IdentityFunc()))>(), - kj::fwd(errorHandler)); -} - -template -T Promise::wait(WaitScope& waitScope) { - _::ExceptionOr<_::FixVoid> result; - - waitImpl(kj::mv(node), result, waitScope); - - KJ_IF_MAYBE(value, result.value) { - KJ_IF_MAYBE(exception, result.exception) { - throwRecoverableException(kj::mv(*exception)); - } - return _::returnMaybeVoid(kj::mv(*value)); - } else KJ_IF_MAYBE(exception, result.exception) { - throwFatalException(kj::mv(*exception)); - } else { - // Result contained neither a value nor an exception? - KJ_UNREACHABLE; - } -} - -template -ForkedPromise Promise::fork() { - return ForkedPromise(false, refcounted<_::ForkHub<_::FixVoid>>(kj::mv(node))); -} - -template -Promise ForkedPromise::addBranch() { - return hub->addBranch(); -} - -template -_::SplitTuplePromise Promise::split() { - return refcounted<_::ForkHub<_::FixVoid>>(kj::mv(node))->split(); -} - -template -Promise Promise::exclusiveJoin(Promise&& other) { - return Promise(false, heap<_::ExclusiveJoinPromiseNode>(kj::mv(node), kj::mv(other.node))); -} - -template -template -Promise Promise::attach(Attachments&&... attachments) { - return Promise(false, kj::heap<_::AttachmentPromiseNode>>( - kj::mv(node), kj::tuple(kj::fwd(attachments)...))); -} - -template -template -Promise Promise::eagerlyEvaluate(ErrorFunc&& errorHandler) { - // See catch_() for commentary. - return Promise(false, _::spark<_::FixVoid>(then( - _::IdentityFunc()))>(), - kj::fwd(errorHandler)).node)); -} - -template -Promise Promise::eagerlyEvaluate(decltype(nullptr)) { - return Promise(false, _::spark<_::FixVoid>(kj::mv(node))); -} - -template -kj::String Promise::trace() { - return PromiseBase::trace(); -} - -template -inline PromiseForResult evalLater(Func&& func) { - return _::yield().then(kj::fwd(func), _::PropagateException()); -} - -template -inline PromiseForResult evalNow(Func&& func) { - PromiseForResult result = nullptr; - KJ_IF_MAYBE(e, kj::runCatchingExceptions([&]() { - result = func(); - })) { - result = kj::mv(*e); - } - return result; -} - -template -template -void Promise::detach(ErrorFunc&& errorHandler) { - return _::detach(then([](T&&) {}, kj::fwd(errorHandler))); -} - -template <> -template -void Promise::detach(ErrorFunc&& errorHandler) { - return _::detach(then([]() {}, kj::fwd(errorHandler))); -} - -template -Promise> joinPromises(Array>&& promises) { - return Promise>(false, kj::heap<_::ArrayJoinPromiseNode>( - KJ_MAP(p, promises) { return kj::mv(p.node); }, - heapArray<_::ExceptionOr>(promises.size()))); -} - -// ======================================================================================= - -namespace _ { // private - -template -class WeakFulfiller final: public PromiseFulfiller, private kj::Disposer { - // A wrapper around PromiseFulfiller which can be detached. - // - // There are a couple non-trivialities here: - // - If the WeakFulfiller is discarded, we want the promise it fulfills to be implicitly - // rejected. - // - We cannot destroy the WeakFulfiller until the application has discarded it *and* it has been - // detached from the underlying fulfiller, because otherwise the later detach() call will go - // to a dangling pointer. Essentially, WeakFulfiller is reference counted, although the - // refcount never goes over 2 and we manually implement the refcounting because we need to do - // other special things when each side detaches anyway. To this end, WeakFulfiller is its own - // Disposer -- dispose() is called when the application discards its owned pointer to the - // fulfiller and detach() is called when the promise is destroyed. - -public: - KJ_DISALLOW_COPY(WeakFulfiller); - - static kj::Own make() { - WeakFulfiller* ptr = new WeakFulfiller; - return Own(ptr, *ptr); - } - - void fulfill(FixVoid&& value) override { - if (inner != nullptr) { - inner->fulfill(kj::mv(value)); - } - } - - void reject(Exception&& exception) override { - if (inner != nullptr) { - inner->reject(kj::mv(exception)); - } - } - - bool isWaiting() override { - return inner != nullptr && inner->isWaiting(); - } - - void attach(PromiseFulfiller& newInner) { - inner = &newInner; - } - - void detach(PromiseFulfiller& from) { - if (inner == nullptr) { - // Already disposed. - delete this; - } else { - KJ_IREQUIRE(inner == &from); - inner = nullptr; - } - } - -private: - mutable PromiseFulfiller* inner; - - WeakFulfiller(): inner(nullptr) {} - - void disposeImpl(void* pointer) const override { - // TODO(perf): Factor some of this out so it isn't regenerated for every fulfiller type? - - if (inner == nullptr) { - // Already detached. - delete this; - } else { - if (inner->isWaiting()) { - inner->reject(kj::Exception(kj::Exception::Type::FAILED, __FILE__, __LINE__, - kj::heapString("PromiseFulfiller was destroyed without fulfilling the promise."))); - } - inner = nullptr; - } - } -}; - -template -class PromiseAndFulfillerAdapter { -public: - PromiseAndFulfillerAdapter(PromiseFulfiller& fulfiller, - WeakFulfiller& wrapper) - : fulfiller(fulfiller), wrapper(wrapper) { - wrapper.attach(fulfiller); - } - - ~PromiseAndFulfillerAdapter() noexcept(false) { - wrapper.detach(fulfiller); - } - -private: - PromiseFulfiller& fulfiller; - WeakFulfiller& wrapper; -}; - -} // namespace _ (private) - -template -template -bool PromiseFulfiller::rejectIfThrows(Func&& func) { - KJ_IF_MAYBE(exception, kj::runCatchingExceptions(kj::mv(func))) { - reject(kj::mv(*exception)); - return false; - } else { - return true; - } -} - -template -bool PromiseFulfiller::rejectIfThrows(Func&& func) { - KJ_IF_MAYBE(exception, kj::runCatchingExceptions(kj::mv(func))) { - reject(kj::mv(*exception)); - return false; - } else { - return true; - } -} - -template -Promise newAdaptedPromise(Params&&... adapterConstructorParams) { - return Promise(false, heap<_::AdapterPromiseNode<_::FixVoid, Adapter>>( - kj::fwd(adapterConstructorParams)...)); -} - -template -PromiseFulfillerPair newPromiseAndFulfiller() { - auto wrapper = _::WeakFulfiller::make(); - - Own<_::PromiseNode> intermediate( - heap<_::AdapterPromiseNode<_::FixVoid, _::PromiseAndFulfillerAdapter>>(*wrapper)); - Promise<_::JoinPromises> promise(false, - _::maybeChain(kj::mv(intermediate), implicitCast(nullptr))); - - return PromiseFulfillerPair { kj::mv(promise), kj::mv(wrapper) }; -} - -} // namespace kj - -#endif // KJ_ASYNC_INL_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 extended inline implementation details that are required along with async.h. +// We move this all into a separate file to make async.h more readable. +// +// Non-inline declarations here are defined in async.c++. + +#ifndef KJ_ASYNC_H_ +#error "Do not include this directly; include kj/async.h." +#include "async.h" // help IDE parse this file +#endif + +#ifndef KJ_ASYNC_INL_H_ +#define KJ_ASYNC_INL_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +namespace kj { +namespace _ { // private + +template +class ExceptionOr; + +class ExceptionOrValue { +public: + ExceptionOrValue(bool, Exception&& exception): exception(kj::mv(exception)) {} + KJ_DISALLOW_COPY(ExceptionOrValue); + + void addException(Exception&& exception) { + if (this->exception == nullptr) { + this->exception = kj::mv(exception); + } + } + + template + ExceptionOr& as() { return *static_cast*>(this); } + template + const ExceptionOr& as() const { return *static_cast*>(this); } + + Maybe exception; + +protected: + // Allow subclasses to have move constructor / assignment. + ExceptionOrValue() = default; + ExceptionOrValue(ExceptionOrValue&& other) = default; + ExceptionOrValue& operator=(ExceptionOrValue&& other) = default; +}; + +template +class ExceptionOr: public ExceptionOrValue { +public: + ExceptionOr() = default; + ExceptionOr(T&& value): value(kj::mv(value)) {} + ExceptionOr(bool, Exception&& exception): ExceptionOrValue(false, kj::mv(exception)) {} + ExceptionOr(ExceptionOr&&) = default; + ExceptionOr& operator=(ExceptionOr&&) = default; + + Maybe value; +}; + +class Event { + // An event waiting to be executed. Not for direct use by applications -- promises use this + // internally. + +public: + Event(); + ~Event() noexcept(false); + KJ_DISALLOW_COPY(Event); + + void armDepthFirst(); + // Enqueue this event so that `fire()` will be called from the event loop soon. + // + // Events scheduled in this way are executed in depth-first order: if an event callback arms + // more events, those events are placed at the front of the queue (in the order in which they + // were armed), so that they run immediately after the first event's callback returns. + // + // Depth-first event scheduling is appropriate for events that represent simple continuations + // of a previous event that should be globbed together for performance. Depth-first scheduling + // can lead to starvation, so any long-running task must occasionally yield with + // `armBreadthFirst()`. (Promise::then() uses depth-first whereas evalLater() uses + // breadth-first.) + // + // To use breadth-first scheduling instead, use `armBreadthFirst()`. + + void armBreadthFirst(); + // Like `armDepthFirst()` except that the event is placed at the end of the queue. + + kj::String trace(); + // Dump debug info about this event. + + virtual _::PromiseNode* getInnerForTrace(); + // If this event wraps a PromiseNode, get that node. Used for debug tracing. + // Default implementation returns nullptr. + +protected: + virtual Maybe> fire() = 0; + // Fire the event. Possibly returns a pointer to itself, which will be discarded by the + // caller. This is the only way that an event can delete itself as a result of firing, as + // doing so from within fire() will throw an exception. + +private: + friend class kj::EventLoop; + EventLoop& loop; + Event* next; + Event** prev; + bool firing = false; +}; + +class PromiseNode { + // A Promise contains a chain of PromiseNodes tracking the pending transformations. + // + // To reduce generated code bloat, PromiseNode is not a template. Instead, it makes very hacky + // use of pointers to ExceptionOrValue which actually point to ExceptionOr, but are only + // so down-cast in the few places that really need to be templated. Luckily this is all + // internal implementation details. + +public: + virtual void onReady(Event& event) noexcept = 0; + // Arms the given event when ready. + + virtual void setSelfPointer(Own* selfPtr) noexcept; + // Tells the node that `selfPtr` is the pointer that owns this node, and will continue to own + // this node until it is destroyed or setSelfPointer() is called again. ChainPromiseNode uses + // this to shorten redundant chains. The default implementation does nothing; only + // ChainPromiseNode should implement this. + + virtual void get(ExceptionOrValue& output) noexcept = 0; + // Get the result. `output` points to an ExceptionOr into which the result will be written. + // Can only be called once, and only after the node is ready. Must be called directly from the + // event loop, with no application code on the stack. + + virtual PromiseNode* getInnerForTrace(); + // If this node wraps some other PromiseNode, get the wrapped node. Used for debug tracing. + // Default implementation returns nullptr. + +protected: + class OnReadyEvent { + // Helper class for implementing onReady(). + + public: + void init(Event& newEvent); + // Returns true if arm() was already called. + + void arm(); + // Arms the event if init() has already been called and makes future calls to init() return + // true. + + private: + Event* event = nullptr; + }; +}; + +// ------------------------------------------------------------------- + +class ImmediatePromiseNodeBase: public PromiseNode { +public: + ImmediatePromiseNodeBase(); + ~ImmediatePromiseNodeBase() noexcept(false); + + void onReady(Event& event) noexcept override; +}; + +template +class ImmediatePromiseNode final: public ImmediatePromiseNodeBase { + // A promise that has already been resolved to an immediate value or exception. + +public: + ImmediatePromiseNode(ExceptionOr&& result): result(kj::mv(result)) {} + + void get(ExceptionOrValue& output) noexcept override { + output.as() = kj::mv(result); + } + +private: + ExceptionOr result; +}; + +class ImmediateBrokenPromiseNode final: public ImmediatePromiseNodeBase { +public: + ImmediateBrokenPromiseNode(Exception&& exception); + + void get(ExceptionOrValue& output) noexcept override; + +private: + Exception exception; +}; + +// ------------------------------------------------------------------- + +class AttachmentPromiseNodeBase: public PromiseNode { +public: + AttachmentPromiseNodeBase(Own&& dependency); + + void onReady(Event& event) noexcept override; + void get(ExceptionOrValue& output) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + Own dependency; + + void dropDependency(); + + template + friend class AttachmentPromiseNode; +}; + +template +class AttachmentPromiseNode final: public AttachmentPromiseNodeBase { + // A PromiseNode that holds on to some object (usually, an Own, but could be any movable + // object) until the promise resolves. + +public: + AttachmentPromiseNode(Own&& dependency, Attachment&& attachment) + : AttachmentPromiseNodeBase(kj::mv(dependency)), + attachment(kj::mv(attachment)) {} + + ~AttachmentPromiseNode() noexcept(false) { + // We need to make sure the dependency is deleted before we delete the attachment because the + // dependency may be using the attachment. + dropDependency(); + } + +private: + Attachment attachment; +}; + +// ------------------------------------------------------------------- + +class PtmfHelper { + // This class is a private helper for GetFunctorStartAddress. The class represents the internal + // representation of a pointer-to-member-function. + + template + friend struct GetFunctorStartAddress; + +#if __GNUG__ + + void* ptr; + ptrdiff_t adj; + // Layout of a pointer-to-member-function used by GCC and compatible compilers. + + void* apply(void* obj) { +#if defined(__arm__) || defined(__mips__) || defined(__aarch64__) + if (adj & 1) { + ptrdiff_t voff = (ptrdiff_t)ptr; +#else + ptrdiff_t voff = (ptrdiff_t)ptr; + if (voff & 1) { + voff &= ~1; +#endif + return *(void**)(*(char**)obj + voff); + } else { + return ptr; + } + } + +#define BODY \ + PtmfHelper result; \ + static_assert(sizeof(p) == sizeof(result), "unknown ptmf layout"); \ + memcpy(&result, &p, sizeof(result)); \ + return result + +#else // __GNUG__ + + void* apply(void* obj) { return nullptr; } + // TODO(port): PTMF instruction address extraction + +#define BODY return PtmfHelper{} + +#endif // __GNUG__, else + + template + static PtmfHelper from(F p) { BODY; } + // Create a PtmfHelper from some arbitrary pointer-to-member-function which is not + // overloaded nor a template. In this case the compiler is able to deduce the full function + // signature directly given the name since there is only one function with that name. + + template + static PtmfHelper from(R (C::*p)(NoInfer

...)) { BODY; } + template + static PtmfHelper from(R (C::*p)(NoInfer

...) const) { BODY; } + // Create a PtmfHelper from some poniter-to-member-function which is a template. In this case + // the function must match exactly the containing type C, return type R, and parameter types P... + // GetFunctorStartAddress normally specifies exactly the correct C and R, but can only make a + // guess at P. Luckily, if the function parameters are template parameters then it's not + // necessary to be precise about P. +#undef BODY +}; + +template +struct GetFunctorStartAddress { + // Given a functor (any object defining operator()), return the start address of the function, + // suitable for passing to addr2line to obtain a source file/line for debugging purposes. + // + // This turns out to be incredibly hard to implement in the presence of overloaded or templated + // functors. Therefore, we impose these specific restrictions, specific to our use case: + // - Overloading is not allowed, but templating is. (Generally we only intend to support lambdas + // anyway.) + // - The template parameters to GetFunctorStartAddress specify a hint as to the expected + // parameter types. If the functor is templated, its parameters must match exactly these types. + // (If it's not templated, ParamTypes are ignored.) + + template + static void* apply(Func&& func) { + typedef decltype(func(instance()...)) ReturnType; + return PtmfHelper::from, ParamTypes...>( + &Decay::operator()).apply(&func); + } +}; + +template <> +struct GetFunctorStartAddress: public GetFunctorStartAddress<> {}; +// Hack for TransformPromiseNode use case: an input type of `Void` indicates that the function +// actually has no parameters. + +class TransformPromiseNodeBase: public PromiseNode { +public: + TransformPromiseNodeBase(Own&& dependency, void* continuationTracePtr); + + void onReady(Event& event) noexcept override; + void get(ExceptionOrValue& output) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + Own dependency; + void* continuationTracePtr; + + void dropDependency(); + void getDepResult(ExceptionOrValue& output); + + virtual void getImpl(ExceptionOrValue& output) = 0; + + template + friend class TransformPromiseNode; +}; + +template +class TransformPromiseNode final: public TransformPromiseNodeBase { + // A PromiseNode that transforms the result of another PromiseNode through an application-provided + // function (implements `then()`). + +public: + TransformPromiseNode(Own&& dependency, Func&& func, ErrorFunc&& errorHandler) + : TransformPromiseNodeBase(kj::mv(dependency), + GetFunctorStartAddress::apply(func)), + func(kj::fwd(func)), errorHandler(kj::fwd(errorHandler)) {} + + ~TransformPromiseNode() noexcept(false) { + // We need to make sure the dependency is deleted before we delete the continuations because it + // is a common pattern for the continuations to hold ownership of objects that might be in-use + // by the dependency. + dropDependency(); + } + +private: + Func func; + ErrorFunc errorHandler; + + void getImpl(ExceptionOrValue& output) override { + ExceptionOr depResult; + getDepResult(depResult); + KJ_IF_MAYBE(depException, depResult.exception) { + output.as() = handle( + MaybeVoidCaller>>::apply( + errorHandler, kj::mv(*depException))); + } else KJ_IF_MAYBE(depValue, depResult.value) { + output.as() = handle(MaybeVoidCaller::apply(func, kj::mv(*depValue))); + } + } + + ExceptionOr handle(T&& value) { + return kj::mv(value); + } + ExceptionOr handle(PropagateException::Bottom&& value) { + return ExceptionOr(false, value.asException()); + } +}; + +// ------------------------------------------------------------------- + +class ForkHubBase; + +class ForkBranchBase: public PromiseNode { +public: + ForkBranchBase(Own&& hub); + ~ForkBranchBase() noexcept(false); + + void hubReady() noexcept; + // Called by the hub to indicate that it is ready. + + // implements PromiseNode ------------------------------------------ + void onReady(Event& event) noexcept override; + PromiseNode* getInnerForTrace() override; + +protected: + inline ExceptionOrValue& getHubResultRef(); + + void releaseHub(ExceptionOrValue& output); + // Release the hub. If an exception is thrown, add it to `output`. + +private: + OnReadyEvent onReadyEvent; + + Own hub; + ForkBranchBase* next = nullptr; + ForkBranchBase** prevPtr = nullptr; + + friend class ForkHubBase; +}; + +template T copyOrAddRef(T& t) { return t; } +template Own copyOrAddRef(Own& t) { return t->addRef(); } + +template +class ForkBranch final: public ForkBranchBase { + // A PromiseNode that implements one branch of a fork -- i.e. one of the branches that receives + // a const reference. + +public: + ForkBranch(Own&& hub): ForkBranchBase(kj::mv(hub)) {} + + void get(ExceptionOrValue& output) noexcept override { + ExceptionOr& hubResult = getHubResultRef().template as(); + KJ_IF_MAYBE(value, hubResult.value) { + output.as().value = copyOrAddRef(*value); + } else { + output.as().value = nullptr; + } + output.exception = hubResult.exception; + releaseHub(output); + } +}; + +template +class SplitBranch final: public ForkBranchBase { + // A PromiseNode that implements one branch of a fork -- i.e. one of the branches that receives + // a const reference. + +public: + SplitBranch(Own&& hub): ForkBranchBase(kj::mv(hub)) {} + + typedef kj::Decay(kj::instance()))> Element; + + void get(ExceptionOrValue& output) noexcept override { + ExceptionOr& hubResult = getHubResultRef().template as(); + KJ_IF_MAYBE(value, hubResult.value) { + output.as().value = kj::mv(kj::get(*value)); + } else { + output.as().value = nullptr; + } + output.exception = hubResult.exception; + releaseHub(output); + } +}; + +// ------------------------------------------------------------------- + +class ForkHubBase: public Refcounted, protected Event { +public: + ForkHubBase(Own&& inner, ExceptionOrValue& resultRef); + + inline ExceptionOrValue& getResultRef() { return resultRef; } + +private: + Own inner; + ExceptionOrValue& resultRef; + + ForkBranchBase* headBranch = nullptr; + ForkBranchBase** tailBranch = &headBranch; + // Tail becomes null once the inner promise is ready and all branches have been notified. + + Maybe> fire() override; + _::PromiseNode* getInnerForTrace() override; + + friend class ForkBranchBase; +}; + +template +class ForkHub final: public ForkHubBase { + // A PromiseNode that implements the hub of a fork. The first call to Promise::fork() replaces + // the promise's outer node with a ForkHub, and subsequent calls add branches to that hub (if + // possible). + +public: + ForkHub(Own&& inner): ForkHubBase(kj::mv(inner), result) {} + + Promise<_::UnfixVoid> addBranch() { + return Promise<_::UnfixVoid>(false, kj::heap>(addRef(*this))); + } + + _::SplitTuplePromise split() { + return splitImpl(MakeIndexes()>()); + } + +private: + ExceptionOr result; + + template + _::SplitTuplePromise splitImpl(Indexes) { + return kj::tuple(addSplit()...); + } + + template + Promise::Element>> addSplit() { + return Promise::Element>>( + false, maybeChain(kj::heap>(addRef(*this)), + implicitCast::Element*>(nullptr))); + } +}; + +inline ExceptionOrValue& ForkBranchBase::getHubResultRef() { + return hub->getResultRef(); +} + +// ------------------------------------------------------------------- + +class ChainPromiseNode final: public PromiseNode, public Event { + // Promise node which reduces Promise> to Promise. + // + // `Event` is only a public base class because otherwise we can't cast Own to + // Own. Ugh, templates and private... + +public: + explicit ChainPromiseNode(Own inner); + ~ChainPromiseNode() noexcept(false); + + void onReady(Event& event) noexcept override; + void setSelfPointer(Own* selfPtr) noexcept override; + void get(ExceptionOrValue& output) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + enum State { + STEP1, + STEP2 + }; + + State state; + + Own inner; + // In STEP1, a PromiseNode for a Promise. + // In STEP2, a PromiseNode for a T. + + Event* onReadyEvent = nullptr; + Own* selfPtr = nullptr; + + Maybe> fire() override; +}; + +template +Own maybeChain(Own&& node, Promise*) { + return heap(kj::mv(node)); +} + +template +Own&& maybeChain(Own&& node, T*) { + return kj::mv(node); +} + +// ------------------------------------------------------------------- + +class ExclusiveJoinPromiseNode final: public PromiseNode { +public: + ExclusiveJoinPromiseNode(Own left, Own right); + ~ExclusiveJoinPromiseNode() noexcept(false); + + void onReady(Event& event) noexcept override; + void get(ExceptionOrValue& output) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + class Branch: public Event { + public: + Branch(ExclusiveJoinPromiseNode& joinNode, Own dependency); + ~Branch() noexcept(false); + + bool get(ExceptionOrValue& output); + // Returns true if this is the side that finished. + + Maybe> fire() override; + _::PromiseNode* getInnerForTrace() override; + + private: + ExclusiveJoinPromiseNode& joinNode; + Own dependency; + }; + + Branch left; + Branch right; + OnReadyEvent onReadyEvent; +}; + +// ------------------------------------------------------------------- + +class ArrayJoinPromiseNodeBase: public PromiseNode { +public: + ArrayJoinPromiseNodeBase(Array> promises, + ExceptionOrValue* resultParts, size_t partSize); + ~ArrayJoinPromiseNodeBase() noexcept(false); + + void onReady(Event& event) noexcept override final; + void get(ExceptionOrValue& output) noexcept override final; + PromiseNode* getInnerForTrace() override final; + +protected: + virtual void getNoError(ExceptionOrValue& output) noexcept = 0; + // Called to compile the result only in the case where there were no errors. + +private: + uint countLeft; + OnReadyEvent onReadyEvent; + + class Branch final: public Event { + public: + Branch(ArrayJoinPromiseNodeBase& joinNode, Own dependency, + ExceptionOrValue& output); + ~Branch() noexcept(false); + + Maybe> fire() override; + _::PromiseNode* getInnerForTrace() override; + + Maybe getPart(); + // Calls dependency->get(output). If there was an exception, return it. + + private: + ArrayJoinPromiseNodeBase& joinNode; + Own dependency; + ExceptionOrValue& output; + }; + + Array branches; +}; + +template +class ArrayJoinPromiseNode final: public ArrayJoinPromiseNodeBase { +public: + ArrayJoinPromiseNode(Array> promises, + Array> resultParts) + : ArrayJoinPromiseNodeBase(kj::mv(promises), resultParts.begin(), sizeof(ExceptionOr)), + resultParts(kj::mv(resultParts)) {} + +protected: + void getNoError(ExceptionOrValue& output) noexcept override { + auto builder = heapArrayBuilder(resultParts.size()); + for (auto& part: resultParts) { + KJ_IASSERT(part.value != nullptr, + "Bug in KJ promise framework: Promise result had neither value no exception."); + builder.add(kj::mv(*_::readMaybe(part.value))); + } + output.as>() = builder.finish(); + } + +private: + Array> resultParts; +}; + +template <> +class ArrayJoinPromiseNode final: public ArrayJoinPromiseNodeBase { +public: + ArrayJoinPromiseNode(Array> promises, + Array> resultParts); + ~ArrayJoinPromiseNode(); + +protected: + void getNoError(ExceptionOrValue& output) noexcept override; + +private: + Array> resultParts; +}; + +// ------------------------------------------------------------------- + +class EagerPromiseNodeBase: public PromiseNode, protected Event { + // A PromiseNode that eagerly evaluates its dependency even if its dependent does not eagerly + // evaluate it. + +public: + EagerPromiseNodeBase(Own&& dependency, ExceptionOrValue& resultRef); + + void onReady(Event& event) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + Own dependency; + OnReadyEvent onReadyEvent; + + ExceptionOrValue& resultRef; + + Maybe> fire() override; +}; + +template +class EagerPromiseNode final: public EagerPromiseNodeBase { +public: + EagerPromiseNode(Own&& dependency) + : EagerPromiseNodeBase(kj::mv(dependency), result) {} + + void get(ExceptionOrValue& output) noexcept override { + output.as() = kj::mv(result); + } + +private: + ExceptionOr result; +}; + +template +Own spark(Own&& node) { + // Forces evaluation of the given node to begin as soon as possible, even if no one is waiting + // on it. + return heap>(kj::mv(node)); +} + +// ------------------------------------------------------------------- + +class AdapterPromiseNodeBase: public PromiseNode { +public: + void onReady(Event& event) noexcept override; + +protected: + inline void setReady() { + onReadyEvent.arm(); + } + +private: + OnReadyEvent onReadyEvent; +}; + +template +class AdapterPromiseNode final: public AdapterPromiseNodeBase, + private PromiseFulfiller> { + // A PromiseNode that wraps a PromiseAdapter. + +public: + template + AdapterPromiseNode(Params&&... params) + : adapter(static_cast>&>(*this), kj::fwd(params)...) {} + + void get(ExceptionOrValue& output) noexcept override { + KJ_IREQUIRE(!isWaiting()); + output.as() = kj::mv(result); + } + +private: + ExceptionOr result; + bool waiting = true; + Adapter adapter; + + void fulfill(T&& value) override { + if (waiting) { + waiting = false; + result = ExceptionOr(kj::mv(value)); + setReady(); + } + } + + void reject(Exception&& exception) override { + if (waiting) { + waiting = false; + result = ExceptionOr(false, kj::mv(exception)); + setReady(); + } + } + + bool isWaiting() override { + return waiting; + } +}; + +} // namespace _ (private) + +// ======================================================================================= + +template +Promise::Promise(_::FixVoid value) + : PromiseBase(heap<_::ImmediatePromiseNode<_::FixVoid>>(kj::mv(value))) {} + +template +Promise::Promise(kj::Exception&& exception) + : PromiseBase(heap<_::ImmediateBrokenPromiseNode>(kj::mv(exception))) {} + +template +template +PromiseForResult Promise::then(Func&& func, ErrorFunc&& errorHandler) { + typedef _::FixVoid<_::ReturnType> ResultT; + + Own<_::PromiseNode> intermediate = + heap<_::TransformPromiseNode, Func, ErrorFunc>>( + kj::mv(node), kj::fwd(func), kj::fwd(errorHandler)); + return PromiseForResult(false, + _::maybeChain(kj::mv(intermediate), implicitCast(nullptr))); +} + +namespace _ { // private + +template +struct IdentityFunc { + inline T operator()(T&& value) const { + return kj::mv(value); + } +}; +template +struct IdentityFunc> { + inline Promise operator()(T&& value) const { + return kj::mv(value); + } +}; +template <> +struct IdentityFunc { + inline void operator()() const {} +}; +template <> +struct IdentityFunc> { + Promise operator()() const; + // This can't be inline because it will make the translation unit depend on kj-async. Awkwardly, + // Cap'n Proto relies on being able to include this header without creating such a link-time + // dependency. +}; + +} // namespace _ (private) + +template +template +Promise Promise::catch_(ErrorFunc&& errorHandler) { + // then()'s ErrorFunc can only return a Promise if Func also returns a Promise. In this case, + // Func is being filled in automatically. We want to make sure ErrorFunc can return a Promise, + // but we don't want the extra overhead of promise chaining if ErrorFunc doesn't actually + // return a promise. So we make our Func return match ErrorFunc. + return then(_::IdentityFunc()))>(), + kj::fwd(errorHandler)); +} + +template +T Promise::wait(WaitScope& waitScope) { + _::ExceptionOr<_::FixVoid> result; + + waitImpl(kj::mv(node), result, waitScope); + + KJ_IF_MAYBE(value, result.value) { + KJ_IF_MAYBE(exception, result.exception) { + throwRecoverableException(kj::mv(*exception)); + } + return _::returnMaybeVoid(kj::mv(*value)); + } else KJ_IF_MAYBE(exception, result.exception) { + throwFatalException(kj::mv(*exception)); + } else { + // Result contained neither a value nor an exception? + KJ_UNREACHABLE; + } +} + +template <> +inline void Promise::wait(WaitScope& waitScope) { + // Override case to use throwRecoverableException(). + + _::ExceptionOr<_::Void> result; + + waitImpl(kj::mv(node), result, waitScope); + + if (result.value != nullptr) { + KJ_IF_MAYBE(exception, result.exception) { + throwRecoverableException(kj::mv(*exception)); + } + } else KJ_IF_MAYBE(exception, result.exception) { + throwRecoverableException(kj::mv(*exception)); + } else { + // Result contained neither a value nor an exception? + KJ_UNREACHABLE; + } +} + +template +ForkedPromise Promise::fork() { + return ForkedPromise(false, refcounted<_::ForkHub<_::FixVoid>>(kj::mv(node))); +} + +template +Promise ForkedPromise::addBranch() { + return hub->addBranch(); +} + +template +_::SplitTuplePromise Promise::split() { + return refcounted<_::ForkHub<_::FixVoid>>(kj::mv(node))->split(); +} + +template +Promise Promise::exclusiveJoin(Promise&& other) { + return Promise(false, heap<_::ExclusiveJoinPromiseNode>(kj::mv(node), kj::mv(other.node))); +} + +template +template +Promise Promise::attach(Attachments&&... attachments) { + return Promise(false, kj::heap<_::AttachmentPromiseNode>>( + kj::mv(node), kj::tuple(kj::fwd(attachments)...))); +} + +template +template +Promise Promise::eagerlyEvaluate(ErrorFunc&& errorHandler) { + // See catch_() for commentary. + return Promise(false, _::spark<_::FixVoid>(then( + _::IdentityFunc()))>(), + kj::fwd(errorHandler)).node)); +} + +template +Promise Promise::eagerlyEvaluate(decltype(nullptr)) { + return Promise(false, _::spark<_::FixVoid>(kj::mv(node))); +} + +template +kj::String Promise::trace() { + return PromiseBase::trace(); +} + +template +inline PromiseForResult evalLater(Func&& func) { + return _::yield().then(kj::fwd(func), _::PropagateException()); +} + +template +inline PromiseForResult evalNow(Func&& func) { + PromiseForResult result = nullptr; + KJ_IF_MAYBE(e, kj::runCatchingExceptions([&]() { + result = func(); + })) { + result = kj::mv(*e); + } + return result; +} + +template +template +void Promise::detach(ErrorFunc&& errorHandler) { + return _::detach(then([](T&&) {}, kj::fwd(errorHandler))); +} + +template <> +template +void Promise::detach(ErrorFunc&& errorHandler) { + return _::detach(then([]() {}, kj::fwd(errorHandler))); +} + +template +Promise> joinPromises(Array>&& promises) { + return Promise>(false, kj::heap<_::ArrayJoinPromiseNode>( + KJ_MAP(p, promises) { return kj::mv(p.node); }, + heapArray<_::ExceptionOr>(promises.size()))); +} + +// ======================================================================================= + +namespace _ { // private + +template +class WeakFulfiller final: public PromiseFulfiller, private kj::Disposer { + // A wrapper around PromiseFulfiller which can be detached. + // + // There are a couple non-trivialities here: + // - If the WeakFulfiller is discarded, we want the promise it fulfills to be implicitly + // rejected. + // - We cannot destroy the WeakFulfiller until the application has discarded it *and* it has been + // detached from the underlying fulfiller, because otherwise the later detach() call will go + // to a dangling pointer. Essentially, WeakFulfiller is reference counted, although the + // refcount never goes over 2 and we manually implement the refcounting because we need to do + // other special things when each side detaches anyway. To this end, WeakFulfiller is its own + // Disposer -- dispose() is called when the application discards its owned pointer to the + // fulfiller and detach() is called when the promise is destroyed. + +public: + KJ_DISALLOW_COPY(WeakFulfiller); + + static kj::Own make() { + WeakFulfiller* ptr = new WeakFulfiller; + return Own(ptr, *ptr); + } + + void fulfill(FixVoid&& value) override { + if (inner != nullptr) { + inner->fulfill(kj::mv(value)); + } + } + + void reject(Exception&& exception) override { + if (inner != nullptr) { + inner->reject(kj::mv(exception)); + } + } + + bool isWaiting() override { + return inner != nullptr && inner->isWaiting(); + } + + void attach(PromiseFulfiller& newInner) { + inner = &newInner; + } + + void detach(PromiseFulfiller& from) { + if (inner == nullptr) { + // Already disposed. + delete this; + } else { + KJ_IREQUIRE(inner == &from); + inner = nullptr; + } + } + +private: + mutable PromiseFulfiller* inner; + + WeakFulfiller(): inner(nullptr) {} + + void disposeImpl(void* pointer) const override { + // TODO(perf): Factor some of this out so it isn't regenerated for every fulfiller type? + + if (inner == nullptr) { + // Already detached. + delete this; + } else { + if (inner->isWaiting()) { + inner->reject(kj::Exception(kj::Exception::Type::FAILED, __FILE__, __LINE__, + kj::heapString("PromiseFulfiller was destroyed without fulfilling the promise."))); + } + inner = nullptr; + } + } +}; + +template +class PromiseAndFulfillerAdapter { +public: + PromiseAndFulfillerAdapter(PromiseFulfiller& fulfiller, + WeakFulfiller& wrapper) + : fulfiller(fulfiller), wrapper(wrapper) { + wrapper.attach(fulfiller); + } + + ~PromiseAndFulfillerAdapter() noexcept(false) { + wrapper.detach(fulfiller); + } + +private: + PromiseFulfiller& fulfiller; + WeakFulfiller& wrapper; +}; + +} // namespace _ (private) + +template +template +bool PromiseFulfiller::rejectIfThrows(Func&& func) { + KJ_IF_MAYBE(exception, kj::runCatchingExceptions(kj::mv(func))) { + reject(kj::mv(*exception)); + return false; + } else { + return true; + } +} + +template +bool PromiseFulfiller::rejectIfThrows(Func&& func) { + KJ_IF_MAYBE(exception, kj::runCatchingExceptions(kj::mv(func))) { + reject(kj::mv(*exception)); + return false; + } else { + return true; + } +} + +template +Promise newAdaptedPromise(Params&&... adapterConstructorParams) { + return Promise(false, heap<_::AdapterPromiseNode<_::FixVoid, Adapter>>( + kj::fwd(adapterConstructorParams)...)); +} + +template +PromiseFulfillerPair newPromiseAndFulfiller() { + auto wrapper = _::WeakFulfiller::make(); + + Own<_::PromiseNode> intermediate( + heap<_::AdapterPromiseNode<_::FixVoid, _::PromiseAndFulfillerAdapter>>(*wrapper)); + Promise<_::JoinPromises> promise(false, + _::maybeChain(kj::mv(intermediate), implicitCast(nullptr))); + + return PromiseFulfillerPair { kj::mv(promise), kj::mv(wrapper) }; +} + +} // namespace kj + +#endif // KJ_ASYNC_INL_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/async-io.h --- a/win32-mingw/include/kj/async-io.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/async-io.h Tue May 23 09:16:54 2017 +0100 @@ -1,502 +1,560 @@ -// 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. - -#ifndef KJ_ASYNC_IO_H_ -#define KJ_ASYNC_IO_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "async.h" -#include "function.h" -#include "thread.h" -#include "time.h" - -struct sockaddr; - -namespace kj { - -class UnixEventPort; -class NetworkAddress; - -// ======================================================================================= -// Streaming I/O - -class AsyncInputStream { - // Asynchronous equivalent of InputStream (from io.h). - -public: - virtual Promise read(void* buffer, size_t minBytes, size_t maxBytes) = 0; - virtual Promise tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; - - Promise read(void* buffer, size_t bytes); -}; - -class AsyncOutputStream { - // Asynchronous equivalent of OutputStream (from io.h). - -public: - virtual Promise write(const void* buffer, size_t size) = 0; - virtual Promise write(ArrayPtr> pieces) = 0; -}; - -class AsyncIoStream: public AsyncInputStream, public AsyncOutputStream { - // A combination input and output stream. - -public: - virtual void shutdownWrite() = 0; - // Cleanly shut down just the write end of the stream, while keeping the read end open. - - virtual void abortRead() {} - // Similar to shutdownWrite, but this will shut down the read end of the stream, and should only - // be called when an error has occurred. - - virtual void getsockopt(int level, int option, void* value, uint* length); - virtual void setsockopt(int level, int option, const void* value, uint length); - // Corresponds to getsockopt() and setsockopt() syscalls. Will throw an "unimplemented" exception - // if the stream is not a socket or the option is not appropriate for the socket type. The - // default implementations always throw "unimplemented". - - virtual void getsockname(struct sockaddr* addr, uint* length); - virtual void getpeername(struct sockaddr* addr, uint* length); - // Corresponds to getsockname() and getpeername() syscalls. Will throw an "unimplemented" - // exception if the stream is not a socket. The default implementations always throw - // "unimplemented". - // - // Note that we don't provide methods that return NetworkAddress because it usually wouldn't - // be useful. You can't connect() to or listen() on these addresses, obviously, because they are - // ephemeral addresses for a single connection. -}; - -struct OneWayPipe { - // A data pipe with an input end and an output end. (Typically backed by pipe() system call.) - - Own in; - Own out; -}; - -struct TwoWayPipe { - // A data pipe that supports sending in both directions. Each end's output sends data to the - // other end's input. (Typically backed by socketpair() system call.) - - Own ends[2]; -}; - -class ConnectionReceiver { - // Represents a server socket listening on a port. - -public: - virtual Promise> accept() = 0; - // Accept the next incoming connection. - - virtual uint getPort() = 0; - // Gets the port number, if applicable (i.e. if listening on IP). This is useful if you didn't - // specify a port when constructing the NetworkAddress -- one will have been assigned - // automatically. - - virtual void getsockopt(int level, int option, void* value, uint* length); - virtual void setsockopt(int level, int option, const void* value, uint length); - // Same as the methods of AsyncIoStream. -}; - -// ======================================================================================= -// Datagram I/O - -class AncillaryMessage { - // Represents an ancillary message (aka control message) received using the recvmsg() system - // call (or equivalent). Most apps will not use this. - -public: - inline AncillaryMessage(int level, int type, ArrayPtr data); - AncillaryMessage() = default; - - inline int getLevel() const; - // Originating protocol / socket level. - - inline int getType() const; - // Protocol-specific message type. - - template - inline Maybe as(); - // Interpret the ancillary message as the given struct type. Most ancillary messages are some - // sort of struct, so this is a convenient way to access it. Returns nullptr if the message - // is smaller than the struct -- this can happen if the message was truncated due to - // insufficient ancillary buffer space. - - template - inline ArrayPtr asArray(); - // Interpret the ancillary message as an array of items. If the message size does not evenly - // divide into elements of type T, the remainder is discarded -- this can happen if the message - // was truncated due to insufficient ancillary buffer space. - -private: - int level; - int type; - ArrayPtr data; - // Message data. In most cases you should use `as()` or `asArray()`. -}; - -class DatagramReceiver { - // Class encapsulating the recvmsg() system call. You must specify the DatagramReceiver's - // capacity in advance; if a received packet is larger than the capacity, it will be truncated. - -public: - virtual Promise receive() = 0; - // Receive a new message, overwriting this object's content. - // - // receive() may reuse the same buffers for content and ancillary data with each call. - - template - struct MaybeTruncated { - T value; - - bool isTruncated; - // True if the Receiver's capacity was insufficient to receive the value and therefore the - // value is truncated. - }; - - virtual MaybeTruncated> getContent() = 0; - // Get the content of the datagram. - - virtual MaybeTruncated> getAncillary() = 0; - // Ancilarry messages received with the datagram. See the recvmsg() system call and the cmsghdr - // struct. Most apps don't need this. - // - // If the returned value is truncated, then the last message in the array may itself be - // truncated, meaning its as() method will return nullptr or its asArray() method will - // return fewer elements than expected. Truncation can also mean that additional messages were - // available but discarded. - - virtual NetworkAddress& getSource() = 0; - // Get the datagram sender's address. - - struct Capacity { - size_t content = 8192; - // How much space to allocate for the datagram content. If a datagram is received that is - // larger than this, it will be truncated, with no way to recover the tail. - - size_t ancillary = 0; - // How much space to allocate for ancillary messages. As with content, if the ancillary data - // is larger than this, it will be truncated. - }; -}; - -class DatagramPort { -public: - virtual Promise send(const void* buffer, size_t size, NetworkAddress& destination) = 0; - virtual Promise send(ArrayPtr> pieces, - NetworkAddress& destination) = 0; - - virtual Own makeReceiver( - DatagramReceiver::Capacity capacity = DatagramReceiver::Capacity()) = 0; - // Create a new `Receiver` that can be used to receive datagrams. `capacity` specifies how much - // space to allocate for the received message. The `DatagramPort` must outlive the `Receiver`. - - virtual uint getPort() = 0; - // Gets the port number, if applicable (i.e. if listening on IP). This is useful if you didn't - // specify a port when constructing the NetworkAddress -- one will have been assigned - // automatically. - - virtual void getsockopt(int level, int option, void* value, uint* length); - virtual void setsockopt(int level, int option, const void* value, uint length); - // Same as the methods of AsyncIoStream. -}; - -// ======================================================================================= -// Networks - -class NetworkAddress { - // Represents a remote address to which the application can connect. - -public: - virtual Promise> connect() = 0; - // Make a new connection to this address. - // - // The address must not be a wildcard ("*"). If it is an IP address, it must have a port number. - - virtual Own listen() = 0; - // Listen for incoming connections on this address. - // - // The address must be local. - - virtual Own bindDatagramPort(); - // Open this address as a datagram (e.g. UDP) port. - // - // The address must be local. - - virtual Own clone() = 0; - // Returns an equivalent copy of this NetworkAddress. - - virtual String toString() = 0; - // Produce a human-readable string which hopefully can be passed to Network::parseAddress() - // to reproduce this address, although whether or not that works of course depends on the Network - // implementation. This should be called only to display the address to human users, who will - // hopefully know what they are able to do with it. -}; - -class Network { - // Factory for NetworkAddress instances, representing the network services offered by the - // operating system. - // - // This interface typically represents broad authority, and well-designed code should limit its - // use to high-level startup code and user interaction. Low-level APIs should accept - // NetworkAddress instances directly and work from there, if at all possible. - -public: - virtual Promise> parseAddress(StringPtr addr, uint portHint = 0) = 0; - // Construct a network address from a user-provided string. The format of the address - // strings is not specified at the API level, and application code should make no assumptions - // about them. These strings should always be provided by humans, and said humans will know - // what format to use in their particular context. - // - // `portHint`, if provided, specifies the "standard" IP port number for the application-level - // service in play. If the address turns out to be an IP address (v4 or v6), and it lacks a - // port number, this port will be used. If `addr` lacks a port number *and* `portHint` is - // omitted, then the returned address will only support listen() and bindDatagramPort() - // (not connect()), and an unused port will be chosen each time one of those methods is called. - - virtual Own getSockaddr(const void* sockaddr, uint len) = 0; - // Construct a network address from a legacy struct sockaddr. -}; - -// ======================================================================================= -// I/O Provider - -class AsyncIoProvider { - // Class which constructs asynchronous wrappers around the operating system's I/O facilities. - // - // Generally, the implementation of this interface must integrate closely with a particular - // `EventLoop` implementation. Typically, the EventLoop implementation itself will provide - // an AsyncIoProvider. - -public: - virtual OneWayPipe newOneWayPipe() = 0; - // Creates an input/output stream pair representing the ends of a one-way pipe (e.g. created with - // the pipe(2) system call). - - virtual TwoWayPipe newTwoWayPipe() = 0; - // Creates two AsyncIoStreams representing the two ends of a two-way pipe (e.g. created with - // socketpair(2) system call). Data written to one end can be read from the other. - - virtual Network& getNetwork() = 0; - // Creates a new `Network` instance representing the networks exposed by the operating system. - // - // DO NOT CALL THIS except at the highest levels of your code, ideally in the main() function. If - // you call this from low-level code, then you are preventing higher-level code from injecting an - // alternative implementation. Instead, if your code needs to use network functionality, it - // should ask for a `Network` as a constructor or method parameter, so that higher-level code can - // chose what implementation to use. The system network is essentially a singleton. See: - // http://www.object-oriented-security.org/lets-argue/singletons - // - // Code that uses the system network should not make any assumptions about what kinds of - // addresses it will parse, as this could differ across platforms. String addresses should come - // strictly from the user, who will know how to write them correctly for their system. - // - // With that said, KJ currently supports the following string address formats: - // - IPv4: "1.2.3.4", "1.2.3.4:80" - // - IPv6: "1234:5678::abcd", "[1234:5678::abcd]:80" - // - Local IP wildcard (covers both v4 and v6): "*", "*:80" - // - Symbolic names: "example.com", "example.com:80", "example.com:http", "1.2.3.4:http" - // - Unix domain: "unix:/path/to/socket" - - struct PipeThread { - // A combination of a thread and a two-way pipe that communicates with that thread. - // - // The fields are intentionally ordered so that the pipe will be destroyed (and therefore - // disconnected) before the thread is destroyed (and therefore joined). Thus if the thread - // arranges to exit when it detects disconnect, destruction should be clean. - - Own thread; - Own pipe; - }; - - virtual PipeThread newPipeThread( - Function startFunc) = 0; - // Create a new thread and set up a two-way pipe (socketpair) which can be used to communicate - // with it. One end of the pipe is passed to the thread's start function and the other end of - // the pipe is returned. The new thread also gets its own `AsyncIoProvider` instance and will - // already have an active `EventLoop` when `startFunc` is called. - // - // TODO(someday): I'm not entirely comfortable with this interface. It seems to be doing too - // much at once but I'm not sure how to cleanly break it down. - - virtual Timer& getTimer() = 0; - // Returns a `Timer` based on real time. Time does not pass while event handlers are running -- - // it only updates when the event loop polls for system events. This means that calling `now()` - // on this timer does not require a system call. - // - // This timer is not affected by changes to the system date. It is unspecified whether the timer - // continues to count while the system is suspended. -}; - -class LowLevelAsyncIoProvider { - // Similar to `AsyncIoProvider`, but represents a lower-level interface that may differ on - // different operating systems. You should prefer to use `AsyncIoProvider` over this interface - // whenever possible, as `AsyncIoProvider` is portable and friendlier to dependency-injection. - // - // On Unix, this interface can be used to import native file descriptors into the async framework. - // Different implementations of this interface might work on top of different event handling - // primitives, such as poll vs. epoll vs. kqueue vs. some higher-level event library. - // - // On Windows, this interface can be used to import native HANDLEs into the async framework. - // Different implementations of this interface might work on top of different event handling - // primitives, such as I/O completion ports vs. completion routines. - // - // TODO(port): Actually implement Windows support. - -public: - // --------------------------------------------------------------------------- - // Unix-specific stuff - - enum Flags { - // Flags controlling how to wrap a file descriptor. - - TAKE_OWNERSHIP = 1 << 0, - // The returned object should own the file descriptor, automatically closing it when destroyed. - // The close-on-exec flag will be set on the descriptor if it is not already. - // - // If this flag is not used, then the file descriptor is not automatically closed and the - // close-on-exec flag is not modified. - - ALREADY_CLOEXEC = 1 << 1, - // Indicates that the close-on-exec flag is known already to be set, so need not be set again. - // Only relevant when combined with TAKE_OWNERSHIP. - // - // On Linux, all system calls which yield new file descriptors have flags or variants which - // set the close-on-exec flag immediately. Unfortunately, other OS's do not. - - ALREADY_NONBLOCK = 1 << 2 - // Indicates that the file descriptor is known already to be in non-blocking mode, so the flag - // need not be set again. Otherwise, all wrap*Fd() methods will enable non-blocking mode - // automatically. - // - // On Linux, all system calls which yield new file descriptors have flags or variants which - // enable non-blocking mode immediately. Unfortunately, other OS's do not. - }; - - virtual Own wrapInputFd(int fd, uint flags = 0) = 0; - // Create an AsyncInputStream wrapping a file descriptor. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Own wrapOutputFd(int fd, uint flags = 0) = 0; - // Create an AsyncOutputStream wrapping a file descriptor. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Own wrapSocketFd(int fd, uint flags = 0) = 0; - // Create an AsyncIoStream wrapping a socket file descriptor. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Promise> wrapConnectingSocketFd(int fd, uint flags = 0) = 0; - // Create an AsyncIoStream wrapping a socket that is in the process of connecting. The returned - // promise should not resolve until connection has completed -- traditionally indicated by the - // descriptor becoming writable. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Own wrapListenSocketFd(int fd, uint flags = 0) = 0; - // Create an AsyncIoStream wrapping a listen socket file descriptor. This socket should already - // have had `bind()` and `listen()` called on it, so it's ready for `accept()`. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Own wrapDatagramSocketFd(int fd, uint flags = 0); - - virtual Timer& getTimer() = 0; - // Returns a `Timer` based on real time. Time does not pass while event handlers are running -- - // it only updates when the event loop polls for system events. This means that calling `now()` - // on this timer does not require a system call. - // - // This timer is not affected by changes to the system date. It is unspecified whether the timer - // continues to count while the system is suspended. -}; - -Own newAsyncIoProvider(LowLevelAsyncIoProvider& lowLevel); -// Make a new AsyncIoProvider wrapping a `LowLevelAsyncIoProvider`. - -struct AsyncIoContext { - Own lowLevelProvider; - Own provider; - WaitScope& waitScope; - - UnixEventPort& unixEventPort; - // TEMPORARY: Direct access to underlying UnixEventPort, mainly for waiting on signals. This - // field will go away at some point when we have a chance to improve these interfaces. -}; - -AsyncIoContext setupAsyncIo(); -// Convenience method which sets up the current thread with everything it needs to do async I/O. -// The returned objects contain an `EventLoop` which is wrapping an appropriate `EventPort` for -// doing I/O on the host system, so everything is ready for the thread to start making async calls -// and waiting on promises. -// -// You would typically call this in your main() loop or in the start function of a thread. -// Example: -// -// int main() { -// auto ioContext = kj::setupAsyncIo(); -// -// // Now we can call an async function. -// Promise textPromise = getHttp(*ioContext.provider, "http://example.com"); -// -// // And we can wait for the promise to complete. Note that you can only use `wait()` -// // from the top level, not from inside a promise callback. -// String text = textPromise.wait(ioContext.waitScope); -// print(text); -// return 0; -// } -// -// WARNING: An AsyncIoContext can only be used in the thread and process that created it. In -// particular, note that after a fork(), an AsyncIoContext created in the parent process will -// not work correctly in the child, even if the parent ceases to use its copy. In particular -// note that this means that server processes which daemonize themselves at startup must wait -// until after daemonization to create an AsyncIoContext. - -// ======================================================================================= -// inline implementation details - -inline AncillaryMessage::AncillaryMessage( - int level, int type, ArrayPtr data) - : level(level), type(type), data(data) {} - -inline int AncillaryMessage::getLevel() const { return level; } -inline int AncillaryMessage::getType() const { return type; } - -template -inline Maybe AncillaryMessage::as() { - if (data.size() >= sizeof(T)) { - return *reinterpret_cast(data.begin()); - } else { - return nullptr; - } -} - -template -inline ArrayPtr AncillaryMessage::asArray() { - return arrayPtr(reinterpret_cast(data.begin()), data.size() / sizeof(T)); -} - -} // namespace kj - -#endif // KJ_ASYNC_IO_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. + +#ifndef KJ_ASYNC_IO_H_ +#define KJ_ASYNC_IO_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "async.h" +#include "function.h" +#include "thread.h" +#include "time.h" + +struct sockaddr; + +namespace kj { + +#if _WIN32 +class Win32EventPort; +#else +class UnixEventPort; +#endif + +class NetworkAddress; +class AsyncOutputStream; + +// ======================================================================================= +// Streaming I/O + +class AsyncInputStream { + // Asynchronous equivalent of InputStream (from io.h). + +public: + virtual Promise read(void* buffer, size_t minBytes, size_t maxBytes); + virtual Promise tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; + + Promise read(void* buffer, size_t bytes); + + virtual Maybe tryGetLength(); + // Get the remaining number of bytes that will be produced by this stream, if known. + // + // This is used e.g. to fill in the Content-Length header of an HTTP message. If unknown, the + // HTTP implementation may need to fall back to Transfer-Encoding: chunked. + // + // The default implementation always returns null. + + virtual Promise pumpTo( + AsyncOutputStream& output, uint64_t amount = kj::maxValue); + // Read `amount` bytes from this stream (or to EOF) and write them to `output`, returning the + // total bytes actually pumped (which is only less than `amount` if EOF was reached). + // + // Override this if your stream type knows how to pump itself to certain kinds of output + // streams more efficiently than via the naive approach. You can use + // kj::dynamicDowncastIfAvailable() to test for stream types you recognize, and if none match, + // delegate to the default implementation. + // + // The default implementation first tries calling output.tryPumpFrom(), but if that fails, it + // performs a naive pump by allocating a buffer and reading to it / writing from it in a loop. + + Promise> readAllBytes(); + Promise readAllText(); + // Read until EOF and return as one big byte array or string. +}; + +class AsyncOutputStream { + // Asynchronous equivalent of OutputStream (from io.h). + +public: + virtual Promise write(const void* buffer, size_t size) = 0; + virtual Promise write(ArrayPtr> pieces) = 0; + + virtual Maybe> tryPumpFrom( + AsyncInputStream& input, uint64_t amount = kj::maxValue); + // Implements double-dispatch for AsyncInputStream::pumpTo(). + // + // This method should only be called from within an implementation of pumpTo(). + // + // This method examines the type of `input` to find optimized ways to pump data from it to this + // output stream. If it finds one, it performs the pump. Otherwise, it returns null. + // + // The default implementation always returns null. +}; + +class AsyncIoStream: public AsyncInputStream, public AsyncOutputStream { + // A combination input and output stream. + +public: + virtual void shutdownWrite() = 0; + // Cleanly shut down just the write end of the stream, while keeping the read end open. + + virtual void abortRead() {} + // Similar to shutdownWrite, but this will shut down the read end of the stream, and should only + // be called when an error has occurred. + + virtual void getsockopt(int level, int option, void* value, uint* length); + virtual void setsockopt(int level, int option, const void* value, uint length); + // Corresponds to getsockopt() and setsockopt() syscalls. Will throw an "unimplemented" exception + // if the stream is not a socket or the option is not appropriate for the socket type. The + // default implementations always throw "unimplemented". + + virtual void getsockname(struct sockaddr* addr, uint* length); + virtual void getpeername(struct sockaddr* addr, uint* length); + // Corresponds to getsockname() and getpeername() syscalls. Will throw an "unimplemented" + // exception if the stream is not a socket. The default implementations always throw + // "unimplemented". + // + // Note that we don't provide methods that return NetworkAddress because it usually wouldn't + // be useful. You can't connect() to or listen() on these addresses, obviously, because they are + // ephemeral addresses for a single connection. +}; + +struct OneWayPipe { + // A data pipe with an input end and an output end. (Typically backed by pipe() system call.) + + Own in; + Own out; +}; + +struct TwoWayPipe { + // A data pipe that supports sending in both directions. Each end's output sends data to the + // other end's input. (Typically backed by socketpair() system call.) + + Own ends[2]; +}; + +class ConnectionReceiver { + // Represents a server socket listening on a port. + +public: + virtual Promise> accept() = 0; + // Accept the next incoming connection. + + virtual uint getPort() = 0; + // Gets the port number, if applicable (i.e. if listening on IP). This is useful if you didn't + // specify a port when constructing the NetworkAddress -- one will have been assigned + // automatically. + + virtual void getsockopt(int level, int option, void* value, uint* length); + virtual void setsockopt(int level, int option, const void* value, uint length); + // Same as the methods of AsyncIoStream. +}; + +// ======================================================================================= +// Datagram I/O + +class AncillaryMessage { + // Represents an ancillary message (aka control message) received using the recvmsg() system + // call (or equivalent). Most apps will not use this. + +public: + inline AncillaryMessage(int level, int type, ArrayPtr data); + AncillaryMessage() = default; + + inline int getLevel() const; + // Originating protocol / socket level. + + inline int getType() const; + // Protocol-specific message type. + + template + inline Maybe as(); + // Interpret the ancillary message as the given struct type. Most ancillary messages are some + // sort of struct, so this is a convenient way to access it. Returns nullptr if the message + // is smaller than the struct -- this can happen if the message was truncated due to + // insufficient ancillary buffer space. + + template + inline ArrayPtr asArray(); + // Interpret the ancillary message as an array of items. If the message size does not evenly + // divide into elements of type T, the remainder is discarded -- this can happen if the message + // was truncated due to insufficient ancillary buffer space. + +private: + int level; + int type; + ArrayPtr data; + // Message data. In most cases you should use `as()` or `asArray()`. +}; + +class DatagramReceiver { + // Class encapsulating the recvmsg() system call. You must specify the DatagramReceiver's + // capacity in advance; if a received packet is larger than the capacity, it will be truncated. + +public: + virtual Promise receive() = 0; + // Receive a new message, overwriting this object's content. + // + // receive() may reuse the same buffers for content and ancillary data with each call. + + template + struct MaybeTruncated { + T value; + + bool isTruncated; + // True if the Receiver's capacity was insufficient to receive the value and therefore the + // value is truncated. + }; + + virtual MaybeTruncated> getContent() = 0; + // Get the content of the datagram. + + virtual MaybeTruncated> getAncillary() = 0; + // Ancilarry messages received with the datagram. See the recvmsg() system call and the cmsghdr + // struct. Most apps don't need this. + // + // If the returned value is truncated, then the last message in the array may itself be + // truncated, meaning its as() method will return nullptr or its asArray() method will + // return fewer elements than expected. Truncation can also mean that additional messages were + // available but discarded. + + virtual NetworkAddress& getSource() = 0; + // Get the datagram sender's address. + + struct Capacity { + size_t content = 8192; + // How much space to allocate for the datagram content. If a datagram is received that is + // larger than this, it will be truncated, with no way to recover the tail. + + size_t ancillary = 0; + // How much space to allocate for ancillary messages. As with content, if the ancillary data + // is larger than this, it will be truncated. + }; +}; + +class DatagramPort { +public: + virtual Promise send(const void* buffer, size_t size, NetworkAddress& destination) = 0; + virtual Promise send(ArrayPtr> pieces, + NetworkAddress& destination) = 0; + + virtual Own makeReceiver( + DatagramReceiver::Capacity capacity = DatagramReceiver::Capacity()) = 0; + // Create a new `Receiver` that can be used to receive datagrams. `capacity` specifies how much + // space to allocate for the received message. The `DatagramPort` must outlive the `Receiver`. + + virtual uint getPort() = 0; + // Gets the port number, if applicable (i.e. if listening on IP). This is useful if you didn't + // specify a port when constructing the NetworkAddress -- one will have been assigned + // automatically. + + virtual void getsockopt(int level, int option, void* value, uint* length); + virtual void setsockopt(int level, int option, const void* value, uint length); + // Same as the methods of AsyncIoStream. +}; + +// ======================================================================================= +// Networks + +class NetworkAddress { + // Represents a remote address to which the application can connect. + +public: + virtual Promise> connect() = 0; + // Make a new connection to this address. + // + // The address must not be a wildcard ("*"). If it is an IP address, it must have a port number. + + virtual Own listen() = 0; + // Listen for incoming connections on this address. + // + // The address must be local. + + virtual Own bindDatagramPort(); + // Open this address as a datagram (e.g. UDP) port. + // + // The address must be local. + + virtual Own clone() = 0; + // Returns an equivalent copy of this NetworkAddress. + + virtual String toString() = 0; + // Produce a human-readable string which hopefully can be passed to Network::parseAddress() + // to reproduce this address, although whether or not that works of course depends on the Network + // implementation. This should be called only to display the address to human users, who will + // hopefully know what they are able to do with it. +}; + +class Network { + // Factory for NetworkAddress instances, representing the network services offered by the + // operating system. + // + // This interface typically represents broad authority, and well-designed code should limit its + // use to high-level startup code and user interaction. Low-level APIs should accept + // NetworkAddress instances directly and work from there, if at all possible. + +public: + virtual Promise> parseAddress(StringPtr addr, uint portHint = 0) = 0; + // Construct a network address from a user-provided string. The format of the address + // strings is not specified at the API level, and application code should make no assumptions + // about them. These strings should always be provided by humans, and said humans will know + // what format to use in their particular context. + // + // `portHint`, if provided, specifies the "standard" IP port number for the application-level + // service in play. If the address turns out to be an IP address (v4 or v6), and it lacks a + // port number, this port will be used. If `addr` lacks a port number *and* `portHint` is + // omitted, then the returned address will only support listen() and bindDatagramPort() + // (not connect()), and an unused port will be chosen each time one of those methods is called. + + virtual Own getSockaddr(const void* sockaddr, uint len) = 0; + // Construct a network address from a legacy struct sockaddr. +}; + +// ======================================================================================= +// I/O Provider + +class AsyncIoProvider { + // Class which constructs asynchronous wrappers around the operating system's I/O facilities. + // + // Generally, the implementation of this interface must integrate closely with a particular + // `EventLoop` implementation. Typically, the EventLoop implementation itself will provide + // an AsyncIoProvider. + +public: + virtual OneWayPipe newOneWayPipe() = 0; + // Creates an input/output stream pair representing the ends of a one-way pipe (e.g. created with + // the pipe(2) system call). + + virtual TwoWayPipe newTwoWayPipe() = 0; + // Creates two AsyncIoStreams representing the two ends of a two-way pipe (e.g. created with + // socketpair(2) system call). Data written to one end can be read from the other. + + virtual Network& getNetwork() = 0; + // Creates a new `Network` instance representing the networks exposed by the operating system. + // + // DO NOT CALL THIS except at the highest levels of your code, ideally in the main() function. If + // you call this from low-level code, then you are preventing higher-level code from injecting an + // alternative implementation. Instead, if your code needs to use network functionality, it + // should ask for a `Network` as a constructor or method parameter, so that higher-level code can + // chose what implementation to use. The system network is essentially a singleton. See: + // http://www.object-oriented-security.org/lets-argue/singletons + // + // Code that uses the system network should not make any assumptions about what kinds of + // addresses it will parse, as this could differ across platforms. String addresses should come + // strictly from the user, who will know how to write them correctly for their system. + // + // With that said, KJ currently supports the following string address formats: + // - IPv4: "1.2.3.4", "1.2.3.4:80" + // - IPv6: "1234:5678::abcd", "[1234:5678::abcd]:80" + // - Local IP wildcard (covers both v4 and v6): "*", "*:80" + // - Symbolic names: "example.com", "example.com:80", "example.com:http", "1.2.3.4:http" + // - Unix domain: "unix:/path/to/socket" + + struct PipeThread { + // A combination of a thread and a two-way pipe that communicates with that thread. + // + // The fields are intentionally ordered so that the pipe will be destroyed (and therefore + // disconnected) before the thread is destroyed (and therefore joined). Thus if the thread + // arranges to exit when it detects disconnect, destruction should be clean. + + Own thread; + Own pipe; + }; + + virtual PipeThread newPipeThread( + Function startFunc) = 0; + // Create a new thread and set up a two-way pipe (socketpair) which can be used to communicate + // with it. One end of the pipe is passed to the thread's start function and the other end of + // the pipe is returned. The new thread also gets its own `AsyncIoProvider` instance and will + // already have an active `EventLoop` when `startFunc` is called. + // + // TODO(someday): I'm not entirely comfortable with this interface. It seems to be doing too + // much at once but I'm not sure how to cleanly break it down. + + virtual Timer& getTimer() = 0; + // Returns a `Timer` based on real time. Time does not pass while event handlers are running -- + // it only updates when the event loop polls for system events. This means that calling `now()` + // on this timer does not require a system call. + // + // This timer is not affected by changes to the system date. It is unspecified whether the timer + // continues to count while the system is suspended. +}; + +class LowLevelAsyncIoProvider { + // Similar to `AsyncIoProvider`, but represents a lower-level interface that may differ on + // different operating systems. You should prefer to use `AsyncIoProvider` over this interface + // whenever possible, as `AsyncIoProvider` is portable and friendlier to dependency-injection. + // + // On Unix, this interface can be used to import native file descriptors into the async framework. + // Different implementations of this interface might work on top of different event handling + // primitives, such as poll vs. epoll vs. kqueue vs. some higher-level event library. + // + // On Windows, this interface can be used to import native HANDLEs into the async framework. + // Different implementations of this interface might work on top of different event handling + // primitives, such as I/O completion ports vs. completion routines. + // + // TODO(port): Actually implement Windows support. + +public: + // --------------------------------------------------------------------------- + // Unix-specific stuff + + enum Flags { + // Flags controlling how to wrap a file descriptor. + + TAKE_OWNERSHIP = 1 << 0, + // The returned object should own the file descriptor, automatically closing it when destroyed. + // The close-on-exec flag will be set on the descriptor if it is not already. + // + // If this flag is not used, then the file descriptor is not automatically closed and the + // close-on-exec flag is not modified. + +#if !_WIN32 + ALREADY_CLOEXEC = 1 << 1, + // Indicates that the close-on-exec flag is known already to be set, so need not be set again. + // Only relevant when combined with TAKE_OWNERSHIP. + // + // On Linux, all system calls which yield new file descriptors have flags or variants which + // set the close-on-exec flag immediately. Unfortunately, other OS's do not. + + ALREADY_NONBLOCK = 1 << 2 + // Indicates that the file descriptor is known already to be in non-blocking mode, so the flag + // need not be set again. Otherwise, all wrap*Fd() methods will enable non-blocking mode + // automatically. + // + // On Linux, all system calls which yield new file descriptors have flags or variants which + // enable non-blocking mode immediately. Unfortunately, other OS's do not. +#endif + }; + +#if _WIN32 + typedef uintptr_t Fd; + // On Windows, the `fd` parameter to each of these methods must be a SOCKET, and must have the + // flag WSA_FLAG_OVERLAPPED (which socket() uses by default, but WSASocket() wants you to specify + // explicitly). +#else + typedef int Fd; + // On Unix, any arbitrary file descriptor is supported. +#endif + + virtual Own wrapInputFd(Fd fd, uint flags = 0) = 0; + // Create an AsyncInputStream wrapping a file descriptor. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Own wrapOutputFd(Fd fd, uint flags = 0) = 0; + // Create an AsyncOutputStream wrapping a file descriptor. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Own wrapSocketFd(Fd fd, uint flags = 0) = 0; + // Create an AsyncIoStream wrapping a socket file descriptor. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Promise> wrapConnectingSocketFd( + Fd fd, const struct sockaddr* addr, uint addrlen, uint flags = 0) = 0; + // Create an AsyncIoStream wrapping a socket and initiate a connection to the given address. + // The returned promise does not resolve until connection has completed. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Own wrapListenSocketFd(Fd fd, uint flags = 0) = 0; + // Create an AsyncIoStream wrapping a listen socket file descriptor. This socket should already + // have had `bind()` and `listen()` called on it, so it's ready for `accept()`. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Own wrapDatagramSocketFd(Fd fd, uint flags = 0); + + virtual Timer& getTimer() = 0; + // Returns a `Timer` based on real time. Time does not pass while event handlers are running -- + // it only updates when the event loop polls for system events. This means that calling `now()` + // on this timer does not require a system call. + // + // This timer is not affected by changes to the system date. It is unspecified whether the timer + // continues to count while the system is suspended. +}; + +Own newAsyncIoProvider(LowLevelAsyncIoProvider& lowLevel); +// Make a new AsyncIoProvider wrapping a `LowLevelAsyncIoProvider`. + +struct AsyncIoContext { + Own lowLevelProvider; + Own provider; + WaitScope& waitScope; + +#if _WIN32 + Win32EventPort& win32EventPort; +#else + UnixEventPort& unixEventPort; + // TEMPORARY: Direct access to underlying UnixEventPort, mainly for waiting on signals. This + // field will go away at some point when we have a chance to improve these interfaces. +#endif +}; + +AsyncIoContext setupAsyncIo(); +// Convenience method which sets up the current thread with everything it needs to do async I/O. +// The returned objects contain an `EventLoop` which is wrapping an appropriate `EventPort` for +// doing I/O on the host system, so everything is ready for the thread to start making async calls +// and waiting on promises. +// +// You would typically call this in your main() loop or in the start function of a thread. +// Example: +// +// int main() { +// auto ioContext = kj::setupAsyncIo(); +// +// // Now we can call an async function. +// Promise textPromise = getHttp(*ioContext.provider, "http://example.com"); +// +// // And we can wait for the promise to complete. Note that you can only use `wait()` +// // from the top level, not from inside a promise callback. +// String text = textPromise.wait(ioContext.waitScope); +// print(text); +// return 0; +// } +// +// WARNING: An AsyncIoContext can only be used in the thread and process that created it. In +// particular, note that after a fork(), an AsyncIoContext created in the parent process will +// not work correctly in the child, even if the parent ceases to use its copy. In particular +// note that this means that server processes which daemonize themselves at startup must wait +// until after daemonization to create an AsyncIoContext. + +// ======================================================================================= +// inline implementation details + +inline AncillaryMessage::AncillaryMessage( + int level, int type, ArrayPtr data) + : level(level), type(type), data(data) {} + +inline int AncillaryMessage::getLevel() const { return level; } +inline int AncillaryMessage::getType() const { return type; } + +template +inline Maybe AncillaryMessage::as() { + if (data.size() >= sizeof(T)) { + return *reinterpret_cast(data.begin()); + } else { + return nullptr; + } +} + +template +inline ArrayPtr AncillaryMessage::asArray() { + return arrayPtr(reinterpret_cast(data.begin()), data.size() / sizeof(T)); +} + +} // namespace kj + +#endif // KJ_ASYNC_IO_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/async-prelude.h --- a/win32-mingw/include/kj/async-prelude.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/async-prelude.h Tue May 23 09:16:54 2017 +0100 @@ -1,218 +1,218 @@ -// 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 a bunch of internal declarations that must appear before async.h can start. -// We don't define these directly in async.h because it makes the file hard to read. - -#ifndef KJ_ASYNC_PRELUDE_H_ -#define KJ_ASYNC_PRELUDE_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "exception.h" -#include "tuple.h" - -namespace kj { - -class EventLoop; -template -class Promise; -class WaitScope; - -template -Promise> joinPromises(Array>&& promises); -Promise joinPromises(Array>&& promises); - -namespace _ { // private - -template struct JoinPromises_ { typedef T Type; }; -template struct JoinPromises_> { typedef T Type; }; - -template -using JoinPromises = typename JoinPromises_::Type; -// If T is Promise, resolves to U, otherwise resolves to T. -// -// TODO(cleanup): Rename to avoid confusion with joinPromises() call which is completely -// unrelated. - -class PropagateException { - // A functor which accepts a kj::Exception as a parameter and returns a broken promise of - // arbitrary type which simply propagates the exception. -public: - class Bottom { - public: - Bottom(Exception&& exception): exception(kj::mv(exception)) {} - - Exception asException() { return kj::mv(exception); } - - private: - Exception exception; - }; - - Bottom operator()(Exception&& e) { - return Bottom(kj::mv(e)); - } - Bottom operator()(const Exception& e) { - return Bottom(kj::cp(e)); - } -}; - -template -struct ReturnType_ { typedef decltype(instance()(instance())) Type; }; -template -struct ReturnType_ { typedef decltype(instance()()) Type; }; - -template -using ReturnType = typename ReturnType_::Type; -// The return type of functor Func given a parameter of type T, with the special exception that if -// T is void, this is the return type of Func called with no arguments. - -template struct SplitTuplePromise_ { typedef Promise Type; }; -template -struct SplitTuplePromise_> { - typedef kj::Tuple>...> Type; -}; - -template -using SplitTuplePromise = typename SplitTuplePromise_::Type; -// T -> Promise -// Tuple -> Tuple> - -struct Void {}; -// Application code should NOT refer to this! See `kj::READY_NOW` instead. - -template struct FixVoid_ { typedef T Type; }; -template <> struct FixVoid_ { typedef Void Type; }; -template using FixVoid = typename FixVoid_::Type; -// FixVoid is just T unless T is void in which case it is _::Void (an empty struct). - -template struct UnfixVoid_ { typedef T Type; }; -template <> struct UnfixVoid_ { typedef void Type; }; -template using UnfixVoid = typename UnfixVoid_::Type; -// UnfixVoid is the opposite of FixVoid. - -template -struct MaybeVoidCaller { - // Calls the function converting a Void input to an empty parameter list and a void return - // value to a Void output. - - template - static inline Out apply(Func& func, In&& in) { - return func(kj::mv(in)); - } -}; -template -struct MaybeVoidCaller { - template - static inline Out apply(Func& func, In& in) { - return func(in); - } -}; -template -struct MaybeVoidCaller { - template - static inline Out apply(Func& func, Void&& in) { - return func(); - } -}; -template -struct MaybeVoidCaller { - template - static inline Void apply(Func& func, In&& in) { - func(kj::mv(in)); - return Void(); - } -}; -template -struct MaybeVoidCaller { - template - static inline Void apply(Func& func, In& in) { - func(in); - return Void(); - } -}; -template <> -struct MaybeVoidCaller { - template - static inline Void apply(Func& func, Void&& in) { - func(); - return Void(); - } -}; - -template -inline T&& returnMaybeVoid(T&& t) { - return kj::fwd(t); -} -inline void returnMaybeVoid(Void&& v) {} - -class ExceptionOrValue; -class PromiseNode; -class ChainPromiseNode; -template -class ForkHub; - -class TaskSetImpl; - -class Event; - -class PromiseBase { -public: - kj::String trace(); - // Dump debug info about this promise. - -private: - Own node; - - PromiseBase() = default; - PromiseBase(Own&& node): node(kj::mv(node)) {} - - friend class kj::EventLoop; - friend class ChainPromiseNode; - template - friend class kj::Promise; - friend class TaskSetImpl; - template - friend Promise> kj::joinPromises(Array>&& promises); - friend Promise kj::joinPromises(Array>&& promises); -}; - -void detach(kj::Promise&& promise); -void waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, WaitScope& waitScope); -Promise yield(); -Own neverDone(); - -class NeverDone { -public: - template - operator Promise() const { - return Promise(false, neverDone()); - } - - KJ_NORETURN(void wait(WaitScope& waitScope) const); -}; - -} // namespace _ (private) -} // namespace kj - -#endif // KJ_ASYNC_PRELUDE_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 a bunch of internal declarations that must appear before async.h can start. +// We don't define these directly in async.h because it makes the file hard to read. + +#ifndef KJ_ASYNC_PRELUDE_H_ +#define KJ_ASYNC_PRELUDE_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "exception.h" +#include "tuple.h" + +namespace kj { + +class EventLoop; +template +class Promise; +class WaitScope; + +template +Promise> joinPromises(Array>&& promises); +Promise joinPromises(Array>&& promises); + +namespace _ { // private + +template struct JoinPromises_ { typedef T Type; }; +template struct JoinPromises_> { typedef T Type; }; + +template +using JoinPromises = typename JoinPromises_::Type; +// If T is Promise, resolves to U, otherwise resolves to T. +// +// TODO(cleanup): Rename to avoid confusion with joinPromises() call which is completely +// unrelated. + +class PropagateException { + // A functor which accepts a kj::Exception as a parameter and returns a broken promise of + // arbitrary type which simply propagates the exception. +public: + class Bottom { + public: + Bottom(Exception&& exception): exception(kj::mv(exception)) {} + + Exception asException() { return kj::mv(exception); } + + private: + Exception exception; + }; + + Bottom operator()(Exception&& e) { + return Bottom(kj::mv(e)); + } + Bottom operator()(const Exception& e) { + return Bottom(kj::cp(e)); + } +}; + +template +struct ReturnType_ { typedef decltype(instance()(instance())) Type; }; +template +struct ReturnType_ { typedef decltype(instance()()) Type; }; + +template +using ReturnType = typename ReturnType_::Type; +// The return type of functor Func given a parameter of type T, with the special exception that if +// T is void, this is the return type of Func called with no arguments. + +template struct SplitTuplePromise_ { typedef Promise Type; }; +template +struct SplitTuplePromise_> { + typedef kj::Tuple>...> Type; +}; + +template +using SplitTuplePromise = typename SplitTuplePromise_::Type; +// T -> Promise +// Tuple -> Tuple> + +struct Void {}; +// Application code should NOT refer to this! See `kj::READY_NOW` instead. + +template struct FixVoid_ { typedef T Type; }; +template <> struct FixVoid_ { typedef Void Type; }; +template using FixVoid = typename FixVoid_::Type; +// FixVoid is just T unless T is void in which case it is _::Void (an empty struct). + +template struct UnfixVoid_ { typedef T Type; }; +template <> struct UnfixVoid_ { typedef void Type; }; +template using UnfixVoid = typename UnfixVoid_::Type; +// UnfixVoid is the opposite of FixVoid. + +template +struct MaybeVoidCaller { + // Calls the function converting a Void input to an empty parameter list and a void return + // value to a Void output. + + template + static inline Out apply(Func& func, In&& in) { + return func(kj::mv(in)); + } +}; +template +struct MaybeVoidCaller { + template + static inline Out apply(Func& func, In& in) { + return func(in); + } +}; +template +struct MaybeVoidCaller { + template + static inline Out apply(Func& func, Void&& in) { + return func(); + } +}; +template +struct MaybeVoidCaller { + template + static inline Void apply(Func& func, In&& in) { + func(kj::mv(in)); + return Void(); + } +}; +template +struct MaybeVoidCaller { + template + static inline Void apply(Func& func, In& in) { + func(in); + return Void(); + } +}; +template <> +struct MaybeVoidCaller { + template + static inline Void apply(Func& func, Void&& in) { + func(); + return Void(); + } +}; + +template +inline T&& returnMaybeVoid(T&& t) { + return kj::fwd(t); +} +inline void returnMaybeVoid(Void&& v) {} + +class ExceptionOrValue; +class PromiseNode; +class ChainPromiseNode; +template +class ForkHub; + +class TaskSetImpl; + +class Event; + +class PromiseBase { +public: + kj::String trace(); + // Dump debug info about this promise. + +private: + Own node; + + PromiseBase() = default; + PromiseBase(Own&& node): node(kj::mv(node)) {} + + friend class kj::EventLoop; + friend class ChainPromiseNode; + template + friend class kj::Promise; + friend class TaskSetImpl; + template + friend Promise> kj::joinPromises(Array>&& promises); + friend Promise kj::joinPromises(Array>&& promises); +}; + +void detach(kj::Promise&& promise); +void waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, WaitScope& waitScope); +Promise yield(); +Own neverDone(); + +class NeverDone { +public: + template + operator Promise() const { + return Promise(false, neverDone()); + } + + KJ_NORETURN(void wait(WaitScope& waitScope) const); +}; + +} // namespace _ (private) +} // namespace kj + +#endif // KJ_ASYNC_PRELUDE_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/async-unix.h --- a/win32-mingw/include/kj/async-unix.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/async-unix.h Tue May 23 09:16:54 2017 +0100 @@ -1,273 +1,274 @@ -// 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. - -#ifndef KJ_ASYNC_UNIX_H_ -#define KJ_ASYNC_UNIX_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "async.h" -#include "time.h" -#include "vector.h" -#include "io.h" -#include - -#if __linux__ && !__BIONIC__ && !defined(KJ_USE_EPOLL) -// Default to epoll on Linux, except on Bionic (Android) which doesn't have signalfd.h. -#define KJ_USE_EPOLL 1 -#endif - -namespace kj { - -class UnixEventPort: public EventPort { - // An EventPort implementation which can wait for events on file descriptors as well as signals. - // This API only makes sense on Unix. - // - // The implementation uses `poll()` or possibly a platform-specific API (e.g. epoll, kqueue). - // To also wait on signals without race conditions, the implementation may block signals until - // just before `poll()` while using a signal handler which `siglongjmp()`s back to just before - // the signal was unblocked, or it may use a nicer platform-specific API like signalfd. - // - // The implementation reserves a signal for internal use. By default, it uses SIGUSR1. If you - // need to use SIGUSR1 for something else, you must offer a different signal by calling - // setReservedSignal() at startup. - // - // WARNING: A UnixEventPort can only be used in the thread and process that created it. In - // particular, note that after a fork(), a UnixEventPort created in the parent process will - // not work correctly in the child, even if the parent ceases to use its copy. In particular - // note that this means that server processes which daemonize themselves at startup must wait - // until after daemonization to create a UnixEventPort. - -public: - UnixEventPort(); - ~UnixEventPort() noexcept(false); - - class FdObserver; - // Class that watches an fd for readability or writability. See definition below. - - Promise onSignal(int signum); - // When the given signal is delivered to this thread, return the corresponding siginfo_t. - // The signal must have been captured using `captureSignal()`. - // - // If `onSignal()` has not been called, the signal will remain blocked in this thread. - // Therefore, a signal which arrives before `onSignal()` was called will not be "missed" -- the - // next call to 'onSignal()' will receive it. Also, you can control which thread receives a - // process-wide signal by only calling `onSignal()` on that thread's event loop. - // - // The result of waiting on the same signal twice at once is undefined. - - static void captureSignal(int signum); - // Arranges for the given signal to be captured and handled via UnixEventPort, so that you may - // then pass it to `onSignal()`. This method is static because it registers a signal handler - // which applies process-wide. If any other threads exist in the process when `captureSignal()` - // is called, you *must* set the signal mask in those threads to block this signal, otherwise - // terrible things will happen if the signal happens to be delivered to those threads. If at - // all possible, call `captureSignal()` *before* creating threads, so that threads you create in - // the future will inherit the proper signal mask. - // - // To un-capture a signal, simply install a different signal handler and then un-block it from - // the signal mask. - - static void setReservedSignal(int signum); - // Sets the signal number which `UnixEventPort` reserves for internal use. If your application - // needs to use SIGUSR1, call this at startup (before any calls to `captureSignal()` and before - // constructing an `UnixEventPort`) to offer a different signal. - - TimePoint steadyTime() { return frozenSteadyTime; } - Promise atSteadyTime(TimePoint time); - - // implements EventPort ------------------------------------------------------ - bool wait() override; - bool poll() override; - void wake() const override; - -private: - struct TimerSet; // Defined in source file to avoid STL include. - class TimerPromiseAdapter; - class SignalPromiseAdapter; - - Own timers; - TimePoint frozenSteadyTime; - - SignalPromiseAdapter* signalHead = nullptr; - SignalPromiseAdapter** signalTail = &signalHead; - - TimePoint currentSteadyTime(); - void processTimers(); - void gotSignal(const siginfo_t& siginfo); - - friend class TimerPromiseAdapter; - -#if KJ_USE_EPOLL - AutoCloseFd epollFd; - AutoCloseFd signalFd; - AutoCloseFd eventFd; // Used for cross-thread wakeups. - - sigset_t signalFdSigset; - // Signal mask as currently set on the signalFd. Tracked so we can detect whether or not it - // needs updating. - - bool doEpollWait(int timeout); - -#else - class PollContext; - - FdObserver* observersHead = nullptr; - FdObserver** observersTail = &observersHead; - - unsigned long long threadId; // actually pthread_t -#endif -}; - -class UnixEventPort::FdObserver { - // Object which watches a file descriptor to determine when it is readable or writable. - // - // For listen sockets, "readable" means that there is a connection to accept(). For everything - // else, it means that read() (or recv()) will return data. - // - // The presence of out-of-band data should NOT fire this event. However, the event may - // occasionally fire spuriously (when there is actually no data to read), and one thing that can - // cause such spurious events is the arrival of OOB data on certain platforms whose event - // interfaces fail to distinguish between regular and OOB data (e.g. Mac OSX). - // - // WARNING: The exact behavior of this class differs across systems, since event interfaces - // vary wildly. Be sure to read the documentation carefully and avoid depending on unspecified - // behavior. If at all possible, use the higher-level AsyncInputStream interface instead. - -public: - enum Flags { - OBSERVE_READ = 1, - OBSERVE_WRITE = 2, - OBSERVE_URGENT = 4, - OBSERVE_READ_WRITE = OBSERVE_READ | OBSERVE_WRITE - }; - - FdObserver(UnixEventPort& eventPort, int fd, uint flags); - // Begin watching the given file descriptor for readability. Only one ReadObserver may exist - // for a given file descriptor at a time. - - ~FdObserver() noexcept(false); - - KJ_DISALLOW_COPY(FdObserver); - - Promise whenBecomesReadable(); - // Resolves the next time the file descriptor transitions from having no data to read to having - // some data to read. - // - // KJ uses "edge-triggered" event notification whenever possible. As a result, it is an error - // to call this method when there is already data in the read buffer which has been there since - // prior to the last turn of the event loop or prior to creation FdWatcher. In this case, it is - // unspecified whether the promise will ever resolve -- it depends on the underlying event - // mechanism being used. - // - // In order to avoid this problem, make sure that you only call `whenBecomesReadable()` - // only at times when you know the buffer is empty. You know this for sure when one of the - // following happens: - // * read() or recv() fails with EAGAIN or EWOULDBLOCK. (You MUST have non-blocking mode - // enabled on the fd!) - // * The file descriptor is a regular byte-oriented object (like a socket or pipe), - // read() or recv() returns fewer than the number of bytes requested, and `atEndHint()` - // returns false. This can only happen if the buffer is empty but EOF is not reached. (Note, - // though, that for record-oriented file descriptors like Linux's inotify interface, this - // rule does not hold, because it could simply be that the next record did not fit into the - // space available.) - // - // It is an error to call `whenBecomesReadable()` again when the promise returned previously - // has not yet resolved. If you do this, the previous promise may throw an exception. - - inline Maybe atEndHint() { return atEnd; } - // Returns true if the event system has indicated that EOF has been received. There may still - // be data in the read buffer, but once that is gone, there's nothing left. - // - // Returns false if the event system has indicated that EOF had NOT been received as of the - // last turn of the event loop. - // - // Returns nullptr if the event system does not know whether EOF has been reached. In this - // case, the only way to know for sure is to call read() or recv() and check if it returns - // zero. - // - // This hint may be useful as an optimization to avoid an unnecessary system call. - - Promise whenBecomesWritable(); - // Resolves the next time the file descriptor transitions from having no space available in the - // write buffer to having some space available. - // - // KJ uses "edge-triggered" event notification whenever possible. As a result, it is an error - // to call this method when there is already space in the write buffer which has been there - // since prior to the last turn of the event loop or prior to creation FdWatcher. In this case, - // it is unspecified whether the promise will ever resolve -- it depends on the underlying - // event mechanism being used. - // - // In order to avoid this problem, make sure that you only call `whenBecomesWritable()` - // only at times when you know the buffer is full. You know this for sure when one of the - // following happens: - // * write() or send() fails with EAGAIN or EWOULDBLOCK. (You MUST have non-blocking mode - // enabled on the fd!) - // * write() or send() succeeds but accepts fewer than the number of bytes provided. This can - // only happen if the buffer is full. - // - // It is an error to call `whenBecomesWritable()` again when the promise returned previously - // has not yet resolved. If you do this, the previous promise may throw an exception. - - Promise whenUrgentDataAvailable(); - // Resolves the next time the file descriptor's read buffer contains "urgent" data. - // - // The conditions for availability of urgent data are specific to the file descriptor's - // underlying implementation. - // - // It is an error to call `whenUrgentDataAvailable()` again when the promise returned previously - // has not yet resolved. If you do this, the previous promise may throw an exception. - // - // WARNING: This has some known weird behavior on macOS. See - // https://github.com/sandstorm-io/capnproto/issues/374. - -private: - UnixEventPort& eventPort; - int fd; - uint flags; - - kj::Maybe>> readFulfiller; - kj::Maybe>> writeFulfiller; - kj::Maybe>> urgentFulfiller; - // Replaced each time `whenBecomesReadable()` or `whenBecomesWritable()` is called. Reverted to - // null every time an event is fired. - - Maybe atEnd; - - void fire(short events); - -#if !KJ_USE_EPOLL - FdObserver* next; - FdObserver** prev; - // Linked list of observers which currently have a non-null readFulfiller or writeFulfiller. - // If `prev` is null then the observer is not currently in the list. - - short getEventMask(); -#endif - - friend class UnixEventPort; -}; - -} // namespace kj - -#endif // KJ_ASYNC_UNIX_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. + +#ifndef KJ_ASYNC_UNIX_H_ +#define KJ_ASYNC_UNIX_H_ + +#if _WIN32 +#error "This file is Unix-specific. On Windows, include async-win32.h instead." +#endif + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "async.h" +#include "time.h" +#include "vector.h" +#include "io.h" +#include + +#if __linux__ && !__BIONIC__ && !defined(KJ_USE_EPOLL) +// Default to epoll on Linux, except on Bionic (Android) which doesn't have signalfd.h. +#define KJ_USE_EPOLL 1 +#endif + +namespace kj { + +class UnixEventPort: public EventPort { + // An EventPort implementation which can wait for events on file descriptors as well as signals. + // This API only makes sense on Unix. + // + // The implementation uses `poll()` or possibly a platform-specific API (e.g. epoll, kqueue). + // To also wait on signals without race conditions, the implementation may block signals until + // just before `poll()` while using a signal handler which `siglongjmp()`s back to just before + // the signal was unblocked, or it may use a nicer platform-specific API like signalfd. + // + // The implementation reserves a signal for internal use. By default, it uses SIGUSR1. If you + // need to use SIGUSR1 for something else, you must offer a different signal by calling + // setReservedSignal() at startup. + // + // WARNING: A UnixEventPort can only be used in the thread and process that created it. In + // particular, note that after a fork(), a UnixEventPort created in the parent process will + // not work correctly in the child, even if the parent ceases to use its copy. In particular + // note that this means that server processes which daemonize themselves at startup must wait + // until after daemonization to create a UnixEventPort. + +public: + UnixEventPort(); + ~UnixEventPort() noexcept(false); + + class FdObserver; + // Class that watches an fd for readability or writability. See definition below. + + Promise onSignal(int signum); + // When the given signal is delivered to this thread, return the corresponding siginfo_t. + // The signal must have been captured using `captureSignal()`. + // + // If `onSignal()` has not been called, the signal will remain blocked in this thread. + // Therefore, a signal which arrives before `onSignal()` was called will not be "missed" -- the + // next call to 'onSignal()' will receive it. Also, you can control which thread receives a + // process-wide signal by only calling `onSignal()` on that thread's event loop. + // + // The result of waiting on the same signal twice at once is undefined. + + static void captureSignal(int signum); + // Arranges for the given signal to be captured and handled via UnixEventPort, so that you may + // then pass it to `onSignal()`. This method is static because it registers a signal handler + // which applies process-wide. If any other threads exist in the process when `captureSignal()` + // is called, you *must* set the signal mask in those threads to block this signal, otherwise + // terrible things will happen if the signal happens to be delivered to those threads. If at + // all possible, call `captureSignal()` *before* creating threads, so that threads you create in + // the future will inherit the proper signal mask. + // + // To un-capture a signal, simply install a different signal handler and then un-block it from + // the signal mask. + + static void setReservedSignal(int signum); + // Sets the signal number which `UnixEventPort` reserves for internal use. If your application + // needs to use SIGUSR1, call this at startup (before any calls to `captureSignal()` and before + // constructing an `UnixEventPort`) to offer a different signal. + + Timer& getTimer() { return timerImpl; } + + // implements EventPort ------------------------------------------------------ + bool wait() override; + bool poll() override; + void wake() const override; + +private: + struct TimerSet; // Defined in source file to avoid STL include. + class TimerPromiseAdapter; + class SignalPromiseAdapter; + + TimerImpl timerImpl; + + SignalPromiseAdapter* signalHead = nullptr; + SignalPromiseAdapter** signalTail = &signalHead; + + TimePoint readClock(); + void gotSignal(const siginfo_t& siginfo); + + friend class TimerPromiseAdapter; + +#if KJ_USE_EPOLL + AutoCloseFd epollFd; + AutoCloseFd signalFd; + AutoCloseFd eventFd; // Used for cross-thread wakeups. + + sigset_t signalFdSigset; + // Signal mask as currently set on the signalFd. Tracked so we can detect whether or not it + // needs updating. + + bool doEpollWait(int timeout); + +#else + class PollContext; + + FdObserver* observersHead = nullptr; + FdObserver** observersTail = &observersHead; + + unsigned long long threadId; // actually pthread_t +#endif +}; + +class UnixEventPort::FdObserver { + // Object which watches a file descriptor to determine when it is readable or writable. + // + // For listen sockets, "readable" means that there is a connection to accept(). For everything + // else, it means that read() (or recv()) will return data. + // + // The presence of out-of-band data should NOT fire this event. However, the event may + // occasionally fire spuriously (when there is actually no data to read), and one thing that can + // cause such spurious events is the arrival of OOB data on certain platforms whose event + // interfaces fail to distinguish between regular and OOB data (e.g. Mac OSX). + // + // WARNING: The exact behavior of this class differs across systems, since event interfaces + // vary wildly. Be sure to read the documentation carefully and avoid depending on unspecified + // behavior. If at all possible, use the higher-level AsyncInputStream interface instead. + +public: + enum Flags { + OBSERVE_READ = 1, + OBSERVE_WRITE = 2, + OBSERVE_URGENT = 4, + OBSERVE_READ_WRITE = OBSERVE_READ | OBSERVE_WRITE + }; + + FdObserver(UnixEventPort& eventPort, int fd, uint flags); + // Begin watching the given file descriptor for readability. Only one ReadObserver may exist + // for a given file descriptor at a time. + + ~FdObserver() noexcept(false); + + KJ_DISALLOW_COPY(FdObserver); + + Promise whenBecomesReadable(); + // Resolves the next time the file descriptor transitions from having no data to read to having + // some data to read. + // + // KJ uses "edge-triggered" event notification whenever possible. As a result, it is an error + // to call this method when there is already data in the read buffer which has been there since + // prior to the last turn of the event loop or prior to creation FdWatcher. In this case, it is + // unspecified whether the promise will ever resolve -- it depends on the underlying event + // mechanism being used. + // + // In order to avoid this problem, make sure that you only call `whenBecomesReadable()` + // only at times when you know the buffer is empty. You know this for sure when one of the + // following happens: + // * read() or recv() fails with EAGAIN or EWOULDBLOCK. (You MUST have non-blocking mode + // enabled on the fd!) + // * The file descriptor is a regular byte-oriented object (like a socket or pipe), + // read() or recv() returns fewer than the number of bytes requested, and `atEndHint()` + // returns false. This can only happen if the buffer is empty but EOF is not reached. (Note, + // though, that for record-oriented file descriptors like Linux's inotify interface, this + // rule does not hold, because it could simply be that the next record did not fit into the + // space available.) + // + // It is an error to call `whenBecomesReadable()` again when the promise returned previously + // has not yet resolved. If you do this, the previous promise may throw an exception. + + inline Maybe atEndHint() { return atEnd; } + // Returns true if the event system has indicated that EOF has been received. There may still + // be data in the read buffer, but once that is gone, there's nothing left. + // + // Returns false if the event system has indicated that EOF had NOT been received as of the + // last turn of the event loop. + // + // Returns nullptr if the event system does not know whether EOF has been reached. In this + // case, the only way to know for sure is to call read() or recv() and check if it returns + // zero. + // + // This hint may be useful as an optimization to avoid an unnecessary system call. + + Promise whenBecomesWritable(); + // Resolves the next time the file descriptor transitions from having no space available in the + // write buffer to having some space available. + // + // KJ uses "edge-triggered" event notification whenever possible. As a result, it is an error + // to call this method when there is already space in the write buffer which has been there + // since prior to the last turn of the event loop or prior to creation FdWatcher. In this case, + // it is unspecified whether the promise will ever resolve -- it depends on the underlying + // event mechanism being used. + // + // In order to avoid this problem, make sure that you only call `whenBecomesWritable()` + // only at times when you know the buffer is full. You know this for sure when one of the + // following happens: + // * write() or send() fails with EAGAIN or EWOULDBLOCK. (You MUST have non-blocking mode + // enabled on the fd!) + // * write() or send() succeeds but accepts fewer than the number of bytes provided. This can + // only happen if the buffer is full. + // + // It is an error to call `whenBecomesWritable()` again when the promise returned previously + // has not yet resolved. If you do this, the previous promise may throw an exception. + + Promise whenUrgentDataAvailable(); + // Resolves the next time the file descriptor's read buffer contains "urgent" data. + // + // The conditions for availability of urgent data are specific to the file descriptor's + // underlying implementation. + // + // It is an error to call `whenUrgentDataAvailable()` again when the promise returned previously + // has not yet resolved. If you do this, the previous promise may throw an exception. + // + // WARNING: This has some known weird behavior on macOS. See + // https://github.com/sandstorm-io/capnproto/issues/374. + +private: + UnixEventPort& eventPort; + int fd; + uint flags; + + kj::Maybe>> readFulfiller; + kj::Maybe>> writeFulfiller; + kj::Maybe>> urgentFulfiller; + // Replaced each time `whenBecomesReadable()` or `whenBecomesWritable()` is called. Reverted to + // null every time an event is fired. + + Maybe atEnd; + + void fire(short events); + +#if !KJ_USE_EPOLL + FdObserver* next; + FdObserver** prev; + // Linked list of observers which currently have a non-null readFulfiller or writeFulfiller. + // If `prev` is null then the observer is not currently in the list. + + short getEventMask(); +#endif + + friend class UnixEventPort; +}; + +} // namespace kj + +#endif // KJ_ASYNC_UNIX_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/async-win32.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/async-win32.h Tue May 23 09:16:54 2017 +0100 @@ -0,0 +1,234 @@ +// Copyright (c) 2016 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. + +#ifndef KJ_ASYNC_WIN32_H_ +#define KJ_ASYNC_WIN32_H_ + +#if !_WIN32 +#error "This file is Windows-specific. On Unix, include async-unix.h instead." +#endif + +#include "async.h" +#include "time.h" +#include "io.h" +#include +#include + +// Include windows.h as lean as possible. (If you need more of the Windows API for your app, +// #include windows.h yourself before including this header.) +#define WIN32_LEAN_AND_MEAN 1 +#define NOSERVICE 1 +#define NOMCX 1 +#define NOIME 1 +#include +#include "windows-sanity.h" + +namespace kj { + +class Win32EventPort: public EventPort { + // Abstract base interface for EventPorts that can listen on Win32 event types. Due to the + // absurd complexity of the Win32 API, it's not possible to standardize on a single + // implementation of EventPort. In particular, there is no way for a single thread to use I/O + // completion ports (the most efficient way of handling I/O) while at the same time waiting for + // signalable handles or UI messages. + // + // Note that UI messages are not supported at all by this interface because the message queue + // is implemented by user32.dll and we want libkj to depend only on kernel32.dll. A separate + // compat library could provide a Win32EventPort implementation that works with the UI message + // queue. + +public: + // --------------------------------------------------------------------------- + // overlapped I/O + + struct IoResult { + DWORD errorCode; + DWORD bytesTransferred; + }; + + class IoOperation { + public: + virtual LPOVERLAPPED getOverlapped() = 0; + // Gets the OVERLAPPED structure to pass to the Win32 I/O call. Do NOT modify it; just pass it + // on. + + virtual Promise onComplete() = 0; + // After making the Win32 call, if the return value indicates that the operation was + // successfully queued (i.e. the completion event will definitely occur), call this to wait + // for completion. + // + // You MUST call this if the operation was successfully queued, and you MUST NOT call this + // otherwise. If the Win32 call failed (without queuing any operation or event) then you should + // simply drop the IoOperation object. + // + // Dropping the returned Promise cancels the operation via Win32's CancelIoEx(). The destructor + // will wait for the cancellation to complete, such that after dropping the proimse it is safe + // to free the buffer that the operation was reading from / writing to. + // + // You may safely drop the `IoOperation` while still waiting for this promise. You may not, + // however, drop the `IoObserver`. + }; + + class IoObserver { + public: + virtual Own newOperation(uint64_t offset) = 0; + // Begin an I/O operation. For file operations, `offset` is the offset within the file at + // which the operation will start. For stream operations, `offset` is ignored. + }; + + virtual Own observeIo(HANDLE handle) = 0; + // Given a handle which supports overlapped I/O, arrange to receive I/O completion events via + // this EventPort. + // + // Different Win32EventPort implementations may handle this in different ways, such as by using + // completion routines (APCs) or by using I/O completion ports. The caller should not assume + // any particular technique. + // + // WARNING: It is only safe to call observeIo() on a particular handle once during its lifetime. + // You cannot observe the same handle from multiple Win32EventPorts, even if not at the same + // time. This is because the Win32 API provides no way to disassociate a handle from an I/O + // completion port once it is associated. + + // --------------------------------------------------------------------------- + // signalable handles + // + // Warning: Due to limitations in the Win32 API, implementations of EventPort may be forced to + // spawn additional threads to wait for signaled objects. This is necessary if the EventPort + // implementation is based on I/O completion ports, or if you need to wait on more than 64 + // handles at once. + + class SignalObserver { + public: + virtual Promise onSignaled() = 0; + // Returns a promise that completes the next time the handle enters the signaled state. + // + // Depending on the type of handle, the handle may automatically be reset to a non-signaled + // state before the promise resolves. The underlying implementaiton uses WaitForSingleObject() + // or an equivalent wait call, so check the documentation for that to understand the semantics. + // + // If the handle is a mutex and it is abandoned without being unlocked, the promise breaks with + // an exception. + + virtual Promise onSignaledOrAbandoned() = 0; + // Like onSingaled(), but instead of throwing when a mutex is abandoned, resolves to `true`. + // Resolves to `false` for non-abandoned signals. + }; + + virtual Own observeSignalState(HANDLE handle) = 0; + // Given a handle that supports waiting for it to become "signaled" via WaitForSingleObject(), + // return an object that can wait for this state using the EventPort. + + // --------------------------------------------------------------------------- + // APCs + + virtual void allowApc() = 0; + // If this is ever called, the Win32EventPort will switch modes so that APCs can be scheduled + // on the thread, e.g. through the Win32 QueueUserAPC() call. In the future, this may be enabled + // by default. However, as of this writing, Wine does not support the necessary + // GetQueuedCompletionStatusEx() call, thus allowApc() breaks Wine support. (Tested on Wine + // 1.8.7.) + // + // If the event port implementation can't support APCs for some reason, this throws. + + // --------------------------------------------------------------------------- + // time + + virtual Timer& getTimer() = 0; +}; + +class Win32WaitObjectThreadPool { + // Helper class that implements Win32EventPort::observeSignalState() by spawning additional + // threads as needed to perform the actual waiting. + // + // This class is intended to be used to assist in building Win32EventPort implementations. + +public: + Win32WaitObjectThreadPool(uint mainThreadCount = 0); + // `mainThreadCount` indicates the number of objects the main thread is able to listen on + // directly. Typically this would be zero (e.g. if the main thread watches an I/O completion + // port) or MAXIMUM_WAIT_OBJECTS (e.g. if the main thread is a UI thread but can use + // MsgWaitForMultipleObjectsEx() to wait on some handles at the same time as messages). + + Own observeSignalState(HANDLE handle); + // Implemetns Win32EventPort::observeSignalState(). + + uint prepareMainThreadWait(HANDLE* handles[]); + // Call immediately before invoking WaitForMultipleObjects() or similar in the main thread. + // Fills in `handles` with the handle pointers to wait on, and returns the number of handles + // in this array. (The array should be allocated to be at least the size passed to the + // constructor). + // + // There's no need to call this if `mainThreadCount` as passed to the constructor was zero. + + bool finishedMainThreadWait(DWORD returnCode); + // Call immediately after invoking WaitForMultipleObjects() or similar in the main thread, + // passing the value returend by that call. Returns true if the event indicated by `returnCode` + // has been handled (i.e. it was WAIT_OBJECT_n or WAIT_ABANDONED_n where n is in-range for the + // last call to prepareMainThreadWait()). +}; + +class Win32IocpEventPort final: public Win32EventPort { + // An EventPort implementation which uses Windows I/O completion ports to listen for events. + // + // With this implementation, observeSignalState() requires spawning a separate thread. + +public: + Win32IocpEventPort(); + ~Win32IocpEventPort() noexcept(false); + + // implements EventPort ------------------------------------------------------ + bool wait() override; + bool poll() override; + void wake() const override; + + // implements Win32IocpEventPort --------------------------------------------- + Own observeIo(HANDLE handle) override; + Own observeSignalState(HANDLE handle) override; + Timer& getTimer() override { return timerImpl; } + void allowApc() override { isAllowApc = true; } + +private: + class IoPromiseAdapter; + class IoOperationImpl; + class IoObserverImpl; + + AutoCloseHandle iocp; + AutoCloseHandle thread; + Win32WaitObjectThreadPool waitThreads; + TimerImpl timerImpl; + mutable std::atomic sentWake {false}; + bool isAllowApc = false; + + static TimePoint readClock(); + + void waitIocp(DWORD timeoutMs); + // Wait on the I/O completion port for up to timeoutMs and pump events. Does not advance the + // timer; caller must do that. + + bool receivedWake(); + + static AutoCloseHandle newIocpHandle(); + static AutoCloseHandle openCurrentThread(); +}; + +} // namespace kj + +#endif // KJ_ASYNC_WIN32_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/async.h --- a/win32-mingw/include/kj/async.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/async.h Tue May 23 09:16:54 2017 +0100 @@ -1,682 +1,682 @@ -// 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. - -#ifndef KJ_ASYNC_H_ -#define KJ_ASYNC_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "async-prelude.h" -#include "exception.h" -#include "refcount.h" - -namespace kj { - -class EventLoop; -class WaitScope; - -template -class Promise; -template -class ForkedPromise; -template -class PromiseFulfiller; -template -struct PromiseFulfillerPair; - -template -using PromiseForResult = Promise<_::JoinPromises<_::ReturnType>>; -// Evaluates to the type of Promise for the result of calling functor type Func with parameter type -// T. If T is void, then the promise is for the result of calling Func with no arguments. If -// Func itself returns a promise, the promises are joined, so you never get Promise>. - -// ======================================================================================= -// Promises - -template -class Promise: protected _::PromiseBase { - // The basic primitive of asynchronous computation in KJ. Similar to "futures", but designed - // specifically for event loop concurrency. Similar to E promises and JavaScript Promises/A. - // - // A Promise represents a promise to produce a value of type T some time in the future. Once - // that value has been produced, the promise is "fulfilled". Alternatively, a promise can be - // "broken", with an Exception describing what went wrong. You may implicitly convert a value of - // type T to an already-fulfilled Promise. You may implicitly convert the constant - // `kj::READY_NOW` to an already-fulfilled Promise. You may also implicitly convert a - // `kj::Exception` to an already-broken promise of any type. - // - // Promises are linear types -- they are moveable but not copyable. If a Promise is destroyed - // or goes out of scope (without being moved elsewhere), any ongoing asynchronous operations - // meant to fulfill the promise will be canceled if possible. All methods of `Promise` (unless - // otherwise noted) actually consume the promise in the sense of move semantics. (Arguably they - // should be rvalue-qualified, but at the time this interface was created compilers didn't widely - // support that yet and anyway it would be pretty ugly typing kj::mv(promise).whatever().) If - // you want to use one Promise in two different places, you must fork it with `fork()`. - // - // To use the result of a Promise, you must call `then()` and supply a callback function to - // call with the result. `then()` returns another promise, for the result of the callback. - // Any time that this would result in Promise>, the promises are collapsed into a - // simple Promise that first waits for the outer promise, then the inner. Example: - // - // // Open a remote file, read the content, and then count the - // // number of lines of text. - // // Note that none of the calls here block. `file`, `content` - // // and `lineCount` are all initialized immediately before any - // // asynchronous operations occur. The lambda callbacks are - // // called later. - // Promise> file = openFtp("ftp://host/foo/bar"); - // Promise content = file.then( - // [](Own file) -> Promise { - // return file.readAll(); - // }); - // Promise lineCount = content.then( - // [](String text) -> int { - // uint count = 0; - // for (char c: text) count += (c == '\n'); - // return count; - // }); - // - // For `then()` to work, the current thread must have an active `EventLoop`. Each callback - // is scheduled to execute in that loop. Since `then()` schedules callbacks only on the current - // thread's event loop, you do not need to worry about two callbacks running at the same time. - // You will need to set up at least one `EventLoop` at the top level of your program before you - // can use promises. - // - // To adapt a non-Promise-based asynchronous API to promises, use `newAdaptedPromise()`. - // - // Systems using promises should consider supporting the concept of "pipelining". Pipelining - // means allowing a caller to start issuing method calls against a promised object before the - // promise has actually been fulfilled. This is particularly useful if the promise is for a - // remote object living across a network, as this can avoid round trips when chaining a series - // of calls. It is suggested that any class T which supports pipelining implement a subclass of - // Promise which adds "eventual send" methods -- methods which, when called, say "please - // invoke the corresponding method on the promised value once it is available". These methods - // should in turn return promises for the eventual results of said invocations. Cap'n Proto, - // for example, implements the type `RemotePromise` which supports pipelining RPC requests -- see - // `capnp/capability.h`. - // - // KJ Promises are based on E promises: - // http://wiki.erights.org/wiki/Walnut/Distributed_Computing#Promises - // - // KJ Promises are also inspired in part by the evolving standards for JavaScript/ECMAScript - // promises, which are themselves influenced by E promises: - // http://promisesaplus.com/ - // https://github.com/domenic/promises-unwrapping - -public: - Promise(_::FixVoid value); - // Construct an already-fulfilled Promise from a value of type T. For non-void promises, the - // parameter type is simply T. So, e.g., in a function that returns `Promise`, you can - // say `return 123;` to return a promise that is already fulfilled to 123. - // - // For void promises, use `kj::READY_NOW` as the value, e.g. `return kj::READY_NOW`. - - Promise(kj::Exception&& e); - // Construct an already-broken Promise. - - inline Promise(decltype(nullptr)) {} - - template - PromiseForResult then(Func&& func, ErrorFunc&& errorHandler = _::PropagateException()) - KJ_WARN_UNUSED_RESULT; - // Register a continuation function to be executed when the promise completes. The continuation - // (`func`) takes the promised value (an rvalue of type `T`) as its parameter. The continuation - // may return a new value; `then()` itself returns a promise for the continuation's eventual - // result. If the continuation itself returns a `Promise`, then `then()` shall also return - // a `Promise` which first waits for the original promise, then executes the continuation, - // then waits for the inner promise (i.e. it automatically "unwraps" the promise). - // - // In all cases, `then()` returns immediately. The continuation is executed later. The - // continuation is always executed on the same EventLoop (and, therefore, the same thread) which - // called `then()`, therefore no synchronization is necessary on state shared by the continuation - // and the surrounding scope. If no EventLoop is running on the current thread, `then()` throws - // an exception. - // - // You may also specify an error handler continuation as the second parameter. `errorHandler` - // must be a functor taking a parameter of type `kj::Exception&&`. It must return the same - // type as `func` returns (except when `func` returns `Promise`, in which case `errorHandler` - // may return either `Promise` or just `U`). The default error handler simply propagates the - // exception to the returned promise. - // - // Either `func` or `errorHandler` may, of course, throw an exception, in which case the promise - // is broken. When compiled with -fno-exceptions, the framework will still detect when a - // recoverable exception was thrown inside of a continuation and will consider the promise - // broken even though a (presumably garbage) result was returned. - // - // If the returned promise is destroyed before the callback runs, the callback will be canceled - // (it will never run). - // - // Note that `then()` -- like all other Promise methods -- consumes the promise on which it is - // called, in the sense of move semantics. After returning, the original promise is no longer - // valid, but `then()` returns a new promise. - // - // *Advanced implementation tips:* Most users will never need to worry about the below, but - // it is good to be aware of. - // - // As an optimization, if the callback function `func` does _not_ return another promise, then - // execution of `func` itself may be delayed until its result is known to be needed. The - // expectation here is that `func` is just doing some transformation on the results, not - // scheduling any other actions, therefore the system doesn't need to be proactive about - // evaluating it. This way, a chain of trivial then() transformations can be executed all at - // once without repeatedly re-scheduling through the event loop. Use the `eagerlyEvaluate()` - // method to suppress this behavior. - // - // On the other hand, if `func` _does_ return another promise, then the system evaluates `func` - // as soon as possible, because the promise it returns might be for a newly-scheduled - // long-running asynchronous task. - // - // As another optimization, when a callback function registered with `then()` is actually - // scheduled, it is scheduled to occur immediately, preempting other work in the event queue. - // This allows a long chain of `then`s to execute all at once, improving cache locality by - // clustering operations on the same data. However, this implies that starvation can occur - // if a chain of `then()`s takes a very long time to execute without ever stopping to wait for - // actual I/O. To solve this, use `kj::evalLater()` to yield control; this way, all other events - // in the queue will get a chance to run before your callback is executed. - - Promise ignoreResult() KJ_WARN_UNUSED_RESULT { return then([](T&&) {}); } - // Convenience method to convert the promise to a void promise by ignoring the return value. - // - // You must still wait on the returned promise if you want the task to execute. - - template - Promise catch_(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT; - // Equivalent to `.then(identityFunc, errorHandler)`, where `identifyFunc` is a function that - // just returns its input. - - T wait(WaitScope& waitScope); - // Run the event loop until the promise is fulfilled, then return its result. If the promise - // is rejected, throw an exception. - // - // wait() is primarily useful at the top level of a program -- typically, within the function - // that allocated the EventLoop. For example, a program that performs one or two RPCs and then - // exits would likely use wait() in its main() function to wait on each RPC. On the other hand, - // server-side code generally cannot use wait(), because it has to be able to accept multiple - // requests at once. - // - // If the promise is rejected, `wait()` throws an exception. If the program was compiled without - // exceptions (-fno-exceptions), this will usually abort. In this case you really should first - // use `then()` to set an appropriate handler for the exception case, so that the promise you - // actually wait on never throws. - // - // `waitScope` is an object proving that the caller is in a scope where wait() is allowed. By - // convention, any function which might call wait(), or which might call another function which - // might call wait(), must take `WaitScope&` as one of its parameters. This is needed for two - // reasons: - // * `wait()` is not allowed during an event callback, because event callbacks are themselves - // called during some other `wait()`, and such recursive `wait()`s would only be able to - // complete in LIFO order, which might mean that the outer `wait()` ends up waiting longer - // than it is supposed to. To prevent this, a `WaitScope` cannot be constructed or used during - // an event callback. - // * Since `wait()` runs the event loop, unrelated event callbacks may execute before `wait()` - // returns. This means that anyone calling `wait()` must be reentrant -- state may change - // around them in arbitrary ways. Therefore, callers really need to know if a function they - // are calling might wait(), and the `WaitScope&` parameter makes this clear. - // - // TODO(someday): Implement fibers, and let them call wait() even when they are handling an - // event. - - ForkedPromise fork() KJ_WARN_UNUSED_RESULT; - // Forks the promise, so that multiple different clients can independently wait on the result. - // `T` must be copy-constructable for this to work. Or, in the special case where `T` is - // `Own`, `U` must have a method `Own addRef()` which returns a new reference to the same - // (or an equivalent) object (probably implemented via reference counting). - - _::SplitTuplePromise split(); - // Split a promise for a tuple into a tuple of promises. - // - // E.g. if you have `Promise>`, `split()` returns - // `kj::Tuple, Promise>`. - - Promise exclusiveJoin(Promise&& other) KJ_WARN_UNUSED_RESULT; - // Return a new promise that resolves when either the original promise resolves or `other` - // resolves (whichever comes first). The promise that didn't resolve first is canceled. - - // TODO(someday): inclusiveJoin(), or perhaps just join(), which waits for both completions - // and produces a tuple? - - template - Promise attach(Attachments&&... attachments) KJ_WARN_UNUSED_RESULT; - // "Attaches" one or more movable objects (often, Owns) to the promise, such that they will - // be destroyed when the promise resolves. This is useful when a promise's callback contains - // pointers into some object and you want to make sure the object still exists when the callback - // runs -- after calling then(), use attach() to add necessary objects to the result. - - template - Promise eagerlyEvaluate(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT; - Promise eagerlyEvaluate(decltype(nullptr)) KJ_WARN_UNUSED_RESULT; - // Force eager evaluation of this promise. Use this if you are going to hold on to the promise - // for awhile without consuming the result, but you want to make sure that the system actually - // processes it. - // - // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to - // `then()`, except that it must return void. We make you specify this because otherwise it's - // easy to forget to handle errors in a promise that you never use. You may specify nullptr for - // the error handler if you are sure that ignoring errors is fine, or if you know that you'll - // eventually wait on the promise somewhere. - - template - void detach(ErrorFunc&& errorHandler); - // Allows the promise to continue running in the background until it completes or the - // `EventLoop` is destroyed. Be careful when using this: since you can no longer cancel this - // promise, you need to make sure that the promise owns all the objects it touches or make sure - // those objects outlive the EventLoop. - // - // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to - // `then()`, except that it must return void. - // - // This function exists mainly to implement the Cap'n Proto requirement that RPC calls cannot be - // canceled unless the callee explicitly permits it. - - kj::String trace(); - // Returns a dump of debug info about this promise. Not for production use. Requires RTTI. - // This method does NOT consume the promise as other methods do. - -private: - Promise(bool, Own<_::PromiseNode>&& node): PromiseBase(kj::mv(node)) {} - // Second parameter prevent ambiguity with immediate-value constructor. - - template - friend class Promise; - friend class EventLoop; - template - friend Promise newAdaptedPromise(Params&&... adapterConstructorParams); - template - friend PromiseFulfillerPair newPromiseAndFulfiller(); - template - friend class _::ForkHub; - friend class _::TaskSetImpl; - friend Promise _::yield(); - friend class _::NeverDone; - template - friend Promise> joinPromises(Array>&& promises); - friend Promise joinPromises(Array>&& promises); -}; - -template -class ForkedPromise { - // The result of `Promise::fork()` and `EventLoop::fork()`. Allows branches to be created. - // Like `Promise`, this is a pass-by-move type. - -public: - inline ForkedPromise(decltype(nullptr)) {} - - Promise addBranch(); - // Add a new branch to the fork. The branch is equivalent to the original promise. - -private: - Own<_::ForkHub<_::FixVoid>> hub; - - inline ForkedPromise(bool, Own<_::ForkHub<_::FixVoid>>&& hub): hub(kj::mv(hub)) {} - - friend class Promise; - friend class EventLoop; -}; - -constexpr _::Void READY_NOW = _::Void(); -// Use this when you need a Promise that is already fulfilled -- this value can be implicitly -// cast to `Promise`. - -constexpr _::NeverDone NEVER_DONE = _::NeverDone(); -// The opposite of `READY_NOW`, return this when the promise should never resolve. This can be -// implicitly converted to any promise type. You may also call `NEVER_DONE.wait()` to wait -// forever (useful for servers). - -template -PromiseForResult evalLater(Func&& func) KJ_WARN_UNUSED_RESULT; -// Schedule for the given zero-parameter function to be executed in the event loop at some -// point in the near future. Returns a Promise for its result -- or, if `func()` itself returns -// a promise, `evalLater()` returns a Promise for the result of resolving that promise. -// -// Example usage: -// Promise x = evalLater([]() { return 123; }); -// -// The above is exactly equivalent to: -// Promise x = Promise(READY_NOW).then([]() { return 123; }); -// -// If the returned promise is destroyed before the callback runs, the callback will be canceled -// (never called). -// -// If you schedule several evaluations with `evalLater` during the same callback, they are -// guaranteed to be executed in order. - -template -PromiseForResult evalNow(Func&& func) KJ_WARN_UNUSED_RESULT; -// Run `func()` and return a promise for its result. `func()` executes before `evalNow()` returns. -// If `func()` throws an exception, the exception is caught and wrapped in a promise -- this is the -// main reason why `evalNow()` is useful. - -template -Promise> joinPromises(Array>&& promises); -// Join an array of promises into a promise for an array. - -// ======================================================================================= -// Hack for creating a lambda that holds an owned pointer. - -template -class CaptureByMove { -public: - inline CaptureByMove(Func&& func, MovedParam&& param) - : func(kj::mv(func)), param(kj::mv(param)) {} - - template - inline auto operator()(Params&&... params) - -> decltype(kj::instance()(kj::instance(), kj::fwd(params)...)) { - return func(kj::mv(param), kj::fwd(params)...); - } - -private: - Func func; - MovedParam param; -}; - -template -inline CaptureByMove> mvCapture(MovedParam&& param, Func&& func) { - // Hack to create a "lambda" which captures a variable by moving it rather than copying or - // referencing. C++14 generalized captures should make this obsolete, but for now in C++11 this - // is commonly needed for Promise continuations that own their state. Example usage: - // - // Own ptr = makeFoo(); - // Promise promise = callRpc(); - // promise.then(mvCapture(ptr, [](Own&& ptr, int result) { - // return ptr->finish(result); - // })); - - return CaptureByMove>(kj::fwd(func), kj::mv(param)); -} - -// ======================================================================================= -// Advanced promise construction - -template -class PromiseFulfiller { - // A callback which can be used to fulfill a promise. Only the first call to fulfill() or - // reject() matters; subsequent calls are ignored. - -public: - virtual void fulfill(T&& value) = 0; - // Fulfill the promise with the given value. - - virtual void reject(Exception&& exception) = 0; - // Reject the promise with an error. - - virtual bool isWaiting() = 0; - // Returns true if the promise is still unfulfilled and someone is potentially waiting for it. - // Returns false if fulfill()/reject() has already been called *or* if the promise to be - // fulfilled has been discarded and therefore the result will never be used anyway. - - template - bool rejectIfThrows(Func&& func); - // Call the function (with no arguments) and return true. If an exception is thrown, call - // `fulfiller.reject()` and then return false. When compiled with exceptions disabled, - // non-fatal exceptions are still detected and handled correctly. -}; - -template <> -class PromiseFulfiller { - // Specialization of PromiseFulfiller for void promises. See PromiseFulfiller. - -public: - virtual void fulfill(_::Void&& value = _::Void()) = 0; - // Call with zero parameters. The parameter is a dummy that only exists so that subclasses don't - // have to specialize for . - - virtual void reject(Exception&& exception) = 0; - virtual bool isWaiting() = 0; - - template - bool rejectIfThrows(Func&& func); -}; - -template -Promise newAdaptedPromise(Params&&... adapterConstructorParams); -// Creates a new promise which owns an instance of `Adapter` which encapsulates the operation -// that will eventually fulfill the promise. This is primarily useful for adapting non-KJ -// asynchronous APIs to use promises. -// -// An instance of `Adapter` will be allocated and owned by the returned `Promise`. A -// `PromiseFulfiller&` will be passed as the first parameter to the adapter's constructor, -// and `adapterConstructorParams` will be forwarded as the subsequent parameters. The adapter -// is expected to perform some asynchronous operation and call the `PromiseFulfiller` once -// it is finished. -// -// The adapter is destroyed when its owning Promise is destroyed. This may occur before the -// Promise has been fulfilled. In this case, the adapter's destructor should cancel the -// asynchronous operation. Once the adapter is destroyed, the fulfillment callback cannot be -// called. -// -// An adapter implementation should be carefully written to ensure that it cannot accidentally -// be left unfulfilled permanently because of an exception. Consider making liberal use of -// `PromiseFulfiller::rejectIfThrows()`. - -template -struct PromiseFulfillerPair { - Promise<_::JoinPromises> promise; - Own> fulfiller; -}; - -template -PromiseFulfillerPair newPromiseAndFulfiller(); -// Construct a Promise and a separate PromiseFulfiller which can be used to fulfill the promise. -// If the PromiseFulfiller is destroyed before either of its methods are called, the Promise is -// implicitly rejected. -// -// Although this function is easier to use than `newAdaptedPromise()`, it has the serious drawback -// that there is no way to handle cancellation (i.e. detect when the Promise is discarded). -// -// You can arrange to fulfill a promise with another promise by using a promise type for T. E.g. -// `newPromiseAndFulfiller>()` will produce a promise of type `Promise` but the -// fulfiller will be of type `PromiseFulfiller>`. Thus you pass a `Promise` to the -// `fulfill()` callback, and the promises are chained. - -// ======================================================================================= -// TaskSet - -class TaskSet { - // Holds a collection of Promises and ensures that each executes to completion. Memory - // associated with each promise is automatically freed when the promise completes. Destroying - // the TaskSet itself automatically cancels all unfinished promises. - // - // This is useful for "daemon" objects that perform background tasks which aren't intended to - // fulfill any particular external promise, but which may need to be canceled (and thus can't - // use `Promise::detach()`). The daemon object holds a TaskSet to collect these tasks it is - // working on. This way, if the daemon itself is destroyed, the TaskSet is detroyed as well, - // and everything the daemon is doing is canceled. - -public: - class ErrorHandler { - public: - virtual void taskFailed(kj::Exception&& exception) = 0; - }; - - TaskSet(ErrorHandler& errorHandler); - // `loop` will be used to wait on promises. `errorHandler` will be executed any time a task - // throws an exception, and will execute within the given EventLoop. - - ~TaskSet() noexcept(false); - - void add(Promise&& promise); - - kj::String trace(); - // Return debug info about all promises currently in the TaskSet. - -private: - Own<_::TaskSetImpl> impl; -}; - -// ======================================================================================= -// The EventLoop class - -class EventPort { - // Interfaces between an `EventLoop` and events originating from outside of the loop's thread. - // All such events come in through the `EventPort` implementation. - // - // An `EventPort` implementation may interface with low-level operating system APIs and/or other - // threads. You can also write an `EventPort` which wraps some other (non-KJ) event loop - // framework, allowing the two to coexist in a single thread. - -public: - virtual bool wait() = 0; - // Wait for an external event to arrive, sleeping if necessary. Once at least one event has - // arrived, queue it to the event loop (e.g. by fulfilling a promise) and return. - // - // This is called during `Promise::wait()` whenever the event queue becomes empty, in order to - // wait for new events to populate the queue. - // - // It is safe to return even if nothing has actually been queued, so long as calling `wait()` in - // a loop will eventually sleep. (That is to say, false positives are fine.) - // - // Returns true if wake() has been called from another thread. (Precisely, returns true if - // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last - // called.) - - virtual bool poll() = 0; - // Check if any external events have arrived, but do not sleep. If any events have arrived, - // add them to the event queue (e.g. by fulfilling promises) before returning. - // - // This may be called during `Promise::wait()` when the EventLoop has been executing for a while - // without a break but is still non-empty. - // - // Returns true if wake() has been called from another thread. (Precisely, returns true if - // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last - // called.) - - virtual void setRunnable(bool runnable); - // Called to notify the `EventPort` when the `EventLoop` has work to do; specifically when it - // transitions from empty -> runnable or runnable -> empty. This is typically useful when - // integrating with an external event loop; if the loop is currently runnable then you should - // arrange to call run() on it soon. The default implementation does nothing. - - virtual void wake() const; - // Wake up the EventPort's thread from another thread. - // - // Unlike all other methods on this interface, `wake()` may be called from another thread, hence - // it is `const`. - // - // Technically speaking, `wake()` causes the target thread to cease sleeping and not to sleep - // again until `wait()` or `poll()` has returned true at least once. - // - // The default implementation throws an UNIMPLEMENTED exception. -}; - -class EventLoop { - // Represents a queue of events being executed in a loop. Most code won't interact with - // EventLoop directly, but instead use `Promise`s to interact with it indirectly. See the - // documentation for `Promise`. - // - // Each thread can have at most one current EventLoop. To make an `EventLoop` current for - // the thread, create a `WaitScope`. Async APIs require that the thread has a current EventLoop, - // or they will throw exceptions. APIs that use `Promise::wait()` additionally must explicitly - // be passed a reference to the `WaitScope` to make the caller aware that they might block. - // - // Generally, you will want to construct an `EventLoop` at the top level of your program, e.g. - // in the main() function, or in the start function of a thread. You can then use it to - // construct some promises and wait on the result. Example: - // - // int main() { - // // `loop` becomes the official EventLoop for the thread. - // MyEventPort eventPort; - // EventLoop loop(eventPort); - // - // // Now we can call an async function. - // Promise textPromise = getHttp("http://example.com"); - // - // // And we can wait for the promise to complete. Note that you can only use `wait()` - // // from the top level, not from inside a promise callback. - // String text = textPromise.wait(); - // print(text); - // return 0; - // } - // - // Most applications that do I/O will prefer to use `setupAsyncIo()` from `async-io.h` rather - // than allocate an `EventLoop` directly. - -public: - EventLoop(); - // Construct an `EventLoop` which does not receive external events at all. - - explicit EventLoop(EventPort& port); - // Construct an `EventLoop` which receives external events through the given `EventPort`. - - ~EventLoop() noexcept(false); - - void run(uint maxTurnCount = maxValue); - // Run the event loop for `maxTurnCount` turns or until there is nothing left to be done, - // whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will - // call the `EventPort`'s `setRunnable(false)` if the queue becomes empty. - - bool isRunnable(); - // Returns true if run() would currently do anything, or false if the queue is empty. - -private: - EventPort& port; - - bool running = false; - // True while looping -- wait() is then not allowed. - - bool lastRunnableState = false; - // What did we last pass to port.setRunnable()? - - _::Event* head = nullptr; - _::Event** tail = &head; - _::Event** depthFirstInsertPoint = &head; - - Own<_::TaskSetImpl> daemons; - - bool turn(); - void setRunnable(bool runnable); - void enterScope(); - void leaveScope(); - - friend void _::detach(kj::Promise&& promise); - friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, - WaitScope& waitScope); - friend class _::Event; - friend class WaitScope; -}; - -class WaitScope { - // Represents a scope in which asynchronous programming can occur. A `WaitScope` should usually - // be allocated on the stack and serves two purposes: - // * While the `WaitScope` exists, its `EventLoop` is registered as the current loop for the - // thread. Most operations dealing with `Promise` (including all of its methods) do not work - // unless the thread has a current `EventLoop`. - // * `WaitScope` may be passed to `Promise::wait()` to synchronously wait for a particular - // promise to complete. See `Promise::wait()` for an extended discussion. - -public: - inline explicit WaitScope(EventLoop& loop): loop(loop) { loop.enterScope(); } - inline ~WaitScope() { loop.leaveScope(); } - KJ_DISALLOW_COPY(WaitScope); - -private: - EventLoop& loop; - friend class EventLoop; - friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, - WaitScope& waitScope); -}; - -} // namespace kj - -#include "async-inl.h" - -#endif // KJ_ASYNC_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. + +#ifndef KJ_ASYNC_H_ +#define KJ_ASYNC_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "async-prelude.h" +#include "exception.h" +#include "refcount.h" + +namespace kj { + +class EventLoop; +class WaitScope; + +template +class Promise; +template +class ForkedPromise; +template +class PromiseFulfiller; +template +struct PromiseFulfillerPair; + +template +using PromiseForResult = Promise<_::JoinPromises<_::ReturnType>>; +// Evaluates to the type of Promise for the result of calling functor type Func with parameter type +// T. If T is void, then the promise is for the result of calling Func with no arguments. If +// Func itself returns a promise, the promises are joined, so you never get Promise>. + +// ======================================================================================= +// Promises + +template +class Promise: protected _::PromiseBase { + // The basic primitive of asynchronous computation in KJ. Similar to "futures", but designed + // specifically for event loop concurrency. Similar to E promises and JavaScript Promises/A. + // + // A Promise represents a promise to produce a value of type T some time in the future. Once + // that value has been produced, the promise is "fulfilled". Alternatively, a promise can be + // "broken", with an Exception describing what went wrong. You may implicitly convert a value of + // type T to an already-fulfilled Promise. You may implicitly convert the constant + // `kj::READY_NOW` to an already-fulfilled Promise. You may also implicitly convert a + // `kj::Exception` to an already-broken promise of any type. + // + // Promises are linear types -- they are moveable but not copyable. If a Promise is destroyed + // or goes out of scope (without being moved elsewhere), any ongoing asynchronous operations + // meant to fulfill the promise will be canceled if possible. All methods of `Promise` (unless + // otherwise noted) actually consume the promise in the sense of move semantics. (Arguably they + // should be rvalue-qualified, but at the time this interface was created compilers didn't widely + // support that yet and anyway it would be pretty ugly typing kj::mv(promise).whatever().) If + // you want to use one Promise in two different places, you must fork it with `fork()`. + // + // To use the result of a Promise, you must call `then()` and supply a callback function to + // call with the result. `then()` returns another promise, for the result of the callback. + // Any time that this would result in Promise>, the promises are collapsed into a + // simple Promise that first waits for the outer promise, then the inner. Example: + // + // // Open a remote file, read the content, and then count the + // // number of lines of text. + // // Note that none of the calls here block. `file`, `content` + // // and `lineCount` are all initialized immediately before any + // // asynchronous operations occur. The lambda callbacks are + // // called later. + // Promise> file = openFtp("ftp://host/foo/bar"); + // Promise content = file.then( + // [](Own file) -> Promise { + // return file.readAll(); + // }); + // Promise lineCount = content.then( + // [](String text) -> int { + // uint count = 0; + // for (char c: text) count += (c == '\n'); + // return count; + // }); + // + // For `then()` to work, the current thread must have an active `EventLoop`. Each callback + // is scheduled to execute in that loop. Since `then()` schedules callbacks only on the current + // thread's event loop, you do not need to worry about two callbacks running at the same time. + // You will need to set up at least one `EventLoop` at the top level of your program before you + // can use promises. + // + // To adapt a non-Promise-based asynchronous API to promises, use `newAdaptedPromise()`. + // + // Systems using promises should consider supporting the concept of "pipelining". Pipelining + // means allowing a caller to start issuing method calls against a promised object before the + // promise has actually been fulfilled. This is particularly useful if the promise is for a + // remote object living across a network, as this can avoid round trips when chaining a series + // of calls. It is suggested that any class T which supports pipelining implement a subclass of + // Promise which adds "eventual send" methods -- methods which, when called, say "please + // invoke the corresponding method on the promised value once it is available". These methods + // should in turn return promises for the eventual results of said invocations. Cap'n Proto, + // for example, implements the type `RemotePromise` which supports pipelining RPC requests -- see + // `capnp/capability.h`. + // + // KJ Promises are based on E promises: + // http://wiki.erights.org/wiki/Walnut/Distributed_Computing#Promises + // + // KJ Promises are also inspired in part by the evolving standards for JavaScript/ECMAScript + // promises, which are themselves influenced by E promises: + // http://promisesaplus.com/ + // https://github.com/domenic/promises-unwrapping + +public: + Promise(_::FixVoid value); + // Construct an already-fulfilled Promise from a value of type T. For non-void promises, the + // parameter type is simply T. So, e.g., in a function that returns `Promise`, you can + // say `return 123;` to return a promise that is already fulfilled to 123. + // + // For void promises, use `kj::READY_NOW` as the value, e.g. `return kj::READY_NOW`. + + Promise(kj::Exception&& e); + // Construct an already-broken Promise. + + inline Promise(decltype(nullptr)) {} + + template + PromiseForResult then(Func&& func, ErrorFunc&& errorHandler = _::PropagateException()) + KJ_WARN_UNUSED_RESULT; + // Register a continuation function to be executed when the promise completes. The continuation + // (`func`) takes the promised value (an rvalue of type `T`) as its parameter. The continuation + // may return a new value; `then()` itself returns a promise for the continuation's eventual + // result. If the continuation itself returns a `Promise`, then `then()` shall also return + // a `Promise` which first waits for the original promise, then executes the continuation, + // then waits for the inner promise (i.e. it automatically "unwraps" the promise). + // + // In all cases, `then()` returns immediately. The continuation is executed later. The + // continuation is always executed on the same EventLoop (and, therefore, the same thread) which + // called `then()`, therefore no synchronization is necessary on state shared by the continuation + // and the surrounding scope. If no EventLoop is running on the current thread, `then()` throws + // an exception. + // + // You may also specify an error handler continuation as the second parameter. `errorHandler` + // must be a functor taking a parameter of type `kj::Exception&&`. It must return the same + // type as `func` returns (except when `func` returns `Promise`, in which case `errorHandler` + // may return either `Promise` or just `U`). The default error handler simply propagates the + // exception to the returned promise. + // + // Either `func` or `errorHandler` may, of course, throw an exception, in which case the promise + // is broken. When compiled with -fno-exceptions, the framework will still detect when a + // recoverable exception was thrown inside of a continuation and will consider the promise + // broken even though a (presumably garbage) result was returned. + // + // If the returned promise is destroyed before the callback runs, the callback will be canceled + // (it will never run). + // + // Note that `then()` -- like all other Promise methods -- consumes the promise on which it is + // called, in the sense of move semantics. After returning, the original promise is no longer + // valid, but `then()` returns a new promise. + // + // *Advanced implementation tips:* Most users will never need to worry about the below, but + // it is good to be aware of. + // + // As an optimization, if the callback function `func` does _not_ return another promise, then + // execution of `func` itself may be delayed until its result is known to be needed. The + // expectation here is that `func` is just doing some transformation on the results, not + // scheduling any other actions, therefore the system doesn't need to be proactive about + // evaluating it. This way, a chain of trivial then() transformations can be executed all at + // once without repeatedly re-scheduling through the event loop. Use the `eagerlyEvaluate()` + // method to suppress this behavior. + // + // On the other hand, if `func` _does_ return another promise, then the system evaluates `func` + // as soon as possible, because the promise it returns might be for a newly-scheduled + // long-running asynchronous task. + // + // As another optimization, when a callback function registered with `then()` is actually + // scheduled, it is scheduled to occur immediately, preempting other work in the event queue. + // This allows a long chain of `then`s to execute all at once, improving cache locality by + // clustering operations on the same data. However, this implies that starvation can occur + // if a chain of `then()`s takes a very long time to execute without ever stopping to wait for + // actual I/O. To solve this, use `kj::evalLater()` to yield control; this way, all other events + // in the queue will get a chance to run before your callback is executed. + + Promise ignoreResult() KJ_WARN_UNUSED_RESULT { return then([](T&&) {}); } + // Convenience method to convert the promise to a void promise by ignoring the return value. + // + // You must still wait on the returned promise if you want the task to execute. + + template + Promise catch_(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT; + // Equivalent to `.then(identityFunc, errorHandler)`, where `identifyFunc` is a function that + // just returns its input. + + T wait(WaitScope& waitScope); + // Run the event loop until the promise is fulfilled, then return its result. If the promise + // is rejected, throw an exception. + // + // wait() is primarily useful at the top level of a program -- typically, within the function + // that allocated the EventLoop. For example, a program that performs one or two RPCs and then + // exits would likely use wait() in its main() function to wait on each RPC. On the other hand, + // server-side code generally cannot use wait(), because it has to be able to accept multiple + // requests at once. + // + // If the promise is rejected, `wait()` throws an exception. If the program was compiled without + // exceptions (-fno-exceptions), this will usually abort. In this case you really should first + // use `then()` to set an appropriate handler for the exception case, so that the promise you + // actually wait on never throws. + // + // `waitScope` is an object proving that the caller is in a scope where wait() is allowed. By + // convention, any function which might call wait(), or which might call another function which + // might call wait(), must take `WaitScope&` as one of its parameters. This is needed for two + // reasons: + // * `wait()` is not allowed during an event callback, because event callbacks are themselves + // called during some other `wait()`, and such recursive `wait()`s would only be able to + // complete in LIFO order, which might mean that the outer `wait()` ends up waiting longer + // than it is supposed to. To prevent this, a `WaitScope` cannot be constructed or used during + // an event callback. + // * Since `wait()` runs the event loop, unrelated event callbacks may execute before `wait()` + // returns. This means that anyone calling `wait()` must be reentrant -- state may change + // around them in arbitrary ways. Therefore, callers really need to know if a function they + // are calling might wait(), and the `WaitScope&` parameter makes this clear. + // + // TODO(someday): Implement fibers, and let them call wait() even when they are handling an + // event. + + ForkedPromise fork() KJ_WARN_UNUSED_RESULT; + // Forks the promise, so that multiple different clients can independently wait on the result. + // `T` must be copy-constructable for this to work. Or, in the special case where `T` is + // `Own`, `U` must have a method `Own addRef()` which returns a new reference to the same + // (or an equivalent) object (probably implemented via reference counting). + + _::SplitTuplePromise split(); + // Split a promise for a tuple into a tuple of promises. + // + // E.g. if you have `Promise>`, `split()` returns + // `kj::Tuple, Promise>`. + + Promise exclusiveJoin(Promise&& other) KJ_WARN_UNUSED_RESULT; + // Return a new promise that resolves when either the original promise resolves or `other` + // resolves (whichever comes first). The promise that didn't resolve first is canceled. + + // TODO(someday): inclusiveJoin(), or perhaps just join(), which waits for both completions + // and produces a tuple? + + template + Promise attach(Attachments&&... attachments) KJ_WARN_UNUSED_RESULT; + // "Attaches" one or more movable objects (often, Owns) to the promise, such that they will + // be destroyed when the promise resolves. This is useful when a promise's callback contains + // pointers into some object and you want to make sure the object still exists when the callback + // runs -- after calling then(), use attach() to add necessary objects to the result. + + template + Promise eagerlyEvaluate(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT; + Promise eagerlyEvaluate(decltype(nullptr)) KJ_WARN_UNUSED_RESULT; + // Force eager evaluation of this promise. Use this if you are going to hold on to the promise + // for awhile without consuming the result, but you want to make sure that the system actually + // processes it. + // + // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to + // `then()`, except that it must return void. We make you specify this because otherwise it's + // easy to forget to handle errors in a promise that you never use. You may specify nullptr for + // the error handler if you are sure that ignoring errors is fine, or if you know that you'll + // eventually wait on the promise somewhere. + + template + void detach(ErrorFunc&& errorHandler); + // Allows the promise to continue running in the background until it completes or the + // `EventLoop` is destroyed. Be careful when using this: since you can no longer cancel this + // promise, you need to make sure that the promise owns all the objects it touches or make sure + // those objects outlive the EventLoop. + // + // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to + // `then()`, except that it must return void. + // + // This function exists mainly to implement the Cap'n Proto requirement that RPC calls cannot be + // canceled unless the callee explicitly permits it. + + kj::String trace(); + // Returns a dump of debug info about this promise. Not for production use. Requires RTTI. + // This method does NOT consume the promise as other methods do. + +private: + Promise(bool, Own<_::PromiseNode>&& node): PromiseBase(kj::mv(node)) {} + // Second parameter prevent ambiguity with immediate-value constructor. + + template + friend class Promise; + friend class EventLoop; + template + friend Promise newAdaptedPromise(Params&&... adapterConstructorParams); + template + friend PromiseFulfillerPair newPromiseAndFulfiller(); + template + friend class _::ForkHub; + friend class _::TaskSetImpl; + friend Promise _::yield(); + friend class _::NeverDone; + template + friend Promise> joinPromises(Array>&& promises); + friend Promise joinPromises(Array>&& promises); +}; + +template +class ForkedPromise { + // The result of `Promise::fork()` and `EventLoop::fork()`. Allows branches to be created. + // Like `Promise`, this is a pass-by-move type. + +public: + inline ForkedPromise(decltype(nullptr)) {} + + Promise addBranch(); + // Add a new branch to the fork. The branch is equivalent to the original promise. + +private: + Own<_::ForkHub<_::FixVoid>> hub; + + inline ForkedPromise(bool, Own<_::ForkHub<_::FixVoid>>&& hub): hub(kj::mv(hub)) {} + + friend class Promise; + friend class EventLoop; +}; + +constexpr _::Void READY_NOW = _::Void(); +// Use this when you need a Promise that is already fulfilled -- this value can be implicitly +// cast to `Promise`. + +constexpr _::NeverDone NEVER_DONE = _::NeverDone(); +// The opposite of `READY_NOW`, return this when the promise should never resolve. This can be +// implicitly converted to any promise type. You may also call `NEVER_DONE.wait()` to wait +// forever (useful for servers). + +template +PromiseForResult evalLater(Func&& func) KJ_WARN_UNUSED_RESULT; +// Schedule for the given zero-parameter function to be executed in the event loop at some +// point in the near future. Returns a Promise for its result -- or, if `func()` itself returns +// a promise, `evalLater()` returns a Promise for the result of resolving that promise. +// +// Example usage: +// Promise x = evalLater([]() { return 123; }); +// +// The above is exactly equivalent to: +// Promise x = Promise(READY_NOW).then([]() { return 123; }); +// +// If the returned promise is destroyed before the callback runs, the callback will be canceled +// (never called). +// +// If you schedule several evaluations with `evalLater` during the same callback, they are +// guaranteed to be executed in order. + +template +PromiseForResult evalNow(Func&& func) KJ_WARN_UNUSED_RESULT; +// Run `func()` and return a promise for its result. `func()` executes before `evalNow()` returns. +// If `func()` throws an exception, the exception is caught and wrapped in a promise -- this is the +// main reason why `evalNow()` is useful. + +template +Promise> joinPromises(Array>&& promises); +// Join an array of promises into a promise for an array. + +// ======================================================================================= +// Hack for creating a lambda that holds an owned pointer. + +template +class CaptureByMove { +public: + inline CaptureByMove(Func&& func, MovedParam&& param) + : func(kj::mv(func)), param(kj::mv(param)) {} + + template + inline auto operator()(Params&&... params) + -> decltype(kj::instance()(kj::instance(), kj::fwd(params)...)) { + return func(kj::mv(param), kj::fwd(params)...); + } + +private: + Func func; + MovedParam param; +}; + +template +inline CaptureByMove> mvCapture(MovedParam&& param, Func&& func) { + // Hack to create a "lambda" which captures a variable by moving it rather than copying or + // referencing. C++14 generalized captures should make this obsolete, but for now in C++11 this + // is commonly needed for Promise continuations that own their state. Example usage: + // + // Own ptr = makeFoo(); + // Promise promise = callRpc(); + // promise.then(mvCapture(ptr, [](Own&& ptr, int result) { + // return ptr->finish(result); + // })); + + return CaptureByMove>(kj::fwd(func), kj::mv(param)); +} + +// ======================================================================================= +// Advanced promise construction + +template +class PromiseFulfiller { + // A callback which can be used to fulfill a promise. Only the first call to fulfill() or + // reject() matters; subsequent calls are ignored. + +public: + virtual void fulfill(T&& value) = 0; + // Fulfill the promise with the given value. + + virtual void reject(Exception&& exception) = 0; + // Reject the promise with an error. + + virtual bool isWaiting() = 0; + // Returns true if the promise is still unfulfilled and someone is potentially waiting for it. + // Returns false if fulfill()/reject() has already been called *or* if the promise to be + // fulfilled has been discarded and therefore the result will never be used anyway. + + template + bool rejectIfThrows(Func&& func); + // Call the function (with no arguments) and return true. If an exception is thrown, call + // `fulfiller.reject()` and then return false. When compiled with exceptions disabled, + // non-fatal exceptions are still detected and handled correctly. +}; + +template <> +class PromiseFulfiller { + // Specialization of PromiseFulfiller for void promises. See PromiseFulfiller. + +public: + virtual void fulfill(_::Void&& value = _::Void()) = 0; + // Call with zero parameters. The parameter is a dummy that only exists so that subclasses don't + // have to specialize for . + + virtual void reject(Exception&& exception) = 0; + virtual bool isWaiting() = 0; + + template + bool rejectIfThrows(Func&& func); +}; + +template +Promise newAdaptedPromise(Params&&... adapterConstructorParams); +// Creates a new promise which owns an instance of `Adapter` which encapsulates the operation +// that will eventually fulfill the promise. This is primarily useful for adapting non-KJ +// asynchronous APIs to use promises. +// +// An instance of `Adapter` will be allocated and owned by the returned `Promise`. A +// `PromiseFulfiller&` will be passed as the first parameter to the adapter's constructor, +// and `adapterConstructorParams` will be forwarded as the subsequent parameters. The adapter +// is expected to perform some asynchronous operation and call the `PromiseFulfiller` once +// it is finished. +// +// The adapter is destroyed when its owning Promise is destroyed. This may occur before the +// Promise has been fulfilled. In this case, the adapter's destructor should cancel the +// asynchronous operation. Once the adapter is destroyed, the fulfillment callback cannot be +// called. +// +// An adapter implementation should be carefully written to ensure that it cannot accidentally +// be left unfulfilled permanently because of an exception. Consider making liberal use of +// `PromiseFulfiller::rejectIfThrows()`. + +template +struct PromiseFulfillerPair { + Promise<_::JoinPromises> promise; + Own> fulfiller; +}; + +template +PromiseFulfillerPair newPromiseAndFulfiller(); +// Construct a Promise and a separate PromiseFulfiller which can be used to fulfill the promise. +// If the PromiseFulfiller is destroyed before either of its methods are called, the Promise is +// implicitly rejected. +// +// Although this function is easier to use than `newAdaptedPromise()`, it has the serious drawback +// that there is no way to handle cancellation (i.e. detect when the Promise is discarded). +// +// You can arrange to fulfill a promise with another promise by using a promise type for T. E.g. +// `newPromiseAndFulfiller>()` will produce a promise of type `Promise` but the +// fulfiller will be of type `PromiseFulfiller>`. Thus you pass a `Promise` to the +// `fulfill()` callback, and the promises are chained. + +// ======================================================================================= +// TaskSet + +class TaskSet { + // Holds a collection of Promises and ensures that each executes to completion. Memory + // associated with each promise is automatically freed when the promise completes. Destroying + // the TaskSet itself automatically cancels all unfinished promises. + // + // This is useful for "daemon" objects that perform background tasks which aren't intended to + // fulfill any particular external promise, but which may need to be canceled (and thus can't + // use `Promise::detach()`). The daemon object holds a TaskSet to collect these tasks it is + // working on. This way, if the daemon itself is destroyed, the TaskSet is detroyed as well, + // and everything the daemon is doing is canceled. + +public: + class ErrorHandler { + public: + virtual void taskFailed(kj::Exception&& exception) = 0; + }; + + TaskSet(ErrorHandler& errorHandler); + // `loop` will be used to wait on promises. `errorHandler` will be executed any time a task + // throws an exception, and will execute within the given EventLoop. + + ~TaskSet() noexcept(false); + + void add(Promise&& promise); + + kj::String trace(); + // Return debug info about all promises currently in the TaskSet. + +private: + Own<_::TaskSetImpl> impl; +}; + +// ======================================================================================= +// The EventLoop class + +class EventPort { + // Interfaces between an `EventLoop` and events originating from outside of the loop's thread. + // All such events come in through the `EventPort` implementation. + // + // An `EventPort` implementation may interface with low-level operating system APIs and/or other + // threads. You can also write an `EventPort` which wraps some other (non-KJ) event loop + // framework, allowing the two to coexist in a single thread. + +public: + virtual bool wait() = 0; + // Wait for an external event to arrive, sleeping if necessary. Once at least one event has + // arrived, queue it to the event loop (e.g. by fulfilling a promise) and return. + // + // This is called during `Promise::wait()` whenever the event queue becomes empty, in order to + // wait for new events to populate the queue. + // + // It is safe to return even if nothing has actually been queued, so long as calling `wait()` in + // a loop will eventually sleep. (That is to say, false positives are fine.) + // + // Returns true if wake() has been called from another thread. (Precisely, returns true if + // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last + // called.) + + virtual bool poll() = 0; + // Check if any external events have arrived, but do not sleep. If any events have arrived, + // add them to the event queue (e.g. by fulfilling promises) before returning. + // + // This may be called during `Promise::wait()` when the EventLoop has been executing for a while + // without a break but is still non-empty. + // + // Returns true if wake() has been called from another thread. (Precisely, returns true if + // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last + // called.) + + virtual void setRunnable(bool runnable); + // Called to notify the `EventPort` when the `EventLoop` has work to do; specifically when it + // transitions from empty -> runnable or runnable -> empty. This is typically useful when + // integrating with an external event loop; if the loop is currently runnable then you should + // arrange to call run() on it soon. The default implementation does nothing. + + virtual void wake() const; + // Wake up the EventPort's thread from another thread. + // + // Unlike all other methods on this interface, `wake()` may be called from another thread, hence + // it is `const`. + // + // Technically speaking, `wake()` causes the target thread to cease sleeping and not to sleep + // again until `wait()` or `poll()` has returned true at least once. + // + // The default implementation throws an UNIMPLEMENTED exception. +}; + +class EventLoop { + // Represents a queue of events being executed in a loop. Most code won't interact with + // EventLoop directly, but instead use `Promise`s to interact with it indirectly. See the + // documentation for `Promise`. + // + // Each thread can have at most one current EventLoop. To make an `EventLoop` current for + // the thread, create a `WaitScope`. Async APIs require that the thread has a current EventLoop, + // or they will throw exceptions. APIs that use `Promise::wait()` additionally must explicitly + // be passed a reference to the `WaitScope` to make the caller aware that they might block. + // + // Generally, you will want to construct an `EventLoop` at the top level of your program, e.g. + // in the main() function, or in the start function of a thread. You can then use it to + // construct some promises and wait on the result. Example: + // + // int main() { + // // `loop` becomes the official EventLoop for the thread. + // MyEventPort eventPort; + // EventLoop loop(eventPort); + // + // // Now we can call an async function. + // Promise textPromise = getHttp("http://example.com"); + // + // // And we can wait for the promise to complete. Note that you can only use `wait()` + // // from the top level, not from inside a promise callback. + // String text = textPromise.wait(); + // print(text); + // return 0; + // } + // + // Most applications that do I/O will prefer to use `setupAsyncIo()` from `async-io.h` rather + // than allocate an `EventLoop` directly. + +public: + EventLoop(); + // Construct an `EventLoop` which does not receive external events at all. + + explicit EventLoop(EventPort& port); + // Construct an `EventLoop` which receives external events through the given `EventPort`. + + ~EventLoop() noexcept(false); + + void run(uint maxTurnCount = maxValue); + // Run the event loop for `maxTurnCount` turns or until there is nothing left to be done, + // whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will + // call the `EventPort`'s `setRunnable(false)` if the queue becomes empty. + + bool isRunnable(); + // Returns true if run() would currently do anything, or false if the queue is empty. + +private: + EventPort& port; + + bool running = false; + // True while looping -- wait() is then not allowed. + + bool lastRunnableState = false; + // What did we last pass to port.setRunnable()? + + _::Event* head = nullptr; + _::Event** tail = &head; + _::Event** depthFirstInsertPoint = &head; + + Own<_::TaskSetImpl> daemons; + + bool turn(); + void setRunnable(bool runnable); + void enterScope(); + void leaveScope(); + + friend void _::detach(kj::Promise&& promise); + friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, + WaitScope& waitScope); + friend class _::Event; + friend class WaitScope; +}; + +class WaitScope { + // Represents a scope in which asynchronous programming can occur. A `WaitScope` should usually + // be allocated on the stack and serves two purposes: + // * While the `WaitScope` exists, its `EventLoop` is registered as the current loop for the + // thread. Most operations dealing with `Promise` (including all of its methods) do not work + // unless the thread has a current `EventLoop`. + // * `WaitScope` may be passed to `Promise::wait()` to synchronously wait for a particular + // promise to complete. See `Promise::wait()` for an extended discussion. + +public: + inline explicit WaitScope(EventLoop& loop): loop(loop) { loop.enterScope(); } + inline ~WaitScope() { loop.leaveScope(); } + KJ_DISALLOW_COPY(WaitScope); + +private: + EventLoop& loop; + friend class EventLoop; + friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, + WaitScope& waitScope); +}; + +} // namespace kj + +#include "async-inl.h" + +#endif // KJ_ASYNC_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/common.h --- a/win32-mingw/include/kj/common.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/common.h Tue May 23 09:16:54 2017 +0100 @@ -1,1342 +1,1400 @@ -// 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. - -// Header that should be #included by everyone. -// -// This defines very simple utilities that are widely applicable. - -#ifndef KJ_COMMON_H_ -#define KJ_COMMON_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#ifndef KJ_NO_COMPILER_CHECK -#if __cplusplus < 201103L && !__CDT_PARSER__ && !_MSC_VER - #error "This code requires C++11. Either your compiler does not support it or it is not enabled." - #ifdef __GNUC__ - // Compiler claims compatibility with GCC, so presumably supports -std. - #error "Pass -std=c++11 on the compiler command line to enable C++11." - #endif -#endif - -#ifdef __GNUC__ - #if __clang__ - #if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2) - #warning "This library requires at least Clang 3.2." - #elif defined(__apple_build_version__) && __apple_build_version__ <= 4250028 - #warning "This library requires at least Clang 3.2. XCode 4.6's Clang, which claims to be "\ - "version 4.2 (wat?), is actually built from some random SVN revision between 3.1 "\ - "and 3.2. Unfortunately, it is insufficient for compiling this library. You can "\ - "download the real Clang 3.2 (or newer) from the Clang web site. Step-by-step "\ - "instructions can be found in Cap'n Proto's documentation: "\ - "http://kentonv.github.io/capnproto/install.html#clang_32_on_mac_osx" - #elif __cplusplus >= 201103L && !__has_include() - #warning "Your compiler supports C++11 but your C++ standard library does not. If your "\ - "system has libc++ installed (as should be the case on e.g. Mac OSX), try adding "\ - "-stdlib=libc++ to your CXXFLAGS." - #endif - #else - #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) - #warning "This library requires at least GCC 4.7." - #endif - #endif -#elif defined(_MSC_VER) - #if _MSC_VER < 1900 - #error "You need Visual Studio 2015 or better to compile this code." - #elif !CAPNP_LITE - // TODO(cleanup): This is KJ, but we're talking about Cap'n Proto. - #error "As of this writing, Cap'n Proto only supports Visual C++ in 'lite mode'; please #define CAPNP_LITE" - #endif -#else - #warning "I don't recognize your compiler. As of this writing, Clang and GCC are the only "\ - "known compilers with enough C++11 support for this library. "\ - "#define KJ_NO_COMPILER_CHECK to make this warning go away." -#endif -#endif - -#include -#include - -#if __linux__ && __cplusplus > 201200L -// Hack around stdlib bug with C++14 that exists on some Linux systems. -// Apparently in this mode the C library decides not to define gets() but the C++ library still -// tries to import it into the std namespace. This bug has been fixed at the source but is still -// widely present in the wild e.g. on Ubuntu 14.04. -#undef _GLIBCXX_HAVE_GETS -#endif - -#if defined(_MSC_VER) -#include // __popcnt -#endif - -// ======================================================================================= - -namespace kj { - -typedef unsigned int uint; -typedef unsigned char byte; - -// ======================================================================================= -// Common macros, especially for common yet compiler-specific features. - -// Detect whether RTTI and exceptions are enabled, assuming they are unless we have specific -// evidence to the contrary. Clients can always define KJ_NO_RTTI or KJ_NO_EXCEPTIONS explicitly -// to override these checks. -#ifdef __GNUC__ - #if !defined(KJ_NO_RTTI) && !__GXX_RTTI - #define KJ_NO_RTTI 1 - #endif - #if !defined(KJ_NO_EXCEPTIONS) && !__EXCEPTIONS - #define KJ_NO_EXCEPTIONS 1 - #endif -#elif defined(_MSC_VER) - #if !defined(KJ_NO_RTTI) && !defined(_CPPRTTI) - #define KJ_NO_RTTI 1 - #endif - #if !defined(KJ_NO_EXCEPTIONS) && !defined(_CPPUNWIND) - #define KJ_NO_EXCEPTIONS 1 - #endif -#endif - -#if !defined(KJ_DEBUG) && !defined(KJ_NDEBUG) -// Heuristically decide whether to enable debug mode. If DEBUG or NDEBUG is defined, use that. -// Otherwise, fall back to checking whether optimization is enabled. -#if defined(DEBUG) || defined(_DEBUG) -#define KJ_DEBUG -#elif defined(NDEBUG) -#define KJ_NDEBUG -#elif __OPTIMIZE__ -#define KJ_NDEBUG -#else -#define KJ_DEBUG -#endif -#endif - -#define KJ_DISALLOW_COPY(classname) \ - classname(const classname&) = delete; \ - classname& operator=(const classname&) = delete -// Deletes the implicit copy constructor and assignment operator. - -#ifdef __GNUC__ -#define KJ_LIKELY(condition) __builtin_expect(condition, true) -#define KJ_UNLIKELY(condition) __builtin_expect(condition, false) -// Branch prediction macros. Evaluates to the condition given, but also tells the compiler that we -// expect the condition to be true/false enough of the time that it's worth hard-coding branch -// prediction. -#else -#define KJ_LIKELY(condition) (condition) -#define KJ_UNLIKELY(condition) (condition) -#endif - -#if defined(KJ_DEBUG) || __NO_INLINE__ -#define KJ_ALWAYS_INLINE(prototype) inline prototype -// Don't force inline in debug mode. -#else -#if defined(_MSC_VER) -#define KJ_ALWAYS_INLINE(prototype) __forceinline prototype -#else -#define KJ_ALWAYS_INLINE(prototype) inline prototype __attribute__((always_inline)) -#endif -// Force a function to always be inlined. Apply only to the prototype, not to the definition. -#endif - -#if defined(_MSC_VER) -#define KJ_NOINLINE __declspec(noinline) -#else -#define KJ_NOINLINE __attribute__((noinline)) -#endif - -#if defined(_MSC_VER) -#define KJ_NORETURN(prototype) __declspec(noreturn) prototype -#define KJ_UNUSED -#define KJ_WARN_UNUSED_RESULT -// TODO(msvc): KJ_WARN_UNUSED_RESULT can use _Check_return_ on MSVC, but it's a prefix, so -// wrapping the whole prototype is needed. http://msdn.microsoft.com/en-us/library/jj159529.aspx -// Similarly, KJ_UNUSED could use __pragma(warning(suppress:...)), but again that's a prefix. -#else -#define KJ_NORETURN(prototype) prototype __attribute__((noreturn)) -#define KJ_UNUSED __attribute__((unused)) -#define KJ_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#endif - -#if __clang__ -#define KJ_UNUSED_MEMBER __attribute__((unused)) -// Inhibits "unused" warning for member variables. Only Clang produces such a warning, while GCC -// complains if the attribute is set on members. -#else -#define KJ_UNUSED_MEMBER -#endif - -#if __clang__ -#define KJ_DEPRECATED(reason) \ - __attribute__((deprecated(reason))) -#define KJ_UNAVAILABLE(reason) \ - __attribute__((unavailable(reason))) -#elif __GNUC__ -#define KJ_DEPRECATED(reason) \ - __attribute__((deprecated)) -#define KJ_UNAVAILABLE(reason) -#else -#define KJ_DEPRECATED(reason) -#define KJ_UNAVAILABLE(reason) -// TODO(msvc): Again, here, MSVC prefers a prefix, __declspec(deprecated). -#endif - -namespace _ { // private - -KJ_NORETURN(void inlineRequireFailure( - const char* file, int line, const char* expectation, const char* macroArgs, - const char* message = nullptr)); - -KJ_NORETURN(void unreachable()); - -} // namespace _ (private) - -#ifdef KJ_DEBUG -#if _MSC_VER -#define KJ_IREQUIRE(condition, ...) \ - if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ - __FILE__, __LINE__, #condition, "" #__VA_ARGS__, __VA_ARGS__) -// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to -// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that -// it will be enabled depending on whether the application is compiled in debug mode rather than -// whether libkj is. -#else -#define KJ_IREQUIRE(condition, ...) \ - if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ - __FILE__, __LINE__, #condition, #__VA_ARGS__, ##__VA_ARGS__) -// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to -// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that -// it will be enabled depending on whether the application is compiled in debug mode rather than -// whether libkj is. -#endif -#else -#define KJ_IREQUIRE(condition, ...) -#endif - -#define KJ_IASSERT KJ_IREQUIRE - -#define KJ_UNREACHABLE ::kj::_::unreachable(); -// Put this on code paths that cannot be reached to suppress compiler warnings about missing -// returns. - -#if __clang__ -#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT -#else -#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT KJ_UNREACHABLE -#endif - -// #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) -// -// Allocate an array, preferably on the stack, unless it is too big. On GCC this will use -// variable-sized arrays. For other compilers we could just use a fixed-size array. `minStack` -// is the stack array size to use if variable-width arrays are not supported. `maxStack` is the -// maximum stack array size if variable-width arrays *are* supported. -#if __GNUC__ && !__clang__ -#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ - size_t name##_size = (size); \ - bool name##_isOnStack = name##_size <= (maxStack); \ - type name##_stack[name##_isOnStack ? size : 0]; \ - ::kj::Array name##_heap = name##_isOnStack ? \ - nullptr : kj::heapArray(name##_size); \ - ::kj::ArrayPtr name = name##_isOnStack ? \ - kj::arrayPtr(name##_stack, name##_size) : name##_heap -#else -#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ - size_t name##_size = (size); \ - bool name##_isOnStack = name##_size <= (minStack); \ - type name##_stack[minStack]; \ - ::kj::Array name##_heap = name##_isOnStack ? \ - nullptr : kj::heapArray(name##_size); \ - ::kj::ArrayPtr name = name##_isOnStack ? \ - kj::arrayPtr(name##_stack, name##_size) : name##_heap -#endif - -#define KJ_CONCAT_(x, y) x##y -#define KJ_CONCAT(x, y) KJ_CONCAT_(x, y) -#define KJ_UNIQUE_NAME(prefix) KJ_CONCAT(prefix, __LINE__) -// Create a unique identifier name. We use concatenate __LINE__ rather than __COUNTER__ so that -// the name can be used multiple times in the same macro. - -#if _MSC_VER - -#define KJ_CONSTEXPR(...) __VA_ARGS__ -// Use in cases where MSVC barfs on constexpr. A replacement keyword (e.g. "const") can be -// provided, or just leave blank to remove the keyword entirely. -// -// TODO(msvc): Remove this hack once MSVC fully supports constexpr. - -#ifndef __restrict__ -#define __restrict__ __restrict -// TODO(msvc): Would it be better to define a KJ_RESTRICT macro? -#endif - -#pragma warning(disable: 4521 4522) -// This warning complains when there are two copy constructors, one for a const reference and -// one for a non-const reference. It is often quite necessary to do this in wrapper templates, -// therefore this warning is dumb and we disable it. - -#pragma warning(disable: 4458) -// Warns when a parameter name shadows a class member. Unfortunately my code does this a lot, -// since I don't use a special name format for members. - -#else // _MSC_VER -#define KJ_CONSTEXPR(...) constexpr -#endif - -// ======================================================================================= -// Template metaprogramming helpers. - -template struct NoInfer_ { typedef T Type; }; -template using NoInfer = typename NoInfer_::Type; -// Use NoInfer::Type in place of T for a template function parameter to prevent inference of -// the type based on the parameter value. - -template struct RemoveConst_ { typedef T Type; }; -template struct RemoveConst_ { typedef T Type; }; -template using RemoveConst = typename RemoveConst_::Type; - -template struct IsLvalueReference_ { static constexpr bool value = false; }; -template struct IsLvalueReference_ { static constexpr bool value = true; }; -template -inline constexpr bool isLvalueReference() { return IsLvalueReference_::value; } - -template struct Decay_ { typedef T Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template using Decay = typename Decay_::Type; - -template struct EnableIf_; -template <> struct EnableIf_ { typedef void Type; }; -template using EnableIf = typename EnableIf_::Type; -// Use like: -// -// template ()> -// void func(T&& t); - -template struct VoidSfinae_ { using Type = void; }; -template using VoidSfinae = typename VoidSfinae_::Type; -// Note: VoidSfinae is std::void_t from C++17. - -template -T instance() noexcept; -// Like std::declval, but doesn't transform T into an rvalue reference. If you want that, specify -// instance(). - -struct DisallowConstCopy { - // Inherit from this, or declare a member variable of this type, to prevent the class from being - // copyable from a const reference -- instead, it will only be copyable from non-const references. - // This is useful for enforcing transitive constness of contained pointers. - // - // For example, say you have a type T which contains a pointer. T has non-const methods which - // modify the value at that pointer, but T's const methods are designed to allow reading only. - // Unfortunately, if T has a regular copy constructor, someone can simply make a copy of T and - // then use it to modify the pointed-to value. However, if T inherits DisallowConstCopy, then - // callers will only be able to copy non-const instances of T. Ideally, there is some - // parallel type ImmutableT which is like a version of T that only has const methods, and can - // be copied from a const T. - // - // Note that due to C++ rules about implicit copy constructors and assignment operators, any - // type that contains or inherits from a type that disallows const copies will also automatically - // disallow const copies. Hey, cool, that's exactly what we want. - - DisallowConstCopy() = default; - DisallowConstCopy(DisallowConstCopy&) = default; - DisallowConstCopy(DisallowConstCopy&&) = default; - DisallowConstCopy& operator=(DisallowConstCopy&) = default; - DisallowConstCopy& operator=(DisallowConstCopy&&) = default; -}; - -template -struct DisallowConstCopyIfNotConst: public DisallowConstCopy { - // Inherit from this when implementing a template that contains a pointer to T and which should - // enforce transitive constness. If T is a const type, this has no effect. Otherwise, it is - // an alias for DisallowConstCopy. -}; - -template -struct DisallowConstCopyIfNotConst {}; - -template struct IsConst_ { static constexpr bool value = false; }; -template struct IsConst_ { static constexpr bool value = true; }; -template constexpr bool isConst() { return IsConst_::value; } - -template struct EnableIfNotConst_ { typedef T Type; }; -template struct EnableIfNotConst_; -template using EnableIfNotConst = typename EnableIfNotConst_::Type; - -template struct EnableIfConst_; -template struct EnableIfConst_ { typedef T Type; }; -template using EnableIfConst = typename EnableIfConst_::Type; - -template struct RemoveConstOrDisable_ { struct Type; }; -template struct RemoveConstOrDisable_ { typedef T Type; }; -template using RemoveConstOrDisable = typename RemoveConstOrDisable_::Type; - -template struct IsReference_ { static constexpr bool value = false; }; -template struct IsReference_ { static constexpr bool value = true; }; -template constexpr bool isReference() { return IsReference_::value; } - -template -struct PropagateConst_ { typedef To Type; }; -template -struct PropagateConst_ { typedef const To Type; }; -template -using PropagateConst = typename PropagateConst_::Type; - -namespace _ { // private - -template -T refIfLvalue(T&&); - -} // namespace _ (private) - -#define KJ_DECLTYPE_REF(exp) decltype(::kj::_::refIfLvalue(exp)) -// Like decltype(exp), but if exp is an lvalue, produces a reference type. -// -// int i; -// decltype(i) i1(i); // i1 has type int. -// KJ_DECLTYPE_REF(i + 1) i2(i + 1); // i2 has type int. -// KJ_DECLTYPE_REF(i) i3(i); // i3 has type int&. -// KJ_DECLTYPE_REF(kj::mv(i)) i4(kj::mv(i)); // i4 has type int. - -template -struct CanConvert_ { - static int sfinae(T); - static bool sfinae(...); -}; - -template -constexpr bool canConvert() { - return sizeof(CanConvert_::sfinae(instance())) == sizeof(int); -} - -#if __clang__ -template -constexpr bool canMemcpy() { - // Returns true if T can be copied using memcpy instead of using the copy constructor or - // assignment operator. - - // Clang unhelpfully defines __has_trivial_{copy,assign}(T) to be true if the copy constructor / - // assign operator are deleted, on the basis that a strict reading of the definition of "trivial" - // according to the standard says that deleted functions are in fact trivial. Meanwhile Clang - // provides these admittedly-better intrinsics, but GCC does not. - return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); -} -#else -template -constexpr bool canMemcpy() { - // Returns true if T can be copied using memcpy instead of using the copy constructor or - // assignment operator. - - // GCC defines these to mean what we want them to mean. - return __has_trivial_copy(T) && __has_trivial_assign(T); -} -#endif - -// ======================================================================================= -// Equivalents to std::move() and std::forward(), since these are very commonly needed and the -// std header pulls in lots of other stuff. -// -// We use abbreviated names mv and fwd because these helpers (especially mv) are so commonly used -// that the cost of typing more letters outweighs the cost of being slightly harder to understand -// when first encountered. - -template constexpr T&& mv(T& t) noexcept { return static_cast(t); } -template constexpr T&& fwd(NoInfer& t) noexcept { return static_cast(t); } - -template constexpr T cp(T& t) noexcept { return t; } -template constexpr T cp(const T& t) noexcept { return t; } -// Useful to force a copy, particularly to pass into a function that expects T&&. - -template struct MinType_; -template struct MinType_ { typedef T Type; }; -template struct MinType_ { typedef U Type; }; - -template -using MinType = typename MinType_::Type; -// Resolves to the smaller of the two input types. - -template -inline constexpr auto min(T&& a, U&& b) -> MinType, Decay> { - return a < b ? MinType, Decay>(a) : MinType, Decay>(b); -} - -template struct MaxType_; -template struct MaxType_ { typedef T Type; }; -template struct MaxType_ { typedef U Type; }; - -template -using MaxType = typename MaxType_= sizeof(U)>::Type; -// Resolves to the larger of the two input types. - -template -inline constexpr auto max(T&& a, U&& b) -> MaxType, Decay> { - return a > b ? MaxType, Decay>(a) : MaxType, Decay>(b); -} - -template -inline constexpr size_t size(T (&arr)[s]) { return s; } -template -inline constexpr size_t size(T&& arr) { return arr.size(); } -// Returns the size of the parameter, whether the parameter is a regular C array or a container -// with a `.size()` method. - -class MaxValue_ { -private: - template - inline constexpr T maxSigned() const { - return (1ull << (sizeof(T) * 8 - 1)) - 1; - } - template - inline constexpr T maxUnsigned() const { - return ~static_cast(0u); - } - -public: -#define _kJ_HANDLE_TYPE(T) \ - inline constexpr operator signed T() const { return MaxValue_::maxSigned < signed T>(); } \ - inline constexpr operator unsigned T() const { return MaxValue_::maxUnsigned(); } - _kJ_HANDLE_TYPE(char) - _kJ_HANDLE_TYPE(short) - _kJ_HANDLE_TYPE(int) - _kJ_HANDLE_TYPE(long) - _kJ_HANDLE_TYPE(long long) -#undef _kJ_HANDLE_TYPE - - inline constexpr operator char() const { - // `char` is different from both `signed char` and `unsigned char`, and may be signed or - // unsigned on different platforms. Ugh. - return char(-1) < 0 ? MaxValue_::maxSigned() - : MaxValue_::maxUnsigned(); - } -}; - -class MinValue_ { -private: - template - inline constexpr T minSigned() const { - return 1ull << (sizeof(T) * 8 - 1); - } - template - inline constexpr T minUnsigned() const { - return 0u; - } - -public: -#define _kJ_HANDLE_TYPE(T) \ - inline constexpr operator signed T() const { return MinValue_::minSigned < signed T>(); } \ - inline constexpr operator unsigned T() const { return MinValue_::minUnsigned(); } - _kJ_HANDLE_TYPE(char) - _kJ_HANDLE_TYPE(short) - _kJ_HANDLE_TYPE(int) - _kJ_HANDLE_TYPE(long) - _kJ_HANDLE_TYPE(long long) -#undef _kJ_HANDLE_TYPE - - inline constexpr operator char() const { - // `char` is different from both `signed char` and `unsigned char`, and may be signed or - // unsigned on different platforms. Ugh. - return char(-1) < 0 ? MinValue_::minSigned() - : MinValue_::minUnsigned(); - } -}; - -static KJ_CONSTEXPR(const) MaxValue_ maxValue = MaxValue_(); -// A special constant which, when cast to an integer type, takes on the maximum possible value of -// that type. This is useful to use as e.g. a parameter to a function because it will be robust -// in the face of changes to the parameter's type. -// -// `char` is not supported, but `signed char` and `unsigned char` are. - -static KJ_CONSTEXPR(const) MinValue_ minValue = MinValue_(); -// A special constant which, when cast to an integer type, takes on the minimum possible value -// of that type. This is useful to use as e.g. a parameter to a function because it will be robust -// in the face of changes to the parameter's type. -// -// `char` is not supported, but `signed char` and `unsigned char` are. - -#if __GNUC__ -inline constexpr float inf() { return __builtin_huge_valf(); } -inline constexpr float nan() { return __builtin_nanf(""); } - -#elif _MSC_VER - -// Do what MSVC math.h does -#pragma warning(push) -#pragma warning(disable: 4756) // "overflow in constant arithmetic" -inline constexpr float inf() { return (float)(1e300 * 1e300); } -#pragma warning(pop) - -float nan(); -// Unfortunatley, inf() * 0.0f produces a NaN with the sign bit set, whereas our preferred -// canonical NaN should not have the sign bit set. std::numeric_limits::quiet_NaN() -// returns the correct NaN, but we don't want to #include that here. So, we give up and make -// this out-of-line on MSVC. -// -// TODO(msvc): Can we do better? - -#else -#error "Not sure how to support your compiler." -#endif - -inline constexpr bool isNaN(float f) { return f != f; } -inline constexpr bool isNaN(double f) { return f != f; } - -inline int popCount(unsigned int x) { -#if defined(_MSC_VER) - return __popcnt(x); - // Note: __popcnt returns unsigned int, but the value is clearly guaranteed to fit into an int -#else - return __builtin_popcount(x); -#endif -} - -// ======================================================================================= -// Useful fake containers - -template -class Range { -public: - inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} - - class Iterator { - public: - Iterator() = default; - inline Iterator(const T& value): value(value) {} - - inline const T& operator* () const { return value; } - inline const T& operator[](size_t index) const { return value + index; } - inline Iterator& operator++() { ++value; return *this; } - inline Iterator operator++(int) { return Iterator(value++); } - inline Iterator& operator--() { --value; return *this; } - inline Iterator operator--(int) { return Iterator(value--); } - inline Iterator& operator+=(ptrdiff_t amount) { value += amount; return *this; } - inline Iterator& operator-=(ptrdiff_t amount) { value -= amount; return *this; } - inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value + amount); } - inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value - amount); } - inline ptrdiff_t operator- (const Iterator& other) const { return value - other.value; } - - inline bool operator==(const Iterator& other) const { return value == other.value; } - inline bool operator!=(const Iterator& other) const { return value != other.value; } - inline bool operator<=(const Iterator& other) const { return value <= other.value; } - inline bool operator>=(const Iterator& other) const { return value >= other.value; } - inline bool operator< (const Iterator& other) const { return value < other.value; } - inline bool operator> (const Iterator& other) const { return value > other.value; } - - private: - T value; - }; - - inline Iterator begin() const { return Iterator(begin_); } - inline Iterator end() const { return Iterator(end_); } - - inline auto size() const -> decltype(instance() - instance()) { return end_ - begin_; } - -private: - T begin_; - T end_; -}; - -template -inline constexpr Range> range(T begin, T end) { return Range>(begin, end); } -// Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end` -// (exclusive). Example: -// -// // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. -// for (int i: kj::range(1, 10)) { print(i); } - -template -inline constexpr Range indices(T&& container) { - // Shortcut for iterating over the indices of a container: - // - // for (size_t i: kj::indices(myArray)) { handle(myArray[i]); } - - return range(0, kj::size(container)); -} - -template -class Repeat { -public: - inline constexpr Repeat(const T& value, size_t count): value(value), count(count) {} - - class Iterator { - public: - Iterator() = default; - inline Iterator(const T& value, size_t index): value(value), index(index) {} - - inline const T& operator* () const { return value; } - inline const T& operator[](ptrdiff_t index) const { return value; } - inline Iterator& operator++() { ++index; return *this; } - inline Iterator operator++(int) { return Iterator(value, index++); } - inline Iterator& operator--() { --index; return *this; } - inline Iterator operator--(int) { return Iterator(value, index--); } - inline Iterator& operator+=(ptrdiff_t amount) { index += amount; return *this; } - inline Iterator& operator-=(ptrdiff_t amount) { index -= amount; return *this; } - inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value, index + amount); } - inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value, index - amount); } - inline ptrdiff_t operator- (const Iterator& other) const { return index - other.index; } - - inline bool operator==(const Iterator& other) const { return index == other.index; } - inline bool operator!=(const Iterator& other) const { return index != other.index; } - inline bool operator<=(const Iterator& other) const { return index <= other.index; } - inline bool operator>=(const Iterator& other) const { return index >= other.index; } - inline bool operator< (const Iterator& other) const { return index < other.index; } - inline bool operator> (const Iterator& other) const { return index > other.index; } - - private: - T value; - size_t index; - }; - - inline Iterator begin() const { return Iterator(value, 0); } - inline Iterator end() const { return Iterator(value, count); } - - inline size_t size() const { return count; } - -private: - T value; - size_t count; -}; - -template -inline constexpr Repeat> repeat(T&& value, size_t count) { - // Returns a fake iterable which contains `count` repeats of `value`. Useful for e.g. creating - // a bunch of spaces: `kj::repeat(' ', indent * 2)` - - return Repeat>(value, count); -} - -// ======================================================================================= -// Manually invoking constructors and destructors -// -// ctor(x, ...) and dtor(x) invoke x's constructor or destructor, respectively. - -// We want placement new, but we don't want to #include . operator new cannot be defined in -// a namespace, and defining it globally conflicts with the definition in . So we have to -// define a dummy type and an operator new that uses it. - -namespace _ { // private -struct PlacementNew {}; -} // namespace _ (private) -} // namespace kj - -inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { - return __p; -} - -inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} - -namespace kj { - -template -inline void ctor(T& location, Params&&... params) { - new (_::PlacementNew(), &location) T(kj::fwd(params)...); -} - -template -inline void dtor(T& location) { - location.~T(); -} - -// ======================================================================================= -// Maybe -// -// Use in cases where you want to indicate that a value may be null. Using Maybe instead of T* -// forces the caller to handle the null case in order to satisfy the compiler, thus reliably -// preventing null pointer dereferences at runtime. -// -// Maybe can be implicitly constructed from T and from nullptr. Additionally, it can be -// implicitly constructed from T*, in which case the pointer is checked for nullness at runtime. -// To read the value of a Maybe, do: -// -// KJ_IF_MAYBE(value, someFuncReturningMaybe()) { -// doSomething(*value); -// } else { -// maybeWasNull(); -// } -// -// KJ_IF_MAYBE's first parameter is a variable name which will be defined within the following -// block. The variable will behave like a (guaranteed non-null) pointer to the Maybe's value, -// though it may or may not actually be a pointer. -// -// Note that Maybe actually just wraps a pointer, whereas Maybe wraps a T and a boolean -// indicating nullness. - -template -class Maybe; - -namespace _ { // private - -#if _MSC_VER - // TODO(msvc): MSVC barfs on noexcept(instance().~T()) where T = kj::Exception and - // kj::_::Void. It and every other factorization I've tried produces: - // error C2325: 'kj::Blah' unexpected type to the right of '.~': expected 'void' -#define MSVC_NOEXCEPT_DTOR_WORKAROUND(T) __is_nothrow_destructible(T) -#else -#define MSVC_NOEXCEPT_DTOR_WORKAROUND(T) noexcept(instance().~T()) -#endif - -template -class NullableValue { - // Class whose interface behaves much like T*, but actually contains an instance of T and a - // boolean flag indicating nullness. - -public: - inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance()))) - : isSet(other.isSet) { - if (isSet) { - ctor(value, kj::mv(other.value)); - } - } - inline NullableValue(const NullableValue& other) - : isSet(other.isSet) { - if (isSet) { - ctor(value, other.value); - } - } - inline NullableValue(NullableValue& other) - : isSet(other.isSet) { - if (isSet) { - ctor(value, other.value); - } - } - inline ~NullableValue() noexcept(MSVC_NOEXCEPT_DTOR_WORKAROUND(T)) { - if (isSet) { - dtor(value); - } - } - - inline T& operator*() & { return value; } - inline const T& operator*() const & { return value; } - inline T&& operator*() && { return kj::mv(value); } - inline const T&& operator*() const && { return kj::mv(value); } - inline T* operator->() { return &value; } - inline const T* operator->() const { return &value; } - inline operator T*() { return isSet ? &value : nullptr; } - inline operator const T*() const { return isSet ? &value : nullptr; } - - template - inline T& emplace(Params&&... params) { - if (isSet) { - isSet = false; - dtor(value); - } - ctor(value, kj::fwd(params)...); - isSet = true; - return value; - } - -private: // internal interface used by friends only - inline NullableValue() noexcept: isSet(false) {} - inline NullableValue(T&& t) noexcept(noexcept(T(instance()))) - : isSet(true) { - ctor(value, kj::mv(t)); - } - inline NullableValue(T& t) - : isSet(true) { - ctor(value, t); - } - inline NullableValue(const T& t) - : isSet(true) { - ctor(value, t); - } - inline NullableValue(const T* t) - : isSet(t != nullptr) { - if (isSet) ctor(value, *t); - } - template - inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance()))) - : isSet(other.isSet) { - if (isSet) { - ctor(value, kj::mv(other.value)); - } - } - template - inline NullableValue(const NullableValue& other) - : isSet(other.isSet) { - if (isSet) { - ctor(value, other.value); - } - } - template - inline NullableValue(const NullableValue& other) - : isSet(other.isSet) { - if (isSet) { - ctor(value, *other.ptr); - } - } - inline NullableValue(decltype(nullptr)): isSet(false) {} - - inline NullableValue& operator=(NullableValue&& other) { - if (&other != this) { - // Careful about throwing destructors/constructors here. - if (isSet) { - isSet = false; - dtor(value); - } - if (other.isSet) { - ctor(value, kj::mv(other.value)); - isSet = true; - } - } - return *this; - } - - inline NullableValue& operator=(NullableValue& other) { - if (&other != this) { - // Careful about throwing destructors/constructors here. - if (isSet) { - isSet = false; - dtor(value); - } - if (other.isSet) { - ctor(value, other.value); - isSet = true; - } - } - return *this; - } - - inline NullableValue& operator=(const NullableValue& other) { - if (&other != this) { - // Careful about throwing destructors/constructors here. - if (isSet) { - isSet = false; - dtor(value); - } - if (other.isSet) { - ctor(value, other.value); - isSet = true; - } - } - return *this; - } - - inline bool operator==(decltype(nullptr)) const { return !isSet; } - inline bool operator!=(decltype(nullptr)) const { return isSet; } - -private: - bool isSet; - -#if _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4624) -// Warns that the anonymous union has a deleted destructor when T is non-trivial. This warning -// seems broken. -#endif - - union { - T value; - }; - -#if _MSC_VER -#pragma warning(pop) -#endif - - friend class kj::Maybe; - template - friend NullableValue&& readMaybe(Maybe&& maybe); -}; - -template -inline NullableValue&& readMaybe(Maybe&& maybe) { return kj::mv(maybe.ptr); } -template -inline T* readMaybe(Maybe& maybe) { return maybe.ptr; } -template -inline const T* readMaybe(const Maybe& maybe) { return maybe.ptr; } -template -inline T* readMaybe(Maybe&& maybe) { return maybe.ptr; } -template -inline T* readMaybe(const Maybe& maybe) { return maybe.ptr; } - -template -inline T* readMaybe(T* ptr) { return ptr; } -// Allow KJ_IF_MAYBE to work on regular pointers. - -} // namespace _ (private) - -#define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp)) - -template -class Maybe { - // A T, or nullptr. - - // IF YOU CHANGE THIS CLASS: Note that there is a specialization of it in memory.h. - -public: - Maybe(): ptr(nullptr) {} - Maybe(T&& t) noexcept(noexcept(T(instance()))): ptr(kj::mv(t)) {} - Maybe(T& t): ptr(t) {} - Maybe(const T& t): ptr(t) {} - Maybe(const T* t) noexcept: ptr(t) {} - Maybe(Maybe&& other) noexcept(noexcept(T(instance()))): ptr(kj::mv(other.ptr)) {} - Maybe(const Maybe& other): ptr(other.ptr) {} - Maybe(Maybe& other): ptr(other.ptr) {} - - template - Maybe(Maybe&& other) noexcept(noexcept(T(instance()))) { - KJ_IF_MAYBE(val, kj::mv(other)) { - ptr = *val; - } - } - template - Maybe(const Maybe& other) { - KJ_IF_MAYBE(val, other) { - ptr = *val; - } - } - - Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} - - template - inline T& emplace(Params&&... params) { - // Replace this Maybe's content with a new value constructed by passing the given parametrs to - // T's constructor. This can be used to initialize a Maybe without copying or even moving a T. - // Returns a reference to the newly-constructed value. - - return ptr.emplace(kj::fwd(params)...); - } - - inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } - inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; } - inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; } - - inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } - - T& orDefault(T& defaultValue) { - if (ptr == nullptr) { - return defaultValue; - } else { - return *ptr; - } - } - const T& orDefault(const T& defaultValue) const { - if (ptr == nullptr) { - return defaultValue; - } else { - return *ptr; - } - } - - template - auto map(Func&& f) & -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(*ptr); - } - } - - template - auto map(Func&& f) const & -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(*ptr); - } - } - - template - auto map(Func&& f) && -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(kj::mv(*ptr)); - } - } - - template - auto map(Func&& f) const && -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(kj::mv(*ptr)); - } - } - -private: - _::NullableValue ptr; - - template - friend class Maybe; - template - friend _::NullableValue&& _::readMaybe(Maybe&& maybe); - template - friend U* _::readMaybe(Maybe& maybe); - template - friend const U* _::readMaybe(const Maybe& maybe); -}; - -template -class Maybe: public DisallowConstCopyIfNotConst { -public: - Maybe() noexcept: ptr(nullptr) {} - Maybe(T& t) noexcept: ptr(&t) {} - Maybe(T* t) noexcept: ptr(t) {} - - template - inline Maybe(Maybe& other) noexcept: ptr(other.ptr) {} - template - inline Maybe(const Maybe& other) noexcept: ptr(other.ptr) {} - inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} - - inline Maybe& operator=(T& other) noexcept { ptr = &other; return *this; } - inline Maybe& operator=(T* other) noexcept { ptr = other; return *this; } - template - inline Maybe& operator=(Maybe& other) noexcept { ptr = other.ptr; return *this; } - template - inline Maybe& operator=(const Maybe& other) noexcept { ptr = other.ptr; return *this; } - - inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } - - T& orDefault(T& defaultValue) { - if (ptr == nullptr) { - return defaultValue; - } else { - return *ptr; - } - } - const T& orDefault(const T& defaultValue) const { - if (ptr == nullptr) { - return defaultValue; - } else { - return *ptr; - } - } - - template - auto map(Func&& f) -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(*ptr); - } - } - -private: - T* ptr; - - template - friend class Maybe; - template - friend U* _::readMaybe(Maybe&& maybe); - template - friend U* _::readMaybe(const Maybe& maybe); -}; - -// ======================================================================================= -// ArrayPtr -// -// So common that we put it in common.h rather than array.h. - -template -class ArrayPtr: public DisallowConstCopyIfNotConst { - // A pointer to an array. Includes a size. Like any pointer, it doesn't own the target data, - // and passing by value only copies the pointer, not the target. - -public: - inline constexpr ArrayPtr(): ptr(nullptr), size_(0) {} - inline constexpr ArrayPtr(decltype(nullptr)): ptr(nullptr), size_(0) {} - inline constexpr ArrayPtr(T* ptr, size_t size): ptr(ptr), size_(size) {} - inline constexpr ArrayPtr(T* begin, T* end): ptr(begin), size_(end - begin) {} - inline KJ_CONSTEXPR() ArrayPtr(::std::initializer_list> init) - : ptr(init.begin()), size_(init.size()) {} - - template - inline constexpr ArrayPtr(T (&native)[size]): ptr(native), size_(size) {} - // Construct an ArrayPtr from a native C-style array. - - inline operator ArrayPtr() const { - return ArrayPtr(ptr, size_); - } - inline ArrayPtr asConst() const { - return ArrayPtr(ptr, size_); - } - - inline size_t size() const { return size_; } - inline const T& operator[](size_t index) const { - KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); - return ptr[index]; - } - inline T& operator[](size_t index) { - KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); - return ptr[index]; - } - - inline T* begin() { return ptr; } - inline T* end() { return ptr + size_; } - inline T& front() { return *ptr; } - inline T& back() { return *(ptr + size_ - 1); } - inline const T* begin() const { return ptr; } - inline const T* end() const { return ptr + size_; } - inline const T& front() const { return *ptr; } - inline const T& back() const { return *(ptr + size_ - 1); } - - inline ArrayPtr slice(size_t start, size_t end) const { - KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); - return ArrayPtr(ptr + start, end - start); - } - inline ArrayPtr slice(size_t start, size_t end) { - KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); - return ArrayPtr(ptr + start, end - start); - } - - inline ArrayPtr> asBytes() const { - // Reinterpret the array as a byte array. This is explicitly legal under C++ aliasing - // rules. - return { reinterpret_cast*>(ptr), size_ * sizeof(T) }; - } - inline ArrayPtr> asChars() const { - // Reinterpret the array as a char array. This is explicitly legal under C++ aliasing - // rules. - return { reinterpret_cast*>(ptr), size_ * sizeof(T) }; - } - - inline bool operator==(decltype(nullptr)) const { return size_ == 0; } - inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } - - inline bool operator==(const ArrayPtr& other) const { - if (size_ != other.size_) return false; - for (size_t i = 0; i < size_; i++) { - if (ptr[i] != other[i]) return false; - } - return true; - } - inline bool operator!=(const ArrayPtr& other) const { return !(*this == other); } - -private: - T* ptr; - size_t size_; -}; - -template -inline constexpr ArrayPtr arrayPtr(T* ptr, size_t size) { - // Use this function to construct ArrayPtrs without writing out the type name. - return ArrayPtr(ptr, size); -} - -template -inline constexpr ArrayPtr arrayPtr(T* begin, T* end) { - // Use this function to construct ArrayPtrs without writing out the type name. - return ArrayPtr(begin, end); -} - -// ======================================================================================= -// Casts - -template -To implicitCast(From&& from) { - // `implicitCast(value)` casts `value` to type `T` only if the conversion is implicit. Useful - // for e.g. resolving ambiguous overloads without sacrificing type-safety. - return kj::fwd(from); -} - -template -Maybe dynamicDowncastIfAvailable(From& from) { - // If RTTI is disabled, always returns nullptr. Otherwise, works like dynamic_cast. Useful - // in situations where dynamic_cast could allow an optimization, but isn't strictly necessary - // for correctness. It is highly recommended that you try to arrange all your dynamic_casts - // this way, as a dynamic_cast that is necessary for correctness implies a flaw in the interface - // design. - - // Force a compile error if To is not a subtype of From. Cross-casting is rare; if it is needed - // we should have a separate cast function like dynamicCrosscastIfAvailable(). - if (false) { - kj::implicitCast(kj::implicitCast(nullptr)); - } - -#if KJ_NO_RTTI - return nullptr; -#else - return dynamic_cast(&from); -#endif -} - -template -To& downcast(From& from) { - // Down-cast a value to a sub-type, asserting that the cast is valid. In opt mode this is a - // static_cast, but in debug mode (when RTTI is enabled) a dynamic_cast will be used to verify - // that the value really has the requested type. - - // Force a compile error if To is not a subtype of From. - if (false) { - kj::implicitCast(kj::implicitCast(nullptr)); - } - -#if !KJ_NO_RTTI - KJ_IREQUIRE(dynamic_cast(&from) != nullptr, "Value cannot be downcast() to requested type."); -#endif - - return static_cast(from); -} - -// ======================================================================================= -// Defer - -namespace _ { // private - -template -class Deferred { -public: - inline Deferred(Func&& func): func(kj::fwd(func)), canceled(false) {} - inline ~Deferred() noexcept(false) { if (!canceled) func(); } - KJ_DISALLOW_COPY(Deferred); - - // This move constructor is usually optimized away by the compiler. - inline Deferred(Deferred&& other): func(kj::mv(other.func)), canceled(false) { - other.canceled = true; - } -private: - Func func; - bool canceled; -}; - -} // namespace _ (private) - -template -_::Deferred defer(Func&& func) { - // Returns an object which will invoke the given functor in its destructor. The object is not - // copyable but is movable with the semantics you'd expect. Since the return type is private, - // you need to assign to an `auto` variable. - // - // The KJ_DEFER macro provides slightly more convenient syntax for the common case where you - // want some code to run at current scope exit. - - return _::Deferred(kj::fwd(func)); -} - -#define KJ_DEFER(code) auto KJ_UNIQUE_NAME(_kjDefer) = ::kj::defer([&](){code;}) -// Run the given code when the function exits, whether by return or exception. - -} // namespace kj - -#endif // KJ_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. + +// Header that should be #included by everyone. +// +// This defines very simple utilities that are widely applicable. + +#ifndef KJ_COMMON_H_ +#define KJ_COMMON_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#ifndef KJ_NO_COMPILER_CHECK +#if __cplusplus < 201103L && !__CDT_PARSER__ && !_MSC_VER + #error "This code requires C++11. Either your compiler does not support it or it is not enabled." + #ifdef __GNUC__ + // Compiler claims compatibility with GCC, so presumably supports -std. + #error "Pass -std=c++11 on the compiler command line to enable C++11." + #endif +#endif + +#ifdef __GNUC__ + #if __clang__ + #if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2) + #warning "This library requires at least Clang 3.2." + #elif defined(__apple_build_version__) && __apple_build_version__ <= 4250028 + #warning "This library requires at least Clang 3.2. XCode 4.6's Clang, which claims to be "\ + "version 4.2 (wat?), is actually built from some random SVN revision between 3.1 "\ + "and 3.2. Unfortunately, it is insufficient for compiling this library. You can "\ + "download the real Clang 3.2 (or newer) from the Clang web site. Step-by-step "\ + "instructions can be found in Cap'n Proto's documentation: "\ + "http://kentonv.github.io/capnproto/install.html#clang_32_on_mac_osx" + #elif __cplusplus >= 201103L && !__has_include() + #warning "Your compiler supports C++11 but your C++ standard library does not. If your "\ + "system has libc++ installed (as should be the case on e.g. Mac OSX), try adding "\ + "-stdlib=libc++ to your CXXFLAGS." + #endif + #else + #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) + #warning "This library requires at least GCC 4.7." + #endif + #endif +#elif defined(_MSC_VER) + #if _MSC_VER < 1900 + #error "You need Visual Studio 2015 or better to compile this code." + #endif +#else + #warning "I don't recognize your compiler. As of this writing, Clang and GCC are the only "\ + "known compilers with enough C++11 support for this library. "\ + "#define KJ_NO_COMPILER_CHECK to make this warning go away." +#endif +#endif + +#include +#include + +#if __linux__ && __cplusplus > 201200L +// Hack around stdlib bug with C++14 that exists on some Linux systems. +// Apparently in this mode the C library decides not to define gets() but the C++ library still +// tries to import it into the std namespace. This bug has been fixed at the source but is still +// widely present in the wild e.g. on Ubuntu 14.04. +#undef _GLIBCXX_HAVE_GETS +#endif + +#if defined(_MSC_VER) +#ifndef NOMINMAX +#define NOMINMAX 1 +#endif +#include // __popcnt +#endif + +// ======================================================================================= + +namespace kj { + +typedef unsigned int uint; +typedef unsigned char byte; + +// ======================================================================================= +// Common macros, especially for common yet compiler-specific features. + +// Detect whether RTTI and exceptions are enabled, assuming they are unless we have specific +// evidence to the contrary. Clients can always define KJ_NO_RTTI or KJ_NO_EXCEPTIONS explicitly +// to override these checks. +#ifdef __GNUC__ + #if !defined(KJ_NO_RTTI) && !__GXX_RTTI + #define KJ_NO_RTTI 1 + #endif + #if !defined(KJ_NO_EXCEPTIONS) && !__EXCEPTIONS + #define KJ_NO_EXCEPTIONS 1 + #endif +#elif defined(_MSC_VER) + #if !defined(KJ_NO_RTTI) && !defined(_CPPRTTI) + #define KJ_NO_RTTI 1 + #endif + #if !defined(KJ_NO_EXCEPTIONS) && !defined(_CPPUNWIND) + #define KJ_NO_EXCEPTIONS 1 + #endif +#endif + +#if !defined(KJ_DEBUG) && !defined(KJ_NDEBUG) +// Heuristically decide whether to enable debug mode. If DEBUG or NDEBUG is defined, use that. +// Otherwise, fall back to checking whether optimization is enabled. +#if defined(DEBUG) || defined(_DEBUG) +#define KJ_DEBUG +#elif defined(NDEBUG) +#define KJ_NDEBUG +#elif __OPTIMIZE__ +#define KJ_NDEBUG +#else +#define KJ_DEBUG +#endif +#endif + +#define KJ_DISALLOW_COPY(classname) \ + classname(const classname&) = delete; \ + classname& operator=(const classname&) = delete +// Deletes the implicit copy constructor and assignment operator. + +#ifdef __GNUC__ +#define KJ_LIKELY(condition) __builtin_expect(condition, true) +#define KJ_UNLIKELY(condition) __builtin_expect(condition, false) +// Branch prediction macros. Evaluates to the condition given, but also tells the compiler that we +// expect the condition to be true/false enough of the time that it's worth hard-coding branch +// prediction. +#else +#define KJ_LIKELY(condition) (condition) +#define KJ_UNLIKELY(condition) (condition) +#endif + +#if defined(KJ_DEBUG) || __NO_INLINE__ +#define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ +// Don't force inline in debug mode. +#else +#if defined(_MSC_VER) +#define KJ_ALWAYS_INLINE(...) __forceinline __VA_ARGS__ +#else +#define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ __attribute__((always_inline)) +#endif +// Force a function to always be inlined. Apply only to the prototype, not to the definition. +#endif + +#if defined(_MSC_VER) +#define KJ_NOINLINE __declspec(noinline) +#else +#define KJ_NOINLINE __attribute__((noinline)) +#endif + +#if defined(_MSC_VER) +#define KJ_NORETURN(prototype) __declspec(noreturn) prototype +#define KJ_UNUSED +#define KJ_WARN_UNUSED_RESULT +// TODO(msvc): KJ_WARN_UNUSED_RESULT can use _Check_return_ on MSVC, but it's a prefix, so +// wrapping the whole prototype is needed. http://msdn.microsoft.com/en-us/library/jj159529.aspx +// Similarly, KJ_UNUSED could use __pragma(warning(suppress:...)), but again that's a prefix. +#else +#define KJ_NORETURN(prototype) prototype __attribute__((noreturn)) +#define KJ_UNUSED __attribute__((unused)) +#define KJ_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#endif + +#if __clang__ +#define KJ_UNUSED_MEMBER __attribute__((unused)) +// Inhibits "unused" warning for member variables. Only Clang produces such a warning, while GCC +// complains if the attribute is set on members. +#else +#define KJ_UNUSED_MEMBER +#endif + +#if __clang__ +#define KJ_DEPRECATED(reason) \ + __attribute__((deprecated(reason))) +#define KJ_UNAVAILABLE(reason) \ + __attribute__((unavailable(reason))) +#elif __GNUC__ +#define KJ_DEPRECATED(reason) \ + __attribute__((deprecated)) +#define KJ_UNAVAILABLE(reason) +#else +#define KJ_DEPRECATED(reason) +#define KJ_UNAVAILABLE(reason) +// TODO(msvc): Again, here, MSVC prefers a prefix, __declspec(deprecated). +#endif + +namespace _ { // private + +KJ_NORETURN(void inlineRequireFailure( + const char* file, int line, const char* expectation, const char* macroArgs, + const char* message = nullptr)); + +KJ_NORETURN(void unreachable()); + +} // namespace _ (private) + +#ifdef KJ_DEBUG +#if _MSC_VER +#define KJ_IREQUIRE(condition, ...) \ + if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ + __FILE__, __LINE__, #condition, "" #__VA_ARGS__, __VA_ARGS__) +// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to +// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that +// it will be enabled depending on whether the application is compiled in debug mode rather than +// whether libkj is. +#else +#define KJ_IREQUIRE(condition, ...) \ + if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ + __FILE__, __LINE__, #condition, #__VA_ARGS__, ##__VA_ARGS__) +// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to +// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that +// it will be enabled depending on whether the application is compiled in debug mode rather than +// whether libkj is. +#endif +#else +#define KJ_IREQUIRE(condition, ...) +#endif + +#define KJ_IASSERT KJ_IREQUIRE + +#define KJ_UNREACHABLE ::kj::_::unreachable(); +// Put this on code paths that cannot be reached to suppress compiler warnings about missing +// returns. + +#if __clang__ +#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT +#else +#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT KJ_UNREACHABLE +#endif + +// #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) +// +// Allocate an array, preferably on the stack, unless it is too big. On GCC this will use +// variable-sized arrays. For other compilers we could just use a fixed-size array. `minStack` +// is the stack array size to use if variable-width arrays are not supported. `maxStack` is the +// maximum stack array size if variable-width arrays *are* supported. +#if __GNUC__ && !__clang__ +#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ + size_t name##_size = (size); \ + bool name##_isOnStack = name##_size <= (maxStack); \ + type name##_stack[name##_isOnStack ? size : 0]; \ + ::kj::Array name##_heap = name##_isOnStack ? \ + nullptr : kj::heapArray(name##_size); \ + ::kj::ArrayPtr name = name##_isOnStack ? \ + kj::arrayPtr(name##_stack, name##_size) : name##_heap +#else +#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ + size_t name##_size = (size); \ + bool name##_isOnStack = name##_size <= (minStack); \ + type name##_stack[minStack]; \ + ::kj::Array name##_heap = name##_isOnStack ? \ + nullptr : kj::heapArray(name##_size); \ + ::kj::ArrayPtr name = name##_isOnStack ? \ + kj::arrayPtr(name##_stack, name##_size) : name##_heap +#endif + +#define KJ_CONCAT_(x, y) x##y +#define KJ_CONCAT(x, y) KJ_CONCAT_(x, y) +#define KJ_UNIQUE_NAME(prefix) KJ_CONCAT(prefix, __LINE__) +// Create a unique identifier name. We use concatenate __LINE__ rather than __COUNTER__ so that +// the name can be used multiple times in the same macro. + +#if _MSC_VER + +#define KJ_CONSTEXPR(...) __VA_ARGS__ +// Use in cases where MSVC barfs on constexpr. A replacement keyword (e.g. "const") can be +// provided, or just leave blank to remove the keyword entirely. +// +// TODO(msvc): Remove this hack once MSVC fully supports constexpr. + +#ifndef __restrict__ +#define __restrict__ __restrict +// TODO(msvc): Would it be better to define a KJ_RESTRICT macro? +#endif + +#pragma warning(disable: 4521 4522) +// This warning complains when there are two copy constructors, one for a const reference and +// one for a non-const reference. It is often quite necessary to do this in wrapper templates, +// therefore this warning is dumb and we disable it. + +#pragma warning(disable: 4458) +// Warns when a parameter name shadows a class member. Unfortunately my code does this a lot, +// since I don't use a special name format for members. + +#else // _MSC_VER +#define KJ_CONSTEXPR(...) constexpr +#endif + +// ======================================================================================= +// Template metaprogramming helpers. + +template struct NoInfer_ { typedef T Type; }; +template using NoInfer = typename NoInfer_::Type; +// Use NoInfer::Type in place of T for a template function parameter to prevent inference of +// the type based on the parameter value. + +template struct RemoveConst_ { typedef T Type; }; +template struct RemoveConst_ { typedef T Type; }; +template using RemoveConst = typename RemoveConst_::Type; + +template struct IsLvalueReference_ { static constexpr bool value = false; }; +template struct IsLvalueReference_ { static constexpr bool value = true; }; +template +inline constexpr bool isLvalueReference() { return IsLvalueReference_::value; } + +template struct Decay_ { typedef T Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template using Decay = typename Decay_::Type; + +template struct EnableIf_; +template <> struct EnableIf_ { typedef void Type; }; +template using EnableIf = typename EnableIf_::Type; +// Use like: +// +// template ()> +// void func(T&& t); + +template struct VoidSfinae_ { using Type = void; }; +template using VoidSfinae = typename VoidSfinae_::Type; +// Note: VoidSfinae is std::void_t from C++17. + +template +T instance() noexcept; +// Like std::declval, but doesn't transform T into an rvalue reference. If you want that, specify +// instance(). + +struct DisallowConstCopy { + // Inherit from this, or declare a member variable of this type, to prevent the class from being + // copyable from a const reference -- instead, it will only be copyable from non-const references. + // This is useful for enforcing transitive constness of contained pointers. + // + // For example, say you have a type T which contains a pointer. T has non-const methods which + // modify the value at that pointer, but T's const methods are designed to allow reading only. + // Unfortunately, if T has a regular copy constructor, someone can simply make a copy of T and + // then use it to modify the pointed-to value. However, if T inherits DisallowConstCopy, then + // callers will only be able to copy non-const instances of T. Ideally, there is some + // parallel type ImmutableT which is like a version of T that only has const methods, and can + // be copied from a const T. + // + // Note that due to C++ rules about implicit copy constructors and assignment operators, any + // type that contains or inherits from a type that disallows const copies will also automatically + // disallow const copies. Hey, cool, that's exactly what we want. + +#if CAPNP_DEBUG_TYPES + // Alas! Declaring a defaulted non-const copy constructor tickles a bug which causes GCC and + // Clang to disagree on ABI, using different calling conventions to pass this type, leading to + // immediate segfaults. See: + // https://bugs.llvm.org/show_bug.cgi?id=23764 + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58074 + // + // Because of this, we can't use this technique. We guard it by CAPNP_DEBUG_TYPES so that it + // still applies to the Cap'n Proto developers during internal testing. + + DisallowConstCopy() = default; + DisallowConstCopy(DisallowConstCopy&) = default; + DisallowConstCopy(DisallowConstCopy&&) = default; + DisallowConstCopy& operator=(DisallowConstCopy&) = default; + DisallowConstCopy& operator=(DisallowConstCopy&&) = default; +#endif +}; + +#if _MSC_VER + +#define KJ_CPCAP(obj) obj=::kj::cp(obj) +// TODO(msvc): MSVC refuses to invoke non-const versions of copy constructors in by-value lambda +// captures. Wrap your captured object in this macro to force the compiler to perform a copy. +// Example: +// +// struct Foo: DisallowConstCopy {}; +// Foo foo; +// auto lambda = [KJ_CPCAP(foo)] {}; + +#else + +#define KJ_CPCAP(obj) obj +// Clang and gcc both already perform copy capturing correctly with non-const copy constructors. + +#endif + +template +struct DisallowConstCopyIfNotConst: public DisallowConstCopy { + // Inherit from this when implementing a template that contains a pointer to T and which should + // enforce transitive constness. If T is a const type, this has no effect. Otherwise, it is + // an alias for DisallowConstCopy. +}; + +template +struct DisallowConstCopyIfNotConst {}; + +template struct IsConst_ { static constexpr bool value = false; }; +template struct IsConst_ { static constexpr bool value = true; }; +template constexpr bool isConst() { return IsConst_::value; } + +template struct EnableIfNotConst_ { typedef T Type; }; +template struct EnableIfNotConst_; +template using EnableIfNotConst = typename EnableIfNotConst_::Type; + +template struct EnableIfConst_; +template struct EnableIfConst_ { typedef T Type; }; +template using EnableIfConst = typename EnableIfConst_::Type; + +template struct RemoveConstOrDisable_ { struct Type; }; +template struct RemoveConstOrDisable_ { typedef T Type; }; +template using RemoveConstOrDisable = typename RemoveConstOrDisable_::Type; + +template struct IsReference_ { static constexpr bool value = false; }; +template struct IsReference_ { static constexpr bool value = true; }; +template constexpr bool isReference() { return IsReference_::value; } + +template +struct PropagateConst_ { typedef To Type; }; +template +struct PropagateConst_ { typedef const To Type; }; +template +using PropagateConst = typename PropagateConst_::Type; + +namespace _ { // private + +template +T refIfLvalue(T&&); + +} // namespace _ (private) + +#define KJ_DECLTYPE_REF(exp) decltype(::kj::_::refIfLvalue(exp)) +// Like decltype(exp), but if exp is an lvalue, produces a reference type. +// +// int i; +// decltype(i) i1(i); // i1 has type int. +// KJ_DECLTYPE_REF(i + 1) i2(i + 1); // i2 has type int. +// KJ_DECLTYPE_REF(i) i3(i); // i3 has type int&. +// KJ_DECLTYPE_REF(kj::mv(i)) i4(kj::mv(i)); // i4 has type int. + +template +struct CanConvert_ { + static int sfinae(T); + static bool sfinae(...); +}; + +template +constexpr bool canConvert() { + return sizeof(CanConvert_::sfinae(instance())) == sizeof(int); +} + +#if __GNUC__ && !__clang__ && __GNUC__ < 5 +template +constexpr bool canMemcpy() { + // Returns true if T can be copied using memcpy instead of using the copy constructor or + // assignment operator. + + // GCC 4 does not have __is_trivially_constructible and friends, and there doesn't seem to be + // any reliable alternative. __has_trivial_copy() and __has_trivial_assign() return the right + // thing at one point but later on they changed such that a deleted copy constructor was + // considered "trivial" (apparently technically correct, though useless). So, on GCC 4 we give up + // and assume we can't memcpy() at all, and must explicitly copy-construct everything. + return false; +} +#define KJ_ASSERT_CAN_MEMCPY(T) +#else +template +constexpr bool canMemcpy() { + // Returns true if T can be copied using memcpy instead of using the copy constructor or + // assignment operator. + + return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); +} +#define KJ_ASSERT_CAN_MEMCPY(T) \ + static_assert(kj::canMemcpy(), "this code expects this type to be memcpy()-able"); +#endif + +// ======================================================================================= +// Equivalents to std::move() and std::forward(), since these are very commonly needed and the +// std header pulls in lots of other stuff. +// +// We use abbreviated names mv and fwd because these helpers (especially mv) are so commonly used +// that the cost of typing more letters outweighs the cost of being slightly harder to understand +// when first encountered. + +template constexpr T&& mv(T& t) noexcept { return static_cast(t); } +template constexpr T&& fwd(NoInfer& t) noexcept { return static_cast(t); } + +template constexpr T cp(T& t) noexcept { return t; } +template constexpr T cp(const T& t) noexcept { return t; } +// Useful to force a copy, particularly to pass into a function that expects T&&. + +template struct ChooseType_; +template struct ChooseType_ { typedef T Type; }; +template struct ChooseType_ { typedef T Type; }; +template struct ChooseType_ { typedef U Type; }; + +template +using WiderType = typename ChooseType_= sizeof(U)>::Type; + +template +inline constexpr auto min(T&& a, U&& b) -> WiderType, Decay> { + return a < b ? WiderType, Decay>(a) : WiderType, Decay>(b); +} + +template +inline constexpr auto max(T&& a, U&& b) -> WiderType, Decay> { + return a > b ? WiderType, Decay>(a) : WiderType, Decay>(b); +} + +template +inline constexpr size_t size(T (&arr)[s]) { return s; } +template +inline constexpr size_t size(T&& arr) { return arr.size(); } +// Returns the size of the parameter, whether the parameter is a regular C array or a container +// with a `.size()` method. + +class MaxValue_ { +private: + template + inline constexpr T maxSigned() const { + return (1ull << (sizeof(T) * 8 - 1)) - 1; + } + template + inline constexpr T maxUnsigned() const { + return ~static_cast(0u); + } + +public: +#define _kJ_HANDLE_TYPE(T) \ + inline constexpr operator signed T() const { return MaxValue_::maxSigned < signed T>(); } \ + inline constexpr operator unsigned T() const { return MaxValue_::maxUnsigned(); } + _kJ_HANDLE_TYPE(char) + _kJ_HANDLE_TYPE(short) + _kJ_HANDLE_TYPE(int) + _kJ_HANDLE_TYPE(long) + _kJ_HANDLE_TYPE(long long) +#undef _kJ_HANDLE_TYPE + + inline constexpr operator char() const { + // `char` is different from both `signed char` and `unsigned char`, and may be signed or + // unsigned on different platforms. Ugh. + return char(-1) < 0 ? MaxValue_::maxSigned() + : MaxValue_::maxUnsigned(); + } +}; + +class MinValue_ { +private: + template + inline constexpr T minSigned() const { + return 1ull << (sizeof(T) * 8 - 1); + } + template + inline constexpr T minUnsigned() const { + return 0u; + } + +public: +#define _kJ_HANDLE_TYPE(T) \ + inline constexpr operator signed T() const { return MinValue_::minSigned < signed T>(); } \ + inline constexpr operator unsigned T() const { return MinValue_::minUnsigned(); } + _kJ_HANDLE_TYPE(char) + _kJ_HANDLE_TYPE(short) + _kJ_HANDLE_TYPE(int) + _kJ_HANDLE_TYPE(long) + _kJ_HANDLE_TYPE(long long) +#undef _kJ_HANDLE_TYPE + + inline constexpr operator char() const { + // `char` is different from both `signed char` and `unsigned char`, and may be signed or + // unsigned on different platforms. Ugh. + return char(-1) < 0 ? MinValue_::minSigned() + : MinValue_::minUnsigned(); + } +}; + +static KJ_CONSTEXPR(const) MaxValue_ maxValue = MaxValue_(); +// A special constant which, when cast to an integer type, takes on the maximum possible value of +// that type. This is useful to use as e.g. a parameter to a function because it will be robust +// in the face of changes to the parameter's type. +// +// `char` is not supported, but `signed char` and `unsigned char` are. + +static KJ_CONSTEXPR(const) MinValue_ minValue = MinValue_(); +// A special constant which, when cast to an integer type, takes on the minimum possible value +// of that type. This is useful to use as e.g. a parameter to a function because it will be robust +// in the face of changes to the parameter's type. +// +// `char` is not supported, but `signed char` and `unsigned char` are. + +template +inline bool operator==(T t, MaxValue_) { return t == Decay(maxValue); } +template +inline bool operator==(T t, MinValue_) { return t == Decay(minValue); } + +template +inline constexpr unsigned long long maxValueForBits() { + // Get the maximum integer representable in the given number of bits. + + // 1ull << 64 is unfortunately undefined. + return (bits == 64 ? 0 : (1ull << bits)) - 1; +} + +struct ThrowOverflow { + // Functor which throws an exception complaining about integer overflow. Usually this is used + // with the interfaces in units.h, but is defined here because Cap'n Proto wants to avoid + // including units.h when not using CAPNP_DEBUG_TYPES. + void operator()() const; +}; + +#if __GNUC__ +inline constexpr float inf() { return __builtin_huge_valf(); } +inline constexpr float nan() { return __builtin_nanf(""); } + +#elif _MSC_VER + +// Do what MSVC math.h does +#pragma warning(push) +#pragma warning(disable: 4756) // "overflow in constant arithmetic" +inline constexpr float inf() { return (float)(1e300 * 1e300); } +#pragma warning(pop) + +float nan(); +// Unfortunatley, inf() * 0.0f produces a NaN with the sign bit set, whereas our preferred +// canonical NaN should not have the sign bit set. std::numeric_limits::quiet_NaN() +// returns the correct NaN, but we don't want to #include that here. So, we give up and make +// this out-of-line on MSVC. +// +// TODO(msvc): Can we do better? + +#else +#error "Not sure how to support your compiler." +#endif + +inline constexpr bool isNaN(float f) { return f != f; } +inline constexpr bool isNaN(double f) { return f != f; } + +inline int popCount(unsigned int x) { +#if defined(_MSC_VER) + return __popcnt(x); + // Note: __popcnt returns unsigned int, but the value is clearly guaranteed to fit into an int +#else + return __builtin_popcount(x); +#endif +} + +// ======================================================================================= +// Useful fake containers + +template +class Range { +public: + inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} + inline explicit constexpr Range(const T& end): begin_(0), end_(end) {} + + class Iterator { + public: + Iterator() = default; + inline Iterator(const T& value): value(value) {} + + inline const T& operator* () const { return value; } + inline const T& operator[](size_t index) const { return value + index; } + inline Iterator& operator++() { ++value; return *this; } + inline Iterator operator++(int) { return Iterator(value++); } + inline Iterator& operator--() { --value; return *this; } + inline Iterator operator--(int) { return Iterator(value--); } + inline Iterator& operator+=(ptrdiff_t amount) { value += amount; return *this; } + inline Iterator& operator-=(ptrdiff_t amount) { value -= amount; return *this; } + inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value + amount); } + inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value - amount); } + inline ptrdiff_t operator- (const Iterator& other) const { return value - other.value; } + + inline bool operator==(const Iterator& other) const { return value == other.value; } + inline bool operator!=(const Iterator& other) const { return value != other.value; } + inline bool operator<=(const Iterator& other) const { return value <= other.value; } + inline bool operator>=(const Iterator& other) const { return value >= other.value; } + inline bool operator< (const Iterator& other) const { return value < other.value; } + inline bool operator> (const Iterator& other) const { return value > other.value; } + + private: + T value; + }; + + inline Iterator begin() const { return Iterator(begin_); } + inline Iterator end() const { return Iterator(end_); } + + inline auto size() const -> decltype(instance() - instance()) { return end_ - begin_; } + +private: + T begin_; + T end_; +}; + +template +inline constexpr Range, Decay>> range(T begin, U end) { + return Range, Decay>>(begin, end); +} + +template +inline constexpr Range> range(T begin, T end) { return Range>(begin, end); } +// Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end` +// (exclusive). Example: +// +// // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. +// for (int i: kj::range(1, 10)) { print(i); } + +template +inline constexpr Range> zeroTo(T end) { return Range>(end); } +// Returns a fake iterable container containing all values of T from zero (inclusive) to `end` +// (exclusive). Example: +// +// // Prints 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. +// for (int i: kj::zeroTo(10)) { print(i); } + +template +inline constexpr Range indices(T&& container) { + // Shortcut for iterating over the indices of a container: + // + // for (size_t i: kj::indices(myArray)) { handle(myArray[i]); } + + return range(0, kj::size(container)); +} + +template +class Repeat { +public: + inline constexpr Repeat(const T& value, size_t count): value(value), count(count) {} + + class Iterator { + public: + Iterator() = default; + inline Iterator(const T& value, size_t index): value(value), index(index) {} + + inline const T& operator* () const { return value; } + inline const T& operator[](ptrdiff_t index) const { return value; } + inline Iterator& operator++() { ++index; return *this; } + inline Iterator operator++(int) { return Iterator(value, index++); } + inline Iterator& operator--() { --index; return *this; } + inline Iterator operator--(int) { return Iterator(value, index--); } + inline Iterator& operator+=(ptrdiff_t amount) { index += amount; return *this; } + inline Iterator& operator-=(ptrdiff_t amount) { index -= amount; return *this; } + inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value, index + amount); } + inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value, index - amount); } + inline ptrdiff_t operator- (const Iterator& other) const { return index - other.index; } + + inline bool operator==(const Iterator& other) const { return index == other.index; } + inline bool operator!=(const Iterator& other) const { return index != other.index; } + inline bool operator<=(const Iterator& other) const { return index <= other.index; } + inline bool operator>=(const Iterator& other) const { return index >= other.index; } + inline bool operator< (const Iterator& other) const { return index < other.index; } + inline bool operator> (const Iterator& other) const { return index > other.index; } + + private: + T value; + size_t index; + }; + + inline Iterator begin() const { return Iterator(value, 0); } + inline Iterator end() const { return Iterator(value, count); } + + inline size_t size() const { return count; } + inline const T& operator[](ptrdiff_t) const { return value; } + +private: + T value; + size_t count; +}; + +template +inline constexpr Repeat> repeat(T&& value, size_t count) { + // Returns a fake iterable which contains `count` repeats of `value`. Useful for e.g. creating + // a bunch of spaces: `kj::repeat(' ', indent * 2)` + + return Repeat>(value, count); +} + +// ======================================================================================= +// Manually invoking constructors and destructors +// +// ctor(x, ...) and dtor(x) invoke x's constructor or destructor, respectively. + +// We want placement new, but we don't want to #include . operator new cannot be defined in +// a namespace, and defining it globally conflicts with the definition in . So we have to +// define a dummy type and an operator new that uses it. + +namespace _ { // private +struct PlacementNew {}; +} // namespace _ (private) +} // namespace kj + +inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { + return __p; +} + +inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} + +namespace kj { + +template +inline void ctor(T& location, Params&&... params) { + new (_::PlacementNew(), &location) T(kj::fwd(params)...); +} + +template +inline void dtor(T& location) { + location.~T(); +} + +// ======================================================================================= +// Maybe +// +// Use in cases where you want to indicate that a value may be null. Using Maybe instead of T* +// forces the caller to handle the null case in order to satisfy the compiler, thus reliably +// preventing null pointer dereferences at runtime. +// +// Maybe can be implicitly constructed from T and from nullptr. Additionally, it can be +// implicitly constructed from T*, in which case the pointer is checked for nullness at runtime. +// To read the value of a Maybe, do: +// +// KJ_IF_MAYBE(value, someFuncReturningMaybe()) { +// doSomething(*value); +// } else { +// maybeWasNull(); +// } +// +// KJ_IF_MAYBE's first parameter is a variable name which will be defined within the following +// block. The variable will behave like a (guaranteed non-null) pointer to the Maybe's value, +// though it may or may not actually be a pointer. +// +// Note that Maybe actually just wraps a pointer, whereas Maybe wraps a T and a boolean +// indicating nullness. + +template +class Maybe; + +namespace _ { // private + +template +class NullableValue { + // Class whose interface behaves much like T*, but actually contains an instance of T and a + // boolean flag indicating nullness. + +public: + inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance()))) + : isSet(other.isSet) { + if (isSet) { + ctor(value, kj::mv(other.value)); + } + } + inline NullableValue(const NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + inline NullableValue(NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + inline ~NullableValue() +#if _MSC_VER + // TODO(msvc): MSVC has a hard time with noexcept specifier expressions that are more complex + // than `true` or `false`. We had a workaround for VS2015, but VS2017 regressed. + noexcept(false) +#else + noexcept(noexcept(instance().~T())) +#endif + { + if (isSet) { + dtor(value); + } + } + + inline T& operator*() & { return value; } + inline const T& operator*() const & { return value; } + inline T&& operator*() && { return kj::mv(value); } + inline const T&& operator*() const && { return kj::mv(value); } + inline T* operator->() { return &value; } + inline const T* operator->() const { return &value; } + inline operator T*() { return isSet ? &value : nullptr; } + inline operator const T*() const { return isSet ? &value : nullptr; } + + template + inline T& emplace(Params&&... params) { + if (isSet) { + isSet = false; + dtor(value); + } + ctor(value, kj::fwd(params)...); + isSet = true; + return value; + } + +private: // internal interface used by friends only + inline NullableValue() noexcept: isSet(false) {} + inline NullableValue(T&& t) noexcept(noexcept(T(instance()))) + : isSet(true) { + ctor(value, kj::mv(t)); + } + inline NullableValue(T& t) + : isSet(true) { + ctor(value, t); + } + inline NullableValue(const T& t) + : isSet(true) { + ctor(value, t); + } + inline NullableValue(const T* t) + : isSet(t != nullptr) { + if (isSet) ctor(value, *t); + } + template + inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance()))) + : isSet(other.isSet) { + if (isSet) { + ctor(value, kj::mv(other.value)); + } + } + template + inline NullableValue(const NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + template + inline NullableValue(const NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, *other.ptr); + } + } + inline NullableValue(decltype(nullptr)): isSet(false) {} + + inline NullableValue& operator=(NullableValue&& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, kj::mv(other.value)); + isSet = true; + } + } + return *this; + } + + inline NullableValue& operator=(NullableValue& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, other.value); + isSet = true; + } + } + return *this; + } + + inline NullableValue& operator=(const NullableValue& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, other.value); + isSet = true; + } + } + return *this; + } + + inline bool operator==(decltype(nullptr)) const { return !isSet; } + inline bool operator!=(decltype(nullptr)) const { return isSet; } + +private: + bool isSet; + +#if _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4624) +// Warns that the anonymous union has a deleted destructor when T is non-trivial. This warning +// seems broken. +#endif + + union { + T value; + }; + +#if _MSC_VER +#pragma warning(pop) +#endif + + friend class kj::Maybe; + template + friend NullableValue&& readMaybe(Maybe&& maybe); +}; + +template +inline NullableValue&& readMaybe(Maybe&& maybe) { return kj::mv(maybe.ptr); } +template +inline T* readMaybe(Maybe& maybe) { return maybe.ptr; } +template +inline const T* readMaybe(const Maybe& maybe) { return maybe.ptr; } +template +inline T* readMaybe(Maybe&& maybe) { return maybe.ptr; } +template +inline T* readMaybe(const Maybe& maybe) { return maybe.ptr; } + +template +inline T* readMaybe(T* ptr) { return ptr; } +// Allow KJ_IF_MAYBE to work on regular pointers. + +} // namespace _ (private) + +#define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp)) + +template +class Maybe { + // A T, or nullptr. + + // IF YOU CHANGE THIS CLASS: Note that there is a specialization of it in memory.h. + +public: + Maybe(): ptr(nullptr) {} + Maybe(T&& t) noexcept(noexcept(T(instance()))): ptr(kj::mv(t)) {} + Maybe(T& t): ptr(t) {} + Maybe(const T& t): ptr(t) {} + Maybe(const T* t) noexcept: ptr(t) {} + Maybe(Maybe&& other) noexcept(noexcept(T(instance()))): ptr(kj::mv(other.ptr)) {} + Maybe(const Maybe& other): ptr(other.ptr) {} + Maybe(Maybe& other): ptr(other.ptr) {} + + template + Maybe(Maybe&& other) noexcept(noexcept(T(instance()))) { + KJ_IF_MAYBE(val, kj::mv(other)) { + ptr.emplace(kj::mv(*val)); + } + } + template + Maybe(const Maybe& other) { + KJ_IF_MAYBE(val, other) { + ptr.emplace(*val); + } + } + + Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} + + template + inline T& emplace(Params&&... params) { + // Replace this Maybe's content with a new value constructed by passing the given parametrs to + // T's constructor. This can be used to initialize a Maybe without copying or even moving a T. + // Returns a reference to the newly-constructed value. + + return ptr.emplace(kj::fwd(params)...); + } + + inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } + inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; } + inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; } + + inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } + + T& orDefault(T& defaultValue) { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + const T& orDefault(const T& defaultValue) const { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + + template + auto map(Func&& f) & -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + + template + auto map(Func&& f) const & -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + + template + auto map(Func&& f) && -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(*ptr)); + } + } + + template + auto map(Func&& f) const && -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(*ptr)); + } + } + +private: + _::NullableValue ptr; + + template + friend class Maybe; + template + friend _::NullableValue&& _::readMaybe(Maybe&& maybe); + template + friend U* _::readMaybe(Maybe& maybe); + template + friend const U* _::readMaybe(const Maybe& maybe); +}; + +template +class Maybe: public DisallowConstCopyIfNotConst { +public: + Maybe() noexcept: ptr(nullptr) {} + Maybe(T& t) noexcept: ptr(&t) {} + Maybe(T* t) noexcept: ptr(t) {} + + template + inline Maybe(Maybe& other) noexcept: ptr(other.ptr) {} + template + inline Maybe(const Maybe& other) noexcept: ptr(other.ptr) {} + inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} + + inline Maybe& operator=(T& other) noexcept { ptr = &other; return *this; } + inline Maybe& operator=(T* other) noexcept { ptr = other; return *this; } + template + inline Maybe& operator=(Maybe& other) noexcept { ptr = other.ptr; return *this; } + template + inline Maybe& operator=(const Maybe& other) noexcept { ptr = other.ptr; return *this; } + + inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } + + T& orDefault(T& defaultValue) { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + const T& orDefault(const T& defaultValue) const { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + + template + auto map(Func&& f) -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + +private: + T* ptr; + + template + friend class Maybe; + template + friend U* _::readMaybe(Maybe&& maybe); + template + friend U* _::readMaybe(const Maybe& maybe); +}; + +// ======================================================================================= +// ArrayPtr +// +// So common that we put it in common.h rather than array.h. + +template +class ArrayPtr: public DisallowConstCopyIfNotConst { + // A pointer to an array. Includes a size. Like any pointer, it doesn't own the target data, + // and passing by value only copies the pointer, not the target. + +public: + inline constexpr ArrayPtr(): ptr(nullptr), size_(0) {} + inline constexpr ArrayPtr(decltype(nullptr)): ptr(nullptr), size_(0) {} + inline constexpr ArrayPtr(T* ptr, size_t size): ptr(ptr), size_(size) {} + inline constexpr ArrayPtr(T* begin, T* end): ptr(begin), size_(end - begin) {} + inline KJ_CONSTEXPR() ArrayPtr(::std::initializer_list> init) + : ptr(init.begin()), size_(init.size()) {} + + template + inline constexpr ArrayPtr(T (&native)[size]): ptr(native), size_(size) {} + // Construct an ArrayPtr from a native C-style array. + + inline operator ArrayPtr() const { + return ArrayPtr(ptr, size_); + } + inline ArrayPtr asConst() const { + return ArrayPtr(ptr, size_); + } + + inline size_t size() const { return size_; } + inline const T& operator[](size_t index) const { + KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); + return ptr[index]; + } + inline T& operator[](size_t index) { + KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); + return ptr[index]; + } + + inline T* begin() { return ptr; } + inline T* end() { return ptr + size_; } + inline T& front() { return *ptr; } + inline T& back() { return *(ptr + size_ - 1); } + inline const T* begin() const { return ptr; } + inline const T* end() const { return ptr + size_; } + inline const T& front() const { return *ptr; } + inline const T& back() const { return *(ptr + size_ - 1); } + + inline ArrayPtr slice(size_t start, size_t end) const { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); + return ArrayPtr(ptr + start, end - start); + } + inline ArrayPtr slice(size_t start, size_t end) { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); + return ArrayPtr(ptr + start, end - start); + } + + inline ArrayPtr> asBytes() const { + // Reinterpret the array as a byte array. This is explicitly legal under C++ aliasing + // rules. + return { reinterpret_cast*>(ptr), size_ * sizeof(T) }; + } + inline ArrayPtr> asChars() const { + // Reinterpret the array as a char array. This is explicitly legal under C++ aliasing + // rules. + return { reinterpret_cast*>(ptr), size_ * sizeof(T) }; + } + + inline bool operator==(decltype(nullptr)) const { return size_ == 0; } + inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } + + inline bool operator==(const ArrayPtr& other) const { + if (size_ != other.size_) return false; + for (size_t i = 0; i < size_; i++) { + if (ptr[i] != other[i]) return false; + } + return true; + } + inline bool operator!=(const ArrayPtr& other) const { return !(*this == other); } + +private: + T* ptr; + size_t size_; +}; + +template +inline constexpr ArrayPtr arrayPtr(T* ptr, size_t size) { + // Use this function to construct ArrayPtrs without writing out the type name. + return ArrayPtr(ptr, size); +} + +template +inline constexpr ArrayPtr arrayPtr(T* begin, T* end) { + // Use this function to construct ArrayPtrs without writing out the type name. + return ArrayPtr(begin, end); +} + +// ======================================================================================= +// Casts + +template +To implicitCast(From&& from) { + // `implicitCast(value)` casts `value` to type `T` only if the conversion is implicit. Useful + // for e.g. resolving ambiguous overloads without sacrificing type-safety. + return kj::fwd(from); +} + +template +Maybe dynamicDowncastIfAvailable(From& from) { + // If RTTI is disabled, always returns nullptr. Otherwise, works like dynamic_cast. Useful + // in situations where dynamic_cast could allow an optimization, but isn't strictly necessary + // for correctness. It is highly recommended that you try to arrange all your dynamic_casts + // this way, as a dynamic_cast that is necessary for correctness implies a flaw in the interface + // design. + + // Force a compile error if To is not a subtype of From. Cross-casting is rare; if it is needed + // we should have a separate cast function like dynamicCrosscastIfAvailable(). + if (false) { + kj::implicitCast(kj::implicitCast(nullptr)); + } + +#if KJ_NO_RTTI + return nullptr; +#else + return dynamic_cast(&from); +#endif +} + +template +To& downcast(From& from) { + // Down-cast a value to a sub-type, asserting that the cast is valid. In opt mode this is a + // static_cast, but in debug mode (when RTTI is enabled) a dynamic_cast will be used to verify + // that the value really has the requested type. + + // Force a compile error if To is not a subtype of From. + if (false) { + kj::implicitCast(kj::implicitCast(nullptr)); + } + +#if !KJ_NO_RTTI + KJ_IREQUIRE(dynamic_cast(&from) != nullptr, "Value cannot be downcast() to requested type."); +#endif + + return static_cast(from); +} + +// ======================================================================================= +// Defer + +namespace _ { // private + +template +class Deferred { +public: + inline Deferred(Func&& func): func(kj::fwd(func)), canceled(false) {} + inline ~Deferred() noexcept(false) { if (!canceled) func(); } + KJ_DISALLOW_COPY(Deferred); + + // This move constructor is usually optimized away by the compiler. + inline Deferred(Deferred&& other): func(kj::mv(other.func)), canceled(false) { + other.canceled = true; + } +private: + Func func; + bool canceled; +}; + +} // namespace _ (private) + +template +_::Deferred defer(Func&& func) { + // Returns an object which will invoke the given functor in its destructor. The object is not + // copyable but is movable with the semantics you'd expect. Since the return type is private, + // you need to assign to an `auto` variable. + // + // The KJ_DEFER macro provides slightly more convenient syntax for the common case where you + // want some code to run at current scope exit. + + return _::Deferred(kj::fwd(func)); +} + +#define KJ_DEFER(code) auto KJ_UNIQUE_NAME(_kjDefer) = ::kj::defer([&](){code;}) +// Run the given code when the function exits, whether by return or exception. + +} // namespace kj + +#endif // KJ_COMMON_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/debug.h --- a/win32-mingw/include/kj/debug.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/debug.h Tue May 23 09:16:54 2017 +0100 @@ -1,455 +1,555 @@ -// 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 declares convenient macros for debug logging and error handling. The macros make -// it excessively easy to extract useful context information from code. Example: -// -// KJ_ASSERT(a == b, a, b, "a and b must be the same."); -// -// On failure, this will throw an exception whose description looks like: -// -// myfile.c++:43: bug in code: expected a == b; a = 14; b = 72; a and b must be the same. -// -// As you can see, all arguments after the first provide additional context. -// -// The macros available are: -// -// * `KJ_LOG(severity, ...)`: Just writes a log message, to stderr by default (but you can -// intercept messages by implementing an ExceptionCallback). `severity` is `INFO`, `WARNING`, -// `ERROR`, or `FATAL`. By default, `INFO` logs are not written, but for command-line apps the -// user should be able to pass a flag like `--verbose` to enable them. Other log levels are -// enabled by default. Log messages -- like exceptions -- can be intercepted by registering an -// ExceptionCallback. -// -// * `KJ_DBG(...)`: Like `KJ_LOG`, but intended specifically for temporary log lines added while -// debugging a particular problem. Calls to `KJ_DBG` should always be deleted before committing -// code. It is suggested that you set up a pre-commit hook that checks for this. -// -// * `KJ_ASSERT(condition, ...)`: Throws an exception if `condition` is false, or aborts if -// exceptions are disabled. This macro should be used to check for bugs in the surrounding code -// and its dependencies, but NOT to check for invalid input. The macro may be followed by a -// brace-delimited code block; if so, the block will be executed in the case where the assertion -// fails, before throwing the exception. If control jumps out of the block (e.g. with "break", -// "return", or "goto"), then the error is considered "recoverable" -- in this case, if -// exceptions are disabled, execution will continue normally rather than aborting (but if -// exceptions are enabled, an exception will still be thrown on exiting the block). A "break" -// statement in particular will jump to the code immediately after the block (it does not break -// any surrounding loop or switch). Example: -// -// KJ_ASSERT(value >= 0, "Value cannot be negative.", value) { -// // Assertion failed. Set value to zero to "recover". -// value = 0; -// // Don't abort if exceptions are disabled. Continue normally. -// // (Still throw an exception if they are enabled, though.) -// break; -// } -// // When exceptions are disabled, we'll get here even if the assertion fails. -// // Otherwise, we get here only if the assertion passes. -// -// * `KJ_REQUIRE(condition, ...)`: Like `KJ_ASSERT` but used to check preconditions -- e.g. to -// validate parameters passed from a caller. A failure indicates that the caller is buggy. -// -// * `KJ_SYSCALL(code, ...)`: Executes `code` assuming it makes a system call. A negative result -// is considered an error, with error code reported via `errno`. EINTR is handled by retrying. -// Other errors are handled by throwing an exception. If you need to examine the return code, -// assign it to a variable like so: -// -// int fd; -// KJ_SYSCALL(fd = open(filename, O_RDONLY), filename); -// -// `KJ_SYSCALL` can be followed by a recovery block, just like `KJ_ASSERT`. -// -// * `KJ_NONBLOCKING_SYSCALL(code, ...)`: Like KJ_SYSCALL, but will not throw an exception on -// EAGAIN/EWOULDBLOCK. The calling code should check the syscall's return value to see if it -// indicates an error; in this case, it can assume the error was EAGAIN because any other error -// would have caused an exception to be thrown. -// -// * `KJ_CONTEXT(...)`: Notes additional contextual information relevant to any exceptions thrown -// from within the current scope. That is, until control exits the block in which KJ_CONTEXT() -// is used, if any exception is generated, it will contain the given information in its context -// chain. This is helpful because it can otherwise be very difficult to come up with error -// messages that make sense within low-level helper code. Note that the parameters to -// KJ_CONTEXT() are only evaluated if an exception is thrown. This implies that any variables -// used must remain valid until the end of the scope. -// -// Notes: -// * Do not write expressions with side-effects in the message content part of the macro, as the -// message will not necessarily be evaluated. -// * For every macro `FOO` above except `LOG`, there is also a `FAIL_FOO` macro used to report -// failures that already happened. For the macros that check a boolean condition, `FAIL_FOO` -// omits the first parameter and behaves like it was `false`. `FAIL_SYSCALL` and -// `FAIL_RECOVERABLE_SYSCALL` take a string and an OS error number as the first two parameters. -// The string should be the name of the failed system call. -// * For every macro `FOO` above, there is a `DFOO` version (or `RECOVERABLE_DFOO`) which is only -// executed in debug mode, i.e. when KJ_DEBUG is defined. KJ_DEBUG is defined automatically -// by common.h when compiling without optimization (unless NDEBUG is defined), but you can also -// define it explicitly (e.g. -DKJ_DEBUG). Generally, production builds should NOT use KJ_DEBUG -// as it may enable expensive checks that are unlikely to fail. - -#ifndef KJ_DEBUG_H_ -#define KJ_DEBUG_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "string.h" -#include "exception.h" - -#ifdef ERROR -// This is problematic because windows.h #defines ERROR, which we use in an enum here. -#error "Make sure to to undefine ERROR (or just #include ) before this file" -#endif - -namespace kj { - -#if _MSC_VER -// MSVC does __VA_ARGS__ differently from GCC: -// - A trailing comma before an empty __VA_ARGS__ is removed automatically, whereas GCC wants -// you to request this behavior with "##__VA_ARGS__". -// - If __VA_ARGS__ is passed directly as an argument to another macro, it will be treated as a -// *single* argument rather than an argument list. This can be worked around by wrapping the -// outer macro call in KJ_EXPAND(), which appraently forces __VA_ARGS__ to be expanded before -// the macro is evaluated. I don't understand the C preprocessor. -// - Using "#__VA_ARGS__" to stringify __VA_ARGS__ expands to zero tokens when __VA_ARGS__ is -// empty, rather than expanding to an empty string literal. We can work around by concatenating -// with an empty string literal. - -#define KJ_EXPAND(X) X - -#define KJ_LOG(severity, ...) \ - if (!::kj::_::Debug::shouldLog(::kj::LogSeverity::severity)) {} else \ - ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ - "" #__VA_ARGS__, __VA_ARGS__) - -#define KJ_DBG(...) KJ_EXPAND(KJ_LOG(DBG, __VA_ARGS__)) - -#define KJ_REQUIRE(cond, ...) \ - if (KJ_LIKELY(cond)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - #cond, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_REQUIRE(...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_SYSCALL(call, ...) \ - if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_NONBLOCKING_SYSCALL(call, ...) \ - if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - errorNumber, code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_UNIMPLEMENTED(...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ - nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_CONTEXT(...) \ - auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ - return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ - ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)); \ - }; \ - ::kj::_::Debug::ContextImpl \ - KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) - -#define KJ_REQUIRE_NONNULL(value, ...) \ - (*[&] { \ - auto _kj_result = ::kj::_::readMaybe(value); \ - if (KJ_UNLIKELY(!_kj_result)) { \ - ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - #value " != nullptr", "" #__VA_ARGS__, __VA_ARGS__).fatal(); \ - } \ - return _kj_result; \ - }()) - -#define KJ_EXCEPTION(type, ...) \ - ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ - ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)) - -#else - -#define KJ_LOG(severity, ...) \ - if (!::kj::_::Debug::shouldLog(::kj::LogSeverity::severity)) {} else \ - ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ - #__VA_ARGS__, ##__VA_ARGS__) - -#define KJ_DBG(...) KJ_LOG(DBG, ##__VA_ARGS__) - -#define KJ_REQUIRE(cond, ...) \ - if (KJ_LIKELY(cond)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - #cond, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_REQUIRE(...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_SYSCALL(call, ...) \ - if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_NONBLOCKING_SYSCALL(call, ...) \ - if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - errorNumber, code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_UNIMPLEMENTED(...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ - nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_CONTEXT(...) \ - auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ - return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ - ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)); \ - }; \ - ::kj::_::Debug::ContextImpl \ - KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) - -#define KJ_REQUIRE_NONNULL(value, ...) \ - (*({ \ - auto _kj_result = ::kj::_::readMaybe(value); \ - if (KJ_UNLIKELY(!_kj_result)) { \ - ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - #value " != nullptr", #__VA_ARGS__, ##__VA_ARGS__).fatal(); \ - } \ - kj::mv(_kj_result); \ - })) - -#define KJ_EXCEPTION(type, ...) \ - ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ - ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)) - -#endif - -#define KJ_ASSERT KJ_REQUIRE -#define KJ_FAIL_ASSERT KJ_FAIL_REQUIRE -#define KJ_ASSERT_NONNULL KJ_REQUIRE_NONNULL -// Use "ASSERT" in place of "REQUIRE" when the problem is local to the immediate surrounding code. -// That is, if the assert ever fails, it indicates that the immediate surrounding code is broken. - -#ifdef KJ_DEBUG -#define KJ_DLOG KJ_LOG -#define KJ_DASSERT KJ_ASSERT -#define KJ_DREQUIRE KJ_REQUIRE -#else -#define KJ_DLOG(...) do {} while (false) -#define KJ_DASSERT(...) do {} while (false) -#define KJ_DREQUIRE(...) do {} while (false) -#endif - -namespace _ { // private - -class Debug { -public: - Debug() = delete; - - typedef LogSeverity Severity; // backwards-compatibility - - static inline bool shouldLog(LogSeverity severity) { return severity >= minSeverity; } - // Returns whether messages of the given severity should be logged. - - static inline void setLogLevel(LogSeverity severity) { minSeverity = severity; } - // Set the minimum message severity which will be logged. - // - // TODO(someday): Expose publicly. - - template - static void log(const char* file, int line, LogSeverity severity, const char* macroArgs, - Params&&... params); - - class Fault { - public: - template - Fault(const char* file, int line, Exception::Type type, - const char* condition, const char* macroArgs, Params&&... params); - template - Fault(const char* file, int line, int osErrorNumber, - const char* condition, const char* macroArgs, Params&&... params); - Fault(const char* file, int line, Exception::Type type, - const char* condition, const char* macroArgs); - Fault(const char* file, int line, int osErrorNumber, - const char* condition, const char* macroArgs); - ~Fault() noexcept(false); - - KJ_NOINLINE KJ_NORETURN(void fatal()); - // Throw the exception. - - private: - void init(const char* file, int line, Exception::Type type, - const char* condition, const char* macroArgs, ArrayPtr argValues); - void init(const char* file, int line, int osErrorNumber, - const char* condition, const char* macroArgs, ArrayPtr argValues); - - Exception* exception; - }; - - class SyscallResult { - public: - inline SyscallResult(int errorNumber): errorNumber(errorNumber) {} - inline operator void*() { return errorNumber == 0 ? this : nullptr; } - inline int getErrorNumber() { return errorNumber; } - - private: - int errorNumber; - }; - - template - static SyscallResult syscall(Call&& call, bool nonblocking); - - class Context: public ExceptionCallback { - public: - Context(); - KJ_DISALLOW_COPY(Context); - virtual ~Context() noexcept(false); - - struct Value { - const char* file; - int line; - String description; - - inline Value(const char* file, int line, String&& description) - : file(file), line(line), description(mv(description)) {} - }; - - virtual Value evaluate() = 0; - - virtual void onRecoverableException(Exception&& exception) override; - virtual void onFatalException(Exception&& exception) override; - virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, - String&& text) override; - - private: - bool logged; - Maybe value; - - Value ensureInitialized(); - }; - - template - class ContextImpl: public Context { - public: - inline ContextImpl(Func& func): func(func) {} - KJ_DISALLOW_COPY(ContextImpl); - - Value evaluate() override { - return func(); - } - private: - Func& func; - }; - - template - static String makeDescription(const char* macroArgs, Params&&... params); - -private: - static LogSeverity minSeverity; - - static void logInternal(const char* file, int line, LogSeverity severity, const char* macroArgs, - ArrayPtr argValues); - static String makeDescriptionInternal(const char* macroArgs, ArrayPtr argValues); - - static int getOsErrorNumber(bool nonblocking); - // Get the error code of the last error (e.g. from errno). Returns -1 on EINTR. -}; - -template -void Debug::log(const char* file, int line, LogSeverity severity, const char* macroArgs, - Params&&... params) { - String argValues[sizeof...(Params)] = {str(params)...}; - logInternal(file, line, severity, macroArgs, arrayPtr(argValues, sizeof...(Params))); -} - -template <> -inline void Debug::log<>(const char* file, int line, LogSeverity severity, const char* macroArgs) { - logInternal(file, line, severity, macroArgs, nullptr); -} - -template -Debug::Fault::Fault(const char* file, int line, Exception::Type type, - const char* condition, const char* macroArgs, Params&&... params) - : exception(nullptr) { - String argValues[sizeof...(Params)] = {str(params)...}; - init(file, line, type, condition, macroArgs, - arrayPtr(argValues, sizeof...(Params))); -} - -template -Debug::Fault::Fault(const char* file, int line, int osErrorNumber, - const char* condition, const char* macroArgs, Params&&... params) - : exception(nullptr) { - String argValues[sizeof...(Params)] = {str(params)...}; - init(file, line, osErrorNumber, condition, macroArgs, - arrayPtr(argValues, sizeof...(Params))); -} - -inline Debug::Fault::Fault(const char* file, int line, int osErrorNumber, - const char* condition, const char* macroArgs) - : exception(nullptr) { - init(file, line, osErrorNumber, condition, macroArgs, nullptr); -} - -inline Debug::Fault::Fault(const char* file, int line, kj::Exception::Type type, - const char* condition, const char* macroArgs) - : exception(nullptr) { - init(file, line, type, condition, macroArgs, nullptr); -} - -template -Debug::SyscallResult Debug::syscall(Call&& call, bool nonblocking) { - while (call() < 0) { - int errorNum = getOsErrorNumber(nonblocking); - // getOsErrorNumber() returns -1 to indicate EINTR. - // Also, if nonblocking is true, then it returns 0 on EAGAIN, which will then be treated as a - // non-error. - if (errorNum != -1) { - return SyscallResult(errorNum); - } - } - return SyscallResult(0); -} - -template -String Debug::makeDescription(const char* macroArgs, Params&&... params) { - String argValues[sizeof...(Params)] = {str(params)...}; - return makeDescriptionInternal(macroArgs, arrayPtr(argValues, sizeof...(Params))); -} - -template <> -inline String Debug::makeDescription<>(const char* macroArgs) { - return makeDescriptionInternal(macroArgs, nullptr); -} - -} // namespace _ (private) -} // namespace kj - -#endif // KJ_DEBUG_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 declares convenient macros for debug logging and error handling. The macros make +// it excessively easy to extract useful context information from code. Example: +// +// KJ_ASSERT(a == b, a, b, "a and b must be the same."); +// +// On failure, this will throw an exception whose description looks like: +// +// myfile.c++:43: bug in code: expected a == b; a = 14; b = 72; a and b must be the same. +// +// As you can see, all arguments after the first provide additional context. +// +// The macros available are: +// +// * `KJ_LOG(severity, ...)`: Just writes a log message, to stderr by default (but you can +// intercept messages by implementing an ExceptionCallback). `severity` is `INFO`, `WARNING`, +// `ERROR`, or `FATAL`. By default, `INFO` logs are not written, but for command-line apps the +// user should be able to pass a flag like `--verbose` to enable them. Other log levels are +// enabled by default. Log messages -- like exceptions -- can be intercepted by registering an +// ExceptionCallback. +// +// * `KJ_DBG(...)`: Like `KJ_LOG`, but intended specifically for temporary log lines added while +// debugging a particular problem. Calls to `KJ_DBG` should always be deleted before committing +// code. It is suggested that you set up a pre-commit hook that checks for this. +// +// * `KJ_ASSERT(condition, ...)`: Throws an exception if `condition` is false, or aborts if +// exceptions are disabled. This macro should be used to check for bugs in the surrounding code +// and its dependencies, but NOT to check for invalid input. The macro may be followed by a +// brace-delimited code block; if so, the block will be executed in the case where the assertion +// fails, before throwing the exception. If control jumps out of the block (e.g. with "break", +// "return", or "goto"), then the error is considered "recoverable" -- in this case, if +// exceptions are disabled, execution will continue normally rather than aborting (but if +// exceptions are enabled, an exception will still be thrown on exiting the block). A "break" +// statement in particular will jump to the code immediately after the block (it does not break +// any surrounding loop or switch). Example: +// +// KJ_ASSERT(value >= 0, "Value cannot be negative.", value) { +// // Assertion failed. Set value to zero to "recover". +// value = 0; +// // Don't abort if exceptions are disabled. Continue normally. +// // (Still throw an exception if they are enabled, though.) +// break; +// } +// // When exceptions are disabled, we'll get here even if the assertion fails. +// // Otherwise, we get here only if the assertion passes. +// +// * `KJ_REQUIRE(condition, ...)`: Like `KJ_ASSERT` but used to check preconditions -- e.g. to +// validate parameters passed from a caller. A failure indicates that the caller is buggy. +// +// * `KJ_SYSCALL(code, ...)`: Executes `code` assuming it makes a system call. A negative result +// is considered an error, with error code reported via `errno`. EINTR is handled by retrying. +// Other errors are handled by throwing an exception. If you need to examine the return code, +// assign it to a variable like so: +// +// int fd; +// KJ_SYSCALL(fd = open(filename, O_RDONLY), filename); +// +// `KJ_SYSCALL` can be followed by a recovery block, just like `KJ_ASSERT`. +// +// * `KJ_NONBLOCKING_SYSCALL(code, ...)`: Like KJ_SYSCALL, but will not throw an exception on +// EAGAIN/EWOULDBLOCK. The calling code should check the syscall's return value to see if it +// indicates an error; in this case, it can assume the error was EAGAIN because any other error +// would have caused an exception to be thrown. +// +// * `KJ_CONTEXT(...)`: Notes additional contextual information relevant to any exceptions thrown +// from within the current scope. That is, until control exits the block in which KJ_CONTEXT() +// is used, if any exception is generated, it will contain the given information in its context +// chain. This is helpful because it can otherwise be very difficult to come up with error +// messages that make sense within low-level helper code. Note that the parameters to +// KJ_CONTEXT() are only evaluated if an exception is thrown. This implies that any variables +// used must remain valid until the end of the scope. +// +// Notes: +// * Do not write expressions with side-effects in the message content part of the macro, as the +// message will not necessarily be evaluated. +// * For every macro `FOO` above except `LOG`, there is also a `FAIL_FOO` macro used to report +// failures that already happened. For the macros that check a boolean condition, `FAIL_FOO` +// omits the first parameter and behaves like it was `false`. `FAIL_SYSCALL` and +// `FAIL_RECOVERABLE_SYSCALL` take a string and an OS error number as the first two parameters. +// The string should be the name of the failed system call. +// * For every macro `FOO` above, there is a `DFOO` version (or `RECOVERABLE_DFOO`) which is only +// executed in debug mode, i.e. when KJ_DEBUG is defined. KJ_DEBUG is defined automatically +// by common.h when compiling without optimization (unless NDEBUG is defined), but you can also +// define it explicitly (e.g. -DKJ_DEBUG). Generally, production builds should NOT use KJ_DEBUG +// as it may enable expensive checks that are unlikely to fail. + +#ifndef KJ_DEBUG_H_ +#define KJ_DEBUG_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "string.h" +#include "exception.h" + +#ifdef ERROR +// This is problematic because windows.h #defines ERROR, which we use in an enum here. +#error "Make sure to to undefine ERROR (or just #include ) before this file" +#endif + +namespace kj { + +#if _MSC_VER +// MSVC does __VA_ARGS__ differently from GCC: +// - A trailing comma before an empty __VA_ARGS__ is removed automatically, whereas GCC wants +// you to request this behavior with "##__VA_ARGS__". +// - If __VA_ARGS__ is passed directly as an argument to another macro, it will be treated as a +// *single* argument rather than an argument list. This can be worked around by wrapping the +// outer macro call in KJ_EXPAND(), which appraently forces __VA_ARGS__ to be expanded before +// the macro is evaluated. I don't understand the C preprocessor. +// - Using "#__VA_ARGS__" to stringify __VA_ARGS__ expands to zero tokens when __VA_ARGS__ is +// empty, rather than expanding to an empty string literal. We can work around by concatenating +// with an empty string literal. + +#define KJ_EXPAND(X) X + +#define KJ_LOG(severity, ...) \ + if (!::kj::_::Debug::shouldLog(::kj::LogSeverity::severity)) {} else \ + ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ + "" #__VA_ARGS__, __VA_ARGS__) + +#define KJ_DBG(...) KJ_EXPAND(KJ_LOG(DBG, __VA_ARGS__)) + +#define KJ_REQUIRE(cond, ...) \ + if (KJ_LIKELY(cond)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #cond, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_REQUIRE(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_NONBLOCKING_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + errorNumber, code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#if _WIN32 + +#define KJ_WIN32(call, ...) \ + if (::kj::_::Debug::isWin32Success(call)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + ::kj::_::Debug::getWin32Error(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_WINSOCK(call, ...) \ + if ((call) != SOCKET_ERROR) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + ::kj::_::Debug::getWin32Error(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_WIN32(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + ::kj::_::Debug::Win32Error(errorNumber), code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#endif + +#define KJ_UNIMPLEMENTED(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ + nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +// TODO(msvc): MSVC mis-deduces `ContextImpl` as `ContextImpl` in some edge +// cases, such as inside nested lambdas inside member functions. Wrapping the type in +// `decltype(instance<...>())` helps it deduce the context function's type correctly. +#define KJ_CONTEXT(...) \ + auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ + return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)); \ + }; \ + decltype(::kj::instance<::kj::_::Debug::ContextImpl>()) \ + KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) + +#define KJ_REQUIRE_NONNULL(value, ...) \ + (*[&] { \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (KJ_UNLIKELY(!_kj_result)) { \ + ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #value " != nullptr", "" #__VA_ARGS__, __VA_ARGS__).fatal(); \ + } \ + return _kj_result; \ + }()) + +#define KJ_EXCEPTION(type, ...) \ + ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)) + +#else + +#define KJ_LOG(severity, ...) \ + if (!::kj::_::Debug::shouldLog(::kj::LogSeverity::severity)) {} else \ + ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ + #__VA_ARGS__, ##__VA_ARGS__) + +#define KJ_DBG(...) KJ_LOG(DBG, ##__VA_ARGS__) + +#define KJ_REQUIRE(cond, ...) \ + if (KJ_LIKELY(cond)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #cond, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_REQUIRE(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_NONBLOCKING_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + errorNumber, code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#if _WIN32 + +#define KJ_WIN32(call, ...) \ + if (::kj::_::Debug::isWin32Success(call)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + ::kj::_::Debug::getWin32Error(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_WINSOCK(call, ...) \ + if ((call) != SOCKET_ERROR) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + ::kj::_::Debug::getWin32Error(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_WIN32(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + ::kj::_::Debug::Win32Error(errorNumber), code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#endif + +#define KJ_UNIMPLEMENTED(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ + nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_CONTEXT(...) \ + auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ + return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)); \ + }; \ + ::kj::_::Debug::ContextImpl \ + KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) + +#define KJ_REQUIRE_NONNULL(value, ...) \ + (*({ \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (KJ_UNLIKELY(!_kj_result)) { \ + ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #value " != nullptr", #__VA_ARGS__, ##__VA_ARGS__).fatal(); \ + } \ + kj::mv(_kj_result); \ + })) + +#define KJ_EXCEPTION(type, ...) \ + ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)) + +#endif + +#define KJ_SYSCALL_HANDLE_ERRORS(call) \ + if (int _kjSyscallError = ::kj::_::Debug::syscallError([&](){return (call);}, false)) \ + switch (int error = _kjSyscallError) +// Like KJ_SYSCALL, but doesn't throw. Instead, the block after the macro is a switch block on the +// error. Additionally, the int value `error` is defined within the block. So you can do: +// +// KJ_SYSCALL_HANDLE_ERRORS(foo()) { +// case ENOENT: +// handleNoSuchFile(); +// break; +// case EEXIST: +// handleExists(); +// break; +// default: +// KJ_FAIL_SYSCALL("foo()", error); +// } else { +// handleSuccessCase(); +// } + +#define KJ_ASSERT KJ_REQUIRE +#define KJ_FAIL_ASSERT KJ_FAIL_REQUIRE +#define KJ_ASSERT_NONNULL KJ_REQUIRE_NONNULL +// Use "ASSERT" in place of "REQUIRE" when the problem is local to the immediate surrounding code. +// That is, if the assert ever fails, it indicates that the immediate surrounding code is broken. + +#ifdef KJ_DEBUG +#define KJ_DLOG KJ_LOG +#define KJ_DASSERT KJ_ASSERT +#define KJ_DREQUIRE KJ_REQUIRE +#else +#define KJ_DLOG(...) do {} while (false) +#define KJ_DASSERT(...) do {} while (false) +#define KJ_DREQUIRE(...) do {} while (false) +#endif + +namespace _ { // private + +class Debug { +public: + Debug() = delete; + + typedef LogSeverity Severity; // backwards-compatibility + +#if _WIN32 + struct Win32Error { + // Hack for overloading purposes. + uint number; + inline explicit Win32Error(uint number): number(number) {} + }; +#endif + + static inline bool shouldLog(LogSeverity severity) { return severity >= minSeverity; } + // Returns whether messages of the given severity should be logged. + + static inline void setLogLevel(LogSeverity severity) { minSeverity = severity; } + // Set the minimum message severity which will be logged. + // + // TODO(someday): Expose publicly. + + template + static void log(const char* file, int line, LogSeverity severity, const char* macroArgs, + Params&&... params); + + class Fault { + public: + template + Fault(const char* file, int line, Code code, + const char* condition, const char* macroArgs, Params&&... params); + Fault(const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs); + Fault(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs); +#if _WIN32 + Fault(const char* file, int line, Win32Error osErrorNumber, + const char* condition, const char* macroArgs); +#endif + ~Fault() noexcept(false); + + KJ_NOINLINE KJ_NORETURN(void fatal()); + // Throw the exception. + + private: + void init(const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs, ArrayPtr argValues); + void init(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs, ArrayPtr argValues); +#if _WIN32 + void init(const char* file, int line, Win32Error osErrorNumber, + const char* condition, const char* macroArgs, ArrayPtr argValues); +#endif + + Exception* exception; + }; + + class SyscallResult { + public: + inline SyscallResult(int errorNumber): errorNumber(errorNumber) {} + inline operator void*() { return errorNumber == 0 ? this : nullptr; } + inline int getErrorNumber() { return errorNumber; } + + private: + int errorNumber; + }; + + template + static SyscallResult syscall(Call&& call, bool nonblocking); + template + static int syscallError(Call&& call, bool nonblocking); + +#if _WIN32 + static bool isWin32Success(int boolean); + static bool isWin32Success(void* handle); + static Win32Error getWin32Error(); +#endif + + class Context: public ExceptionCallback { + public: + Context(); + KJ_DISALLOW_COPY(Context); + virtual ~Context() noexcept(false); + + struct Value { + const char* file; + int line; + String description; + + inline Value(const char* file, int line, String&& description) + : file(file), line(line), description(mv(description)) {} + }; + + virtual Value evaluate() = 0; + + virtual void onRecoverableException(Exception&& exception) override; + virtual void onFatalException(Exception&& exception) override; + virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text) override; + + private: + bool logged; + Maybe value; + + Value ensureInitialized(); + }; + + template + class ContextImpl: public Context { + public: + inline ContextImpl(Func& func): func(func) {} + KJ_DISALLOW_COPY(ContextImpl); + + Value evaluate() override { + return func(); + } + private: + Func& func; + }; + + template + static String makeDescription(const char* macroArgs, Params&&... params); + +private: + static LogSeverity minSeverity; + + static void logInternal(const char* file, int line, LogSeverity severity, const char* macroArgs, + ArrayPtr argValues); + static String makeDescriptionInternal(const char* macroArgs, ArrayPtr argValues); + + static int getOsErrorNumber(bool nonblocking); + // Get the error code of the last error (e.g. from errno). Returns -1 on EINTR. +}; + +template +void Debug::log(const char* file, int line, LogSeverity severity, const char* macroArgs, + Params&&... params) { + String argValues[sizeof...(Params)] = {str(params)...}; + logInternal(file, line, severity, macroArgs, arrayPtr(argValues, sizeof...(Params))); +} + +template <> +inline void Debug::log<>(const char* file, int line, LogSeverity severity, const char* macroArgs) { + logInternal(file, line, severity, macroArgs, nullptr); +} + +template +Debug::Fault::Fault(const char* file, int line, Code code, + const char* condition, const char* macroArgs, Params&&... params) + : exception(nullptr) { + String argValues[sizeof...(Params)] = {str(params)...}; + init(file, line, code, condition, macroArgs, + arrayPtr(argValues, sizeof...(Params))); +} + +inline Debug::Fault::Fault(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs) + : exception(nullptr) { + init(file, line, osErrorNumber, condition, macroArgs, nullptr); +} + +inline Debug::Fault::Fault(const char* file, int line, kj::Exception::Type type, + const char* condition, const char* macroArgs) + : exception(nullptr) { + init(file, line, type, condition, macroArgs, nullptr); +} + +#if _WIN32 +inline Debug::Fault::Fault(const char* file, int line, Win32Error osErrorNumber, + const char* condition, const char* macroArgs) + : exception(nullptr) { + init(file, line, osErrorNumber, condition, macroArgs, nullptr); +} + +inline bool Debug::isWin32Success(int boolean) { + return boolean; +} +inline bool Debug::isWin32Success(void* handle) { + // Assume null and INVALID_HANDLE_VALUE mean failure. + return handle != nullptr && handle != (void*)-1; +} +#endif + +template +Debug::SyscallResult Debug::syscall(Call&& call, bool nonblocking) { + while (call() < 0) { + int errorNum = getOsErrorNumber(nonblocking); + // getOsErrorNumber() returns -1 to indicate EINTR. + // Also, if nonblocking is true, then it returns 0 on EAGAIN, which will then be treated as a + // non-error. + if (errorNum != -1) { + return SyscallResult(errorNum); + } + } + return SyscallResult(0); +} + +template +int Debug::syscallError(Call&& call, bool nonblocking) { + while (call() < 0) { + int errorNum = getOsErrorNumber(nonblocking); + // getOsErrorNumber() returns -1 to indicate EINTR. + // Also, if nonblocking is true, then it returns 0 on EAGAIN, which will then be treated as a + // non-error. + if (errorNum != -1) { + return errorNum; + } + } + return 0; +} + +template +String Debug::makeDescription(const char* macroArgs, Params&&... params) { + String argValues[sizeof...(Params)] = {str(params)...}; + return makeDescriptionInternal(macroArgs, arrayPtr(argValues, sizeof...(Params))); +} + +template <> +inline String Debug::makeDescription<>(const char* macroArgs) { + return makeDescriptionInternal(macroArgs, nullptr); +} + +} // namespace _ (private) +} // namespace kj + +#endif // KJ_DEBUG_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/exception.h --- a/win32-mingw/include/kj/exception.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/exception.h Tue May 23 09:16:54 2017 +0100 @@ -1,337 +1,363 @@ -// 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. - -#ifndef KJ_EXCEPTION_H_ -#define KJ_EXCEPTION_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "memory.h" -#include "array.h" -#include "string.h" - -namespace kj { - -class ExceptionImpl; - -class Exception { - // Exception thrown in case of fatal errors. - // - // Actually, a subclass of this which also implements std::exception will be thrown, but we hide - // that fact from the interface to avoid #including . - -public: - enum class Type { - // What kind of failure? - - FAILED = 0, - // Something went wrong. This is the usual error type. KJ_ASSERT and KJ_REQUIRE throw this - // error type. - - OVERLOADED = 1, - // The call failed because of a temporary lack of resources. This could be space resources - // (out of memory, out of disk space) or time resources (request queue overflow, operation - // timed out). - // - // The operation might work if tried again, but it should NOT be repeated immediately as this - // may simply exacerbate the problem. - - DISCONNECTED = 2, - // The call required communication over a connection that has been lost. The callee will need - // to re-establish connections and try again. - - UNIMPLEMENTED = 3 - // The requested method is not implemented. The caller may wish to revert to a fallback - // approach based on other methods. - - // IF YOU ADD A NEW VALUE: - // - Update the stringifier. - // - Update Cap'n Proto's RPC protocol's Exception.Type enum. - }; - - Exception(Type type, const char* file, int line, String description = nullptr) noexcept; - Exception(Type type, String file, int line, String description = nullptr) noexcept; - Exception(const Exception& other) noexcept; - Exception(Exception&& other) = default; - ~Exception() noexcept; - - const char* getFile() const { return file; } - int getLine() const { return line; } - Type getType() const { return type; } - StringPtr getDescription() const { return description; } - ArrayPtr getStackTrace() const { return arrayPtr(trace, traceCount); } - - struct Context { - // Describes a bit about what was going on when the exception was thrown. - - const char* file; - int line; - String description; - Maybe> next; - - Context(const char* file, int line, String&& description, Maybe>&& next) - : file(file), line(line), description(mv(description)), next(mv(next)) {} - Context(const Context& other) noexcept; - }; - - inline Maybe getContext() const { - KJ_IF_MAYBE(c, context) { - return **c; - } else { - return nullptr; - } - } - - void wrapContext(const char* file, int line, String&& description); - // Wraps the context in a new node. This becomes the head node returned by getContext() -- it - // is expected that contexts will be added in reverse order as the exception passes up the - // callback stack. - - KJ_NOINLINE void extendTrace(uint ignoreCount); - // Append the current stack trace to the exception's trace, ignoring the first `ignoreCount` - // frames (see `getStackTrace()` for discussion of `ignoreCount`). - - KJ_NOINLINE void truncateCommonTrace(); - // Remove the part of the stack trace which the exception shares with the caller of this method. - // This is used by the async library to remove the async infrastructure from the stack trace - // before replacing it with the async trace. - - void addTrace(void* ptr); - // Append the given pointer to the backtrace, if it is not already full. This is used by the - // async library to trace through the promise chain that led to the exception. - -private: - String ownFile; - const char* file; - int line; - Type type; - String description; - Maybe> context; - void* trace[32]; - uint traceCount; - - friend class ExceptionImpl; -}; - -StringPtr KJ_STRINGIFY(Exception::Type type); -String KJ_STRINGIFY(const Exception& e); - -// ======================================================================================= - -enum class LogSeverity { - INFO, // Information describing what the code is up to, which users may request to see - // with a flag like `--verbose`. Does not indicate a problem. Not printed by - // default; you must call setLogLevel(INFO) to enable. - WARNING, // A problem was detected but execution can continue with correct output. - ERROR, // Something is wrong, but execution can continue with garbage output. - FATAL, // Something went wrong, and execution cannot continue. - DBG // Temporary debug logging. See KJ_DBG. - - // Make sure to update the stringifier if you add a new severity level. -}; - -StringPtr KJ_STRINGIFY(LogSeverity severity); - -class ExceptionCallback { - // If you don't like C++ exceptions, you may implement and register an ExceptionCallback in order - // to perform your own exception handling. For example, a reasonable thing to do is to have - // onRecoverableException() set a flag indicating that an error occurred, and then check for that - // flag just before writing to storage and/or returning results to the user. If the flag is set, - // discard whatever you have and return an error instead. - // - // ExceptionCallbacks must always be allocated on the stack. When an exception is thrown, the - // newest ExceptionCallback on the calling thread's stack is called. The default implementation - // of each method calls the next-oldest ExceptionCallback for that thread. Thus the callbacks - // behave a lot like try/catch blocks, except that they are called before any stack unwinding - // occurs. - -public: - ExceptionCallback(); - KJ_DISALLOW_COPY(ExceptionCallback); - virtual ~ExceptionCallback() noexcept(false); - - virtual void onRecoverableException(Exception&& exception); - // Called when an exception has been raised, but the calling code has the ability to continue by - // producing garbage output. This method _should_ throw the exception, but is allowed to simply - // return if garbage output is acceptable. - // - // The global default implementation throws an exception unless the library was compiled with - // -fno-exceptions, in which case it logs an error and returns. - - virtual void onFatalException(Exception&& exception); - // Called when an exception has been raised and the calling code cannot continue. If this method - // returns normally, abort() will be called. The method must throw the exception to avoid - // aborting. - // - // The global default implementation throws an exception unless the library was compiled with - // -fno-exceptions, in which case it logs an error and returns. - - virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, - String&& text); - // Called when something wants to log some debug text. `contextDepth` indicates how many levels - // of context the message passed through; it may make sense to indent the message accordingly. - // - // The global default implementation writes the text to stderr. - -protected: - ExceptionCallback& next; - -private: - ExceptionCallback(ExceptionCallback& next); - - class RootExceptionCallback; - friend ExceptionCallback& getExceptionCallback(); -}; - -ExceptionCallback& getExceptionCallback(); -// Returns the current exception callback. - -KJ_NOINLINE KJ_NORETURN(void throwFatalException(kj::Exception&& exception, uint ignoreCount = 0)); -// Invoke the exception callback to throw the given fatal exception. If the exception callback -// returns, abort. - -KJ_NOINLINE void throwRecoverableException(kj::Exception&& exception, uint ignoreCount = 0); -// Invoke the exception callback to throw the given recoverable exception. If the exception -// callback returns, return normally. - -// ======================================================================================= - -namespace _ { class Runnable; } - -template -Maybe runCatchingExceptions(Func&& func) noexcept; -// Executes the given function (usually, a lambda returning nothing) catching any exceptions that -// are thrown. Returns the Exception if there was one, or null if the operation completed normally. -// Non-KJ exceptions will be wrapped. -// -// If exception are disabled (e.g. with -fno-exceptions), this will still detect whether any -// recoverable exceptions occurred while running the function and will return those. - -class UnwindDetector { - // Utility for detecting when a destructor is called due to unwind. Useful for: - // - Avoiding throwing exceptions in this case, which would terminate the program. - // - Detecting whether to commit or roll back a transaction. - // - // To use this class, either inherit privately from it or declare it as a member. The detector - // works by comparing the exception state against that when the constructor was called, so for - // an object that was actually constructed during exception unwind, it will behave as if no - // unwind is taking place. This is usually the desired behavior. - -public: - UnwindDetector(); - - bool isUnwinding() const; - // Returns true if the current thread is in a stack unwind that it wasn't in at the time the - // object was constructed. - - template - void catchExceptionsIfUnwinding(Func&& func) const; - // Runs the given function (e.g., a lambda). If isUnwinding() is true, any exceptions are - // caught and treated as secondary faults, meaning they are considered to be side-effects of the - // exception that is unwinding the stack. Otherwise, exceptions are passed through normally. - -private: - uint uncaughtCount; - - void catchExceptionsAsSecondaryFaults(_::Runnable& runnable) const; -}; - -namespace _ { // private - -class Runnable { -public: - virtual void run() = 0; -}; - -template -class RunnableImpl: public Runnable { -public: - RunnableImpl(Func&& func): func(kj::mv(func)) {} - void run() override { - func(); - } -private: - Func func; -}; - -Maybe runCatchingExceptions(Runnable& runnable) noexcept; - -} // namespace _ (private) - -template -Maybe runCatchingExceptions(Func&& func) noexcept { - _::RunnableImpl> runnable(kj::fwd(func)); - return _::runCatchingExceptions(runnable); -} - -template -void UnwindDetector::catchExceptionsIfUnwinding(Func&& func) const { - if (isUnwinding()) { - _::RunnableImpl> runnable(kj::fwd(func)); - catchExceptionsAsSecondaryFaults(runnable); - } else { - func(); - } -} - -#define KJ_ON_SCOPE_SUCCESS(code) \ - ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ - KJ_DEFER(if (!KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) -// Runs `code` if the current scope is exited normally (not due to an exception). - -#define KJ_ON_SCOPE_FAILURE(code) \ - ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ - KJ_DEFER(if (KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) -// Runs `code` if the current scope is exited due to an exception. - -// ======================================================================================= - -KJ_NOINLINE ArrayPtr getStackTrace(ArrayPtr space, uint ignoreCount); -// Attempt to get the current stack trace, returning a list of pointers to instructions. The -// returned array is a slice of `space`. Provide a larger `space` to get a deeper stack trace. -// If the platform doesn't support stack traces, returns an empty array. -// -// `ignoreCount` items will be truncated from the front of the trace. This is useful for chopping -// off a prefix of the trace that is uninteresting to the developer because it's just locations -// inside the debug infrastructure that is requesting the trace. Be careful to mark functions as -// KJ_NOINLINE if you intend to count them in `ignoreCount`. Note that, unfortunately, the -// ignored entries will still waste space in the `space` array (and the returned array's `begin()` -// is never exactly equal to `space.begin()` due to this effect, even if `ignoreCount` is zero -// since `getStackTrace()` needs to ignore its own internal frames). - -String stringifyStackTrace(ArrayPtr); -// Convert the stack trace to a string with file names and line numbers. This may involve executing -// suprocesses. - -void printStackTraceOnCrash(); -// Registers signal handlers on common "crash" signals like SIGSEGV that will (attempt to) print -// a stack trace. You should call this as early as possible on program startup. Programs using -// KJ_MAIN get this automatically. - -kj::StringPtr trimSourceFilename(kj::StringPtr filename); -// Given a source code file name, trim off noisy prefixes like "src/" or -// "/ekam-provider/canonical/". - -} // namespace kj - -#endif // KJ_EXCEPTION_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. + +#ifndef KJ_EXCEPTION_H_ +#define KJ_EXCEPTION_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "memory.h" +#include "array.h" +#include "string.h" + +namespace kj { + +class ExceptionImpl; + +class Exception { + // Exception thrown in case of fatal errors. + // + // Actually, a subclass of this which also implements std::exception will be thrown, but we hide + // that fact from the interface to avoid #including . + +public: + enum class Type { + // What kind of failure? + + FAILED = 0, + // Something went wrong. This is the usual error type. KJ_ASSERT and KJ_REQUIRE throw this + // error type. + + OVERLOADED = 1, + // The call failed because of a temporary lack of resources. This could be space resources + // (out of memory, out of disk space) or time resources (request queue overflow, operation + // timed out). + // + // The operation might work if tried again, but it should NOT be repeated immediately as this + // may simply exacerbate the problem. + + DISCONNECTED = 2, + // The call required communication over a connection that has been lost. The callee will need + // to re-establish connections and try again. + + UNIMPLEMENTED = 3 + // The requested method is not implemented. The caller may wish to revert to a fallback + // approach based on other methods. + + // IF YOU ADD A NEW VALUE: + // - Update the stringifier. + // - Update Cap'n Proto's RPC protocol's Exception.Type enum. + }; + + Exception(Type type, const char* file, int line, String description = nullptr) noexcept; + Exception(Type type, String file, int line, String description = nullptr) noexcept; + Exception(const Exception& other) noexcept; + Exception(Exception&& other) = default; + ~Exception() noexcept; + + const char* getFile() const { return file; } + int getLine() const { return line; } + Type getType() const { return type; } + StringPtr getDescription() const { return description; } + ArrayPtr getStackTrace() const { return arrayPtr(trace, traceCount); } + + struct Context { + // Describes a bit about what was going on when the exception was thrown. + + const char* file; + int line; + String description; + Maybe> next; + + Context(const char* file, int line, String&& description, Maybe>&& next) + : file(file), line(line), description(mv(description)), next(mv(next)) {} + Context(const Context& other) noexcept; + }; + + inline Maybe getContext() const { + KJ_IF_MAYBE(c, context) { + return **c; + } else { + return nullptr; + } + } + + void wrapContext(const char* file, int line, String&& description); + // Wraps the context in a new node. This becomes the head node returned by getContext() -- it + // is expected that contexts will be added in reverse order as the exception passes up the + // callback stack. + + KJ_NOINLINE void extendTrace(uint ignoreCount); + // Append the current stack trace to the exception's trace, ignoring the first `ignoreCount` + // frames (see `getStackTrace()` for discussion of `ignoreCount`). + + KJ_NOINLINE void truncateCommonTrace(); + // Remove the part of the stack trace which the exception shares with the caller of this method. + // This is used by the async library to remove the async infrastructure from the stack trace + // before replacing it with the async trace. + + void addTrace(void* ptr); + // Append the given pointer to the backtrace, if it is not already full. This is used by the + // async library to trace through the promise chain that led to the exception. + +private: + String ownFile; + const char* file; + int line; + Type type; + String description; + Maybe> context; + void* trace[32]; + uint traceCount; + + friend class ExceptionImpl; +}; + +StringPtr KJ_STRINGIFY(Exception::Type type); +String KJ_STRINGIFY(const Exception& e); + +// ======================================================================================= + +enum class LogSeverity { + INFO, // Information describing what the code is up to, which users may request to see + // with a flag like `--verbose`. Does not indicate a problem. Not printed by + // default; you must call setLogLevel(INFO) to enable. + WARNING, // A problem was detected but execution can continue with correct output. + ERROR, // Something is wrong, but execution can continue with garbage output. + FATAL, // Something went wrong, and execution cannot continue. + DBG // Temporary debug logging. See KJ_DBG. + + // Make sure to update the stringifier if you add a new severity level. +}; + +StringPtr KJ_STRINGIFY(LogSeverity severity); + +class ExceptionCallback { + // If you don't like C++ exceptions, you may implement and register an ExceptionCallback in order + // to perform your own exception handling. For example, a reasonable thing to do is to have + // onRecoverableException() set a flag indicating that an error occurred, and then check for that + // flag just before writing to storage and/or returning results to the user. If the flag is set, + // discard whatever you have and return an error instead. + // + // ExceptionCallbacks must always be allocated on the stack. When an exception is thrown, the + // newest ExceptionCallback on the calling thread's stack is called. The default implementation + // of each method calls the next-oldest ExceptionCallback for that thread. Thus the callbacks + // behave a lot like try/catch blocks, except that they are called before any stack unwinding + // occurs. + +public: + ExceptionCallback(); + KJ_DISALLOW_COPY(ExceptionCallback); + virtual ~ExceptionCallback() noexcept(false); + + virtual void onRecoverableException(Exception&& exception); + // Called when an exception has been raised, but the calling code has the ability to continue by + // producing garbage output. This method _should_ throw the exception, but is allowed to simply + // return if garbage output is acceptable. + // + // The global default implementation throws an exception unless the library was compiled with + // -fno-exceptions, in which case it logs an error and returns. + + virtual void onFatalException(Exception&& exception); + // Called when an exception has been raised and the calling code cannot continue. If this method + // returns normally, abort() will be called. The method must throw the exception to avoid + // aborting. + // + // The global default implementation throws an exception unless the library was compiled with + // -fno-exceptions, in which case it logs an error and returns. + + virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text); + // Called when something wants to log some debug text. `contextDepth` indicates how many levels + // of context the message passed through; it may make sense to indent the message accordingly. + // + // The global default implementation writes the text to stderr. + + enum class StackTraceMode { + FULL, + // Stringifying a stack trace will attempt to determine source file and line numbers. This may + // be expensive. For example, on Linux, this shells out to `addr2line`. + // + // This is the default in debug builds. + + ADDRESS_ONLY, + // Stringifying a stack trace will only generate a list of code addresses. + // + // This is the default in release builds. + + NONE + // Generating a stack trace will always return an empty array. + // + // This avoids ever unwinding the stack. On Windows in particular, the stack unwinding library + // has been observed to be pretty slow, so exception-heavy code might benefit significantly + // from this setting. (But exceptions should be rare...) + }; + + virtual StackTraceMode stackTraceMode(); + // Returns the current preferred stack trace mode. + +protected: + ExceptionCallback& next; + +private: + ExceptionCallback(ExceptionCallback& next); + + class RootExceptionCallback; + friend ExceptionCallback& getExceptionCallback(); +}; + +ExceptionCallback& getExceptionCallback(); +// Returns the current exception callback. + +KJ_NOINLINE KJ_NORETURN(void throwFatalException(kj::Exception&& exception, uint ignoreCount = 0)); +// Invoke the exception callback to throw the given fatal exception. If the exception callback +// returns, abort. + +KJ_NOINLINE void throwRecoverableException(kj::Exception&& exception, uint ignoreCount = 0); +// Invoke the exception callback to throw the given recoverable exception. If the exception +// callback returns, return normally. + +// ======================================================================================= + +namespace _ { class Runnable; } + +template +Maybe runCatchingExceptions(Func&& func) noexcept; +// Executes the given function (usually, a lambda returning nothing) catching any exceptions that +// are thrown. Returns the Exception if there was one, or null if the operation completed normally. +// Non-KJ exceptions will be wrapped. +// +// If exception are disabled (e.g. with -fno-exceptions), this will still detect whether any +// recoverable exceptions occurred while running the function and will return those. + +class UnwindDetector { + // Utility for detecting when a destructor is called due to unwind. Useful for: + // - Avoiding throwing exceptions in this case, which would terminate the program. + // - Detecting whether to commit or roll back a transaction. + // + // To use this class, either inherit privately from it or declare it as a member. The detector + // works by comparing the exception state against that when the constructor was called, so for + // an object that was actually constructed during exception unwind, it will behave as if no + // unwind is taking place. This is usually the desired behavior. + +public: + UnwindDetector(); + + bool isUnwinding() const; + // Returns true if the current thread is in a stack unwind that it wasn't in at the time the + // object was constructed. + + template + void catchExceptionsIfUnwinding(Func&& func) const; + // Runs the given function (e.g., a lambda). If isUnwinding() is true, any exceptions are + // caught and treated as secondary faults, meaning they are considered to be side-effects of the + // exception that is unwinding the stack. Otherwise, exceptions are passed through normally. + +private: + uint uncaughtCount; + + void catchExceptionsAsSecondaryFaults(_::Runnable& runnable) const; +}; + +namespace _ { // private + +class Runnable { +public: + virtual void run() = 0; +}; + +template +class RunnableImpl: public Runnable { +public: + RunnableImpl(Func&& func): func(kj::mv(func)) {} + void run() override { + func(); + } +private: + Func func; +}; + +Maybe runCatchingExceptions(Runnable& runnable) noexcept; + +} // namespace _ (private) + +template +Maybe runCatchingExceptions(Func&& func) noexcept { + _::RunnableImpl> runnable(kj::fwd(func)); + return _::runCatchingExceptions(runnable); +} + +template +void UnwindDetector::catchExceptionsIfUnwinding(Func&& func) const { + if (isUnwinding()) { + _::RunnableImpl> runnable(kj::fwd(func)); + catchExceptionsAsSecondaryFaults(runnable); + } else { + func(); + } +} + +#define KJ_ON_SCOPE_SUCCESS(code) \ + ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ + KJ_DEFER(if (!KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) +// Runs `code` if the current scope is exited normally (not due to an exception). + +#define KJ_ON_SCOPE_FAILURE(code) \ + ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ + KJ_DEFER(if (KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) +// Runs `code` if the current scope is exited due to an exception. + +// ======================================================================================= + +KJ_NOINLINE ArrayPtr getStackTrace(ArrayPtr space, uint ignoreCount); +// Attempt to get the current stack trace, returning a list of pointers to instructions. The +// returned array is a slice of `space`. Provide a larger `space` to get a deeper stack trace. +// If the platform doesn't support stack traces, returns an empty array. +// +// `ignoreCount` items will be truncated from the front of the trace. This is useful for chopping +// off a prefix of the trace that is uninteresting to the developer because it's just locations +// inside the debug infrastructure that is requesting the trace. Be careful to mark functions as +// KJ_NOINLINE if you intend to count them in `ignoreCount`. Note that, unfortunately, the +// ignored entries will still waste space in the `space` array (and the returned array's `begin()` +// is never exactly equal to `space.begin()` due to this effect, even if `ignoreCount` is zero +// since `getStackTrace()` needs to ignore its own internal frames). + +String stringifyStackTrace(ArrayPtr); +// Convert the stack trace to a string with file names and line numbers. This may involve executing +// suprocesses. + +String getStackTrace(); +// Get a stack trace right now and stringify it. Useful for debugging. + +void printStackTraceOnCrash(); +// Registers signal handlers on common "crash" signals like SIGSEGV that will (attempt to) print +// a stack trace. You should call this as early as possible on program startup. Programs using +// KJ_MAIN get this automatically. + +kj::StringPtr trimSourceFilename(kj::StringPtr filename); +// Given a source code file name, trim off noisy prefixes like "src/" or +// "/ekam-provider/canonical/". + +} // namespace kj + +#endif // KJ_EXCEPTION_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/function.h --- a/win32-mingw/include/kj/function.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/function.h Tue May 23 09:16:54 2017 +0100 @@ -1,277 +1,277 @@ -// 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. - -#ifndef KJ_FUNCTION_H_ -#define KJ_FUNCTION_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "memory.h" - -namespace kj { - -template -class Function; -// Function wrapper using virtual-based polymorphism. Use this when template polymorphism is -// not possible. You can, for example, accept a Function as a parameter: -// -// void setFilter(Function filter); -// -// The caller of `setFilter()` may then pass any callable object as the parameter. The callable -// object does not have to have the exact signature specified, just one that is "compatible" -- -// i.e. the return type is covariant and the parameters are contravariant. -// -// Unlike `std::function`, `kj::Function`s are movable but not copyable, just like `kj::Own`. This -// is to avoid unexpected heap allocation or slow atomic reference counting. -// -// When a `Function` is constructed from an lvalue, it captures only a reference to the value. -// When constructed from an rvalue, it invokes the value's move constructor. So, for example: -// -// struct AddN { -// int n; -// int operator(int i) { return i + n; } -// } -// -// Function f1 = AddN{2}; -// // f1 owns an instance of AddN. It may safely be moved out -// // of the local scope. -// -// AddN adder(2); -// Function f2 = adder; -// // f2 contains a reference to `adder`. Thus, it becomes invalid -// // when `adder` goes out-of-scope. -// -// AddN adder2(2); -// Function f3 = kj::mv(adder2); -// // f3 owns an insatnce of AddN moved from `adder2`. f3 may safely -// // be moved out of the local scope. -// -// Additionally, a Function may be bound to a class method using KJ_BIND_METHOD(object, methodName). -// For example: -// -// class Printer { -// public: -// void print(int i); -// void print(kj::StringPtr s); -// }; -// -// Printer p; -// -// Function intPrinter = KJ_BIND_METHOD(p, print); -// // Will call Printer::print(int). -// -// Function strPrinter = KJ_BIND_METHOD(p, print); -// // Will call Printer::print(kj::StringPtr). -// -// Notice how KJ_BIND_METHOD is able to figure out which overload to use depending on the kind of -// Function it is binding to. - -template -class ConstFunction; -// Like Function, but wraps a "const" (i.e. thread-safe) call. - -template -class Function { -public: - template - inline Function(F&& f): impl(heap>(kj::fwd(f))) {} - Function() = default; - - // Make sure people don't accidentally end up wrapping a reference when they meant to return - // a function. - KJ_DISALLOW_COPY(Function); - Function(Function&) = delete; - Function& operator=(Function&) = delete; - template Function(const Function&) = delete; - template Function& operator=(const Function&) = delete; - template Function(const ConstFunction&) = delete; - template Function& operator=(const ConstFunction&) = delete; - Function(Function&&) = default; - Function& operator=(Function&&) = default; - - inline Return operator()(Params... params) { - return (*impl)(kj::fwd(params)...); - } - - Function reference() { - // Forms a new Function of the same type that delegates to this Function by reference. - // Therefore, this Function must outlive the returned Function, but otherwise they behave - // exactly the same. - - return *impl; - } - -private: - class Iface { - public: - virtual Return operator()(Params... params) = 0; - }; - - template - class Impl final: public Iface { - public: - explicit Impl(F&& f): f(kj::fwd(f)) {} - - Return operator()(Params... params) override { - return f(kj::fwd(params)...); - } - - private: - F f; - }; - - Own impl; -}; - -template -class ConstFunction { -public: - template - inline ConstFunction(F&& f): impl(heap>(kj::fwd(f))) {} - ConstFunction() = default; - - // Make sure people don't accidentally end up wrapping a reference when they meant to return - // a function. - KJ_DISALLOW_COPY(ConstFunction); - ConstFunction(ConstFunction&) = delete; - ConstFunction& operator=(ConstFunction&) = delete; - template ConstFunction(const ConstFunction&) = delete; - template ConstFunction& operator=(const ConstFunction&) = delete; - template ConstFunction(const Function&) = delete; - template ConstFunction& operator=(const Function&) = delete; - ConstFunction(ConstFunction&&) = default; - ConstFunction& operator=(ConstFunction&&) = default; - - inline Return operator()(Params... params) const { - return (*impl)(kj::fwd(params)...); - } - - ConstFunction reference() const { - // Forms a new ConstFunction of the same type that delegates to this ConstFunction by reference. - // Therefore, this ConstFunction must outlive the returned ConstFunction, but otherwise they - // behave exactly the same. - - return *impl; - } - -private: - class Iface { - public: - virtual Return operator()(Params... params) const = 0; - }; - - template - class Impl final: public Iface { - public: - explicit Impl(F&& f): f(kj::fwd(f)) {} - - Return operator()(Params... params) const override { - return f(kj::fwd(params)...); - } - - private: - F f; - }; - - Own impl; -}; - -#if 1 - -namespace _ { // private - -template -class BoundMethod; - -template ::*method)(Params...)> -class BoundMethod::*)(Params...), method> { -public: - BoundMethod(T&& t): t(kj::fwd(t)) {} - - Return operator()(Params&&... params) { - return (t.*method)(kj::fwd(params)...); - } - -private: - T t; -}; - -template ::*method)(Params...) const> -class BoundMethod::*)(Params...) const, method> { -public: - BoundMethod(T&& t): t(kj::fwd(t)) {} - - Return operator()(Params&&... params) const { - return (t.*method)(kj::fwd(params)...); - } - -private: - T t; -}; - -} // namespace _ (private) - -#define KJ_BIND_METHOD(obj, method) \ - ::kj::_::BoundMethod::method), \ - &::kj::Decay::method>(obj) -// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an -// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will -// contain a copy (by move) of it. -// -// The current implementation requires that the method is not overloaded. -// -// TODO(someday): C++14's generic lambdas may be able to simplify this code considerably, and -// probably make it work with overloaded methods. - -#else -// Here's a better implementation of the above that doesn't work with GCC (but does with Clang) -// because it uses a local class with a template method. Sigh. This implementation supports -// overloaded methods. - -#define KJ_BIND_METHOD(obj, method) \ - ({ \ - typedef KJ_DECLTYPE_REF(obj) T; \ - class F { \ - public: \ - inline F(T&& t): t(::kj::fwd(t)) {} \ - template \ - auto operator()(Params&&... params) \ - -> decltype(::kj::instance().method(::kj::fwd(params)...)) { \ - return t.method(::kj::fwd(params)...); \ - } \ - private: \ - T t; \ - }; \ - (F(obj)); \ - }) -// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an -// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will -// contain a copy (by move) of it. - -#endif - -} // namespace kj - -#endif // KJ_FUNCTION_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. + +#ifndef KJ_FUNCTION_H_ +#define KJ_FUNCTION_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "memory.h" + +namespace kj { + +template +class Function; +// Function wrapper using virtual-based polymorphism. Use this when template polymorphism is +// not possible. You can, for example, accept a Function as a parameter: +// +// void setFilter(Function filter); +// +// The caller of `setFilter()` may then pass any callable object as the parameter. The callable +// object does not have to have the exact signature specified, just one that is "compatible" -- +// i.e. the return type is covariant and the parameters are contravariant. +// +// Unlike `std::function`, `kj::Function`s are movable but not copyable, just like `kj::Own`. This +// is to avoid unexpected heap allocation or slow atomic reference counting. +// +// When a `Function` is constructed from an lvalue, it captures only a reference to the value. +// When constructed from an rvalue, it invokes the value's move constructor. So, for example: +// +// struct AddN { +// int n; +// int operator(int i) { return i + n; } +// } +// +// Function f1 = AddN{2}; +// // f1 owns an instance of AddN. It may safely be moved out +// // of the local scope. +// +// AddN adder(2); +// Function f2 = adder; +// // f2 contains a reference to `adder`. Thus, it becomes invalid +// // when `adder` goes out-of-scope. +// +// AddN adder2(2); +// Function f3 = kj::mv(adder2); +// // f3 owns an insatnce of AddN moved from `adder2`. f3 may safely +// // be moved out of the local scope. +// +// Additionally, a Function may be bound to a class method using KJ_BIND_METHOD(object, methodName). +// For example: +// +// class Printer { +// public: +// void print(int i); +// void print(kj::StringPtr s); +// }; +// +// Printer p; +// +// Function intPrinter = KJ_BIND_METHOD(p, print); +// // Will call Printer::print(int). +// +// Function strPrinter = KJ_BIND_METHOD(p, print); +// // Will call Printer::print(kj::StringPtr). +// +// Notice how KJ_BIND_METHOD is able to figure out which overload to use depending on the kind of +// Function it is binding to. + +template +class ConstFunction; +// Like Function, but wraps a "const" (i.e. thread-safe) call. + +template +class Function { +public: + template + inline Function(F&& f): impl(heap>(kj::fwd(f))) {} + Function() = default; + + // Make sure people don't accidentally end up wrapping a reference when they meant to return + // a function. + KJ_DISALLOW_COPY(Function); + Function(Function&) = delete; + Function& operator=(Function&) = delete; + template Function(const Function&) = delete; + template Function& operator=(const Function&) = delete; + template Function(const ConstFunction&) = delete; + template Function& operator=(const ConstFunction&) = delete; + Function(Function&&) = default; + Function& operator=(Function&&) = default; + + inline Return operator()(Params... params) { + return (*impl)(kj::fwd(params)...); + } + + Function reference() { + // Forms a new Function of the same type that delegates to this Function by reference. + // Therefore, this Function must outlive the returned Function, but otherwise they behave + // exactly the same. + + return *impl; + } + +private: + class Iface { + public: + virtual Return operator()(Params... params) = 0; + }; + + template + class Impl final: public Iface { + public: + explicit Impl(F&& f): f(kj::fwd(f)) {} + + Return operator()(Params... params) override { + return f(kj::fwd(params)...); + } + + private: + F f; + }; + + Own impl; +}; + +template +class ConstFunction { +public: + template + inline ConstFunction(F&& f): impl(heap>(kj::fwd(f))) {} + ConstFunction() = default; + + // Make sure people don't accidentally end up wrapping a reference when they meant to return + // a function. + KJ_DISALLOW_COPY(ConstFunction); + ConstFunction(ConstFunction&) = delete; + ConstFunction& operator=(ConstFunction&) = delete; + template ConstFunction(const ConstFunction&) = delete; + template ConstFunction& operator=(const ConstFunction&) = delete; + template ConstFunction(const Function&) = delete; + template ConstFunction& operator=(const Function&) = delete; + ConstFunction(ConstFunction&&) = default; + ConstFunction& operator=(ConstFunction&&) = default; + + inline Return operator()(Params... params) const { + return (*impl)(kj::fwd(params)...); + } + + ConstFunction reference() const { + // Forms a new ConstFunction of the same type that delegates to this ConstFunction by reference. + // Therefore, this ConstFunction must outlive the returned ConstFunction, but otherwise they + // behave exactly the same. + + return *impl; + } + +private: + class Iface { + public: + virtual Return operator()(Params... params) const = 0; + }; + + template + class Impl final: public Iface { + public: + explicit Impl(F&& f): f(kj::fwd(f)) {} + + Return operator()(Params... params) const override { + return f(kj::fwd(params)...); + } + + private: + F f; + }; + + Own impl; +}; + +#if 1 + +namespace _ { // private + +template +class BoundMethod; + +template ::*method)(Params...)> +class BoundMethod::*)(Params...), method> { +public: + BoundMethod(T&& t): t(kj::fwd(t)) {} + + Return operator()(Params&&... params) { + return (t.*method)(kj::fwd(params)...); + } + +private: + T t; +}; + +template ::*method)(Params...) const> +class BoundMethod::*)(Params...) const, method> { +public: + BoundMethod(T&& t): t(kj::fwd(t)) {} + + Return operator()(Params&&... params) const { + return (t.*method)(kj::fwd(params)...); + } + +private: + T t; +}; + +} // namespace _ (private) + +#define KJ_BIND_METHOD(obj, method) \ + ::kj::_::BoundMethod::method), \ + &::kj::Decay::method>(obj) +// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an +// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will +// contain a copy (by move) of it. +// +// The current implementation requires that the method is not overloaded. +// +// TODO(someday): C++14's generic lambdas may be able to simplify this code considerably, and +// probably make it work with overloaded methods. + +#else +// Here's a better implementation of the above that doesn't work with GCC (but does with Clang) +// because it uses a local class with a template method. Sigh. This implementation supports +// overloaded methods. + +#define KJ_BIND_METHOD(obj, method) \ + ({ \ + typedef KJ_DECLTYPE_REF(obj) T; \ + class F { \ + public: \ + inline F(T&& t): t(::kj::fwd(t)) {} \ + template \ + auto operator()(Params&&... params) \ + -> decltype(::kj::instance().method(::kj::fwd(params)...)) { \ + return t.method(::kj::fwd(params)...); \ + } \ + private: \ + T t; \ + }; \ + (F(obj)); \ + }) +// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an +// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will +// contain a copy (by move) of it. + +#endif + +} // namespace kj + +#endif // KJ_FUNCTION_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/io.h --- a/win32-mingw/include/kj/io.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/io.h Tue May 23 09:16:54 2017 +0100 @@ -1,331 +1,419 @@ -// 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. - -#ifndef KJ_IO_H_ -#define KJ_IO_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include -#include "common.h" -#include "array.h" -#include "exception.h" - -namespace kj { - -// ======================================================================================= -// Abstract interfaces - -class InputStream { -public: - virtual ~InputStream() noexcept(false); - - size_t read(void* buffer, size_t minBytes, size_t maxBytes); - // Reads at least minBytes and at most maxBytes, copying them into the given buffer. Returns - // the size read. Throws an exception on errors. Implemented in terms of tryRead(). - // - // maxBytes is the number of bytes the caller really wants, but minBytes is the minimum amount - // needed by the caller before it can start doing useful processing. If the stream returns less - // than maxBytes, the caller will usually call read() again later to get the rest. Returning - // less than maxBytes is useful when it makes sense for the caller to parallelize processing - // with I/O. - // - // Never blocks if minBytes is zero. If minBytes is zero and maxBytes is non-zero, this may - // attempt a non-blocking read or may just return zero. To force a read, use a non-zero minBytes. - // To detect EOF without throwing an exception, use tryRead(). - // - // If the InputStream can't produce minBytes, it MUST throw an exception, as the caller is not - // expected to understand how to deal with partial reads. - - virtual size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; - // Like read(), but may return fewer than minBytes on EOF. - - inline void read(void* buffer, size_t bytes) { read(buffer, bytes, bytes); } - // Convenience method for reading an exact number of bytes. - - virtual void skip(size_t bytes); - // Skips past the given number of bytes, discarding them. The default implementation read()s - // into a scratch buffer. -}; - -class OutputStream { -public: - virtual ~OutputStream() noexcept(false); - - virtual void write(const void* buffer, size_t size) = 0; - // Always writes the full size. Throws exception on error. - - virtual void write(ArrayPtr> pieces); - // Equivalent to write()ing each byte array in sequence, which is what the default implementation - // does. Override if you can do something better, e.g. use writev() to do the write in a single - // syscall. -}; - -class BufferedInputStream: public InputStream { - // An input stream which buffers some bytes in memory to reduce system call overhead. - // - OR - - // An input stream that actually reads from some in-memory data structure and wants to give its - // caller a direct pointer to that memory to potentially avoid a copy. - -public: - virtual ~BufferedInputStream() noexcept(false); - - ArrayPtr getReadBuffer(); - // Get a direct pointer into the read buffer, which contains the next bytes in the input. If the - // caller consumes any bytes, it should then call skip() to indicate this. This always returns a - // non-empty buffer or throws an exception. Implemented in terms of tryGetReadBuffer(). - - virtual ArrayPtr tryGetReadBuffer() = 0; - // Like getReadBuffer() but may return an empty buffer on EOF. -}; - -class BufferedOutputStream: public OutputStream { - // An output stream which buffers some bytes in memory to reduce system call overhead. - // - OR - - // An output stream that actually writes into some in-memory data structure and wants to give its - // caller a direct pointer to that memory to potentially avoid a copy. - -public: - virtual ~BufferedOutputStream() noexcept(false); - - virtual ArrayPtr getWriteBuffer() = 0; - // Get a direct pointer into the write buffer. The caller may choose to fill in some prefix of - // this buffer and then pass it to write(), in which case write() may avoid a copy. It is - // incorrect to pass to write any slice of this buffer which is not a prefix. -}; - -// ======================================================================================= -// Buffered streams implemented as wrappers around regular streams - -class BufferedInputStreamWrapper: public BufferedInputStream { - // Implements BufferedInputStream in terms of an InputStream. - // - // Note that the underlying stream's position is unpredictable once the wrapper is destroyed, - // unless the entire stream was consumed. To read a predictable number of bytes in a buffered - // way without going over, you'd need this wrapper to wrap some other wrapper which itself - // implements an artificial EOF at the desired point. Such a stream should be trivial to write - // but is not provided by the library at this time. - -public: - explicit BufferedInputStreamWrapper(InputStream& inner, ArrayPtr buffer = nullptr); - // Creates a buffered stream wrapping the given non-buffered stream. No guarantee is made about - // the position of the inner stream after a buffered wrapper has been created unless the entire - // input is read. - // - // If the second parameter is non-null, the stream uses the given buffer instead of allocating - // its own. This may improve performance if the buffer can be reused. - - KJ_DISALLOW_COPY(BufferedInputStreamWrapper); - ~BufferedInputStreamWrapper() noexcept(false); - - // implements BufferedInputStream ---------------------------------- - ArrayPtr tryGetReadBuffer() override; - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - void skip(size_t bytes) override; - -private: - InputStream& inner; - Array ownedBuffer; - ArrayPtr buffer; - ArrayPtr bufferAvailable; -}; - -class BufferedOutputStreamWrapper: public BufferedOutputStream { - // Implements BufferedOutputStream in terms of an OutputStream. Note that writes to the - // underlying stream may be delayed until flush() is called or the wrapper is destroyed. - -public: - explicit BufferedOutputStreamWrapper(OutputStream& inner, ArrayPtr buffer = nullptr); - // Creates a buffered stream wrapping the given non-buffered stream. - // - // If the second parameter is non-null, the stream uses the given buffer instead of allocating - // its own. This may improve performance if the buffer can be reused. - - KJ_DISALLOW_COPY(BufferedOutputStreamWrapper); - ~BufferedOutputStreamWrapper() noexcept(false); - - void flush(); - // Force the wrapper to write any remaining bytes in its buffer to the inner stream. Note that - // this only flushes this object's buffer; this object has no idea how to flush any other buffers - // that may be present in the underlying stream. - - // implements BufferedOutputStream --------------------------------- - ArrayPtr getWriteBuffer() override; - void write(const void* buffer, size_t size) override; - -private: - OutputStream& inner; - Array ownedBuffer; - ArrayPtr buffer; - byte* bufferPos; - UnwindDetector unwindDetector; -}; - -// ======================================================================================= -// Array I/O - -class ArrayInputStream: public BufferedInputStream { -public: - explicit ArrayInputStream(ArrayPtr array); - KJ_DISALLOW_COPY(ArrayInputStream); - ~ArrayInputStream() noexcept(false); - - // implements BufferedInputStream ---------------------------------- - ArrayPtr tryGetReadBuffer() override; - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - void skip(size_t bytes) override; - -private: - ArrayPtr array; -}; - -class ArrayOutputStream: public BufferedOutputStream { -public: - explicit ArrayOutputStream(ArrayPtr array); - KJ_DISALLOW_COPY(ArrayOutputStream); - ~ArrayOutputStream() noexcept(false); - - ArrayPtr getArray() { - // Get the portion of the array which has been filled in. - return arrayPtr(array.begin(), fillPos); - } - - // implements BufferedInputStream ---------------------------------- - ArrayPtr getWriteBuffer() override; - void write(const void* buffer, size_t size) override; - -private: - ArrayPtr array; - byte* fillPos; -}; - -class VectorOutputStream: public BufferedOutputStream { -public: - explicit VectorOutputStream(size_t initialCapacity = 4096); - KJ_DISALLOW_COPY(VectorOutputStream); - ~VectorOutputStream() noexcept(false); - - ArrayPtr getArray() { - // Get the portion of the array which has been filled in. - return arrayPtr(vector.begin(), fillPos); - } - - // implements BufferedInputStream ---------------------------------- - ArrayPtr getWriteBuffer() override; - void write(const void* buffer, size_t size) override; - -private: - Array vector; - byte* fillPos; - - void grow(size_t minSize); -}; - -// ======================================================================================= -// File descriptor I/O - -class AutoCloseFd { - // A wrapper around a file descriptor which automatically closes the descriptor when destroyed. - // The wrapper supports move construction for transferring ownership of the descriptor. If - // close() returns an error, the destructor throws an exception, UNLESS the destructor is being - // called during unwind from another exception, in which case the close error is ignored. - // - // If your code is not exception-safe, you should not use AutoCloseFd. In this case you will - // have to call close() yourself and handle errors appropriately. - -public: - inline AutoCloseFd(): fd(-1) {} - inline AutoCloseFd(decltype(nullptr)): fd(-1) {} - inline explicit AutoCloseFd(int fd): fd(fd) {} - inline AutoCloseFd(AutoCloseFd&& other) noexcept: fd(other.fd) { other.fd = -1; } - KJ_DISALLOW_COPY(AutoCloseFd); - ~AutoCloseFd() noexcept(false); - - inline AutoCloseFd& operator=(AutoCloseFd&& other) { - AutoCloseFd old(kj::mv(*this)); - fd = other.fd; - other.fd = -1; - return *this; - } - - inline AutoCloseFd& operator=(decltype(nullptr)) { - AutoCloseFd old(kj::mv(*this)); - return *this; - } - - inline operator int() const { return fd; } - inline int get() const { return fd; } - - operator bool() const = delete; - // Deleting this operator prevents accidental use in boolean contexts, which - // the int conversion operator above would otherwise allow. - - inline bool operator==(decltype(nullptr)) { return fd < 0; } - inline bool operator!=(decltype(nullptr)) { return fd >= 0; } - -private: - int fd; - UnwindDetector unwindDetector; -}; - -inline auto KJ_STRINGIFY(const AutoCloseFd& fd) - -> decltype(kj::toCharSequence(implicitCast(fd))) { - return kj::toCharSequence(implicitCast(fd)); -} - -class FdInputStream: public InputStream { - // An InputStream wrapping a file descriptor. - -public: - explicit FdInputStream(int fd): fd(fd) {} - explicit FdInputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} - KJ_DISALLOW_COPY(FdInputStream); - ~FdInputStream() noexcept(false); - - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - -private: - int fd; - AutoCloseFd autoclose; -}; - -class FdOutputStream: public OutputStream { - // An OutputStream wrapping a file descriptor. - -public: - explicit FdOutputStream(int fd): fd(fd) {} - explicit FdOutputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} - KJ_DISALLOW_COPY(FdOutputStream); - ~FdOutputStream() noexcept(false); - - void write(const void* buffer, size_t size) override; - void write(ArrayPtr> pieces) override; - -private: - int fd; - AutoCloseFd autoclose; -}; - -} // namespace kj - -#endif // KJ_IO_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. + +#ifndef KJ_IO_H_ +#define KJ_IO_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include +#include "common.h" +#include "array.h" +#include "exception.h" + +namespace kj { + +// ======================================================================================= +// Abstract interfaces + +class InputStream { +public: + virtual ~InputStream() noexcept(false); + + size_t read(void* buffer, size_t minBytes, size_t maxBytes); + // Reads at least minBytes and at most maxBytes, copying them into the given buffer. Returns + // the size read. Throws an exception on errors. Implemented in terms of tryRead(). + // + // maxBytes is the number of bytes the caller really wants, but minBytes is the minimum amount + // needed by the caller before it can start doing useful processing. If the stream returns less + // than maxBytes, the caller will usually call read() again later to get the rest. Returning + // less than maxBytes is useful when it makes sense for the caller to parallelize processing + // with I/O. + // + // Never blocks if minBytes is zero. If minBytes is zero and maxBytes is non-zero, this may + // attempt a non-blocking read or may just return zero. To force a read, use a non-zero minBytes. + // To detect EOF without throwing an exception, use tryRead(). + // + // If the InputStream can't produce minBytes, it MUST throw an exception, as the caller is not + // expected to understand how to deal with partial reads. + + virtual size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; + // Like read(), but may return fewer than minBytes on EOF. + + inline void read(void* buffer, size_t bytes) { read(buffer, bytes, bytes); } + // Convenience method for reading an exact number of bytes. + + virtual void skip(size_t bytes); + // Skips past the given number of bytes, discarding them. The default implementation read()s + // into a scratch buffer. +}; + +class OutputStream { +public: + virtual ~OutputStream() noexcept(false); + + virtual void write(const void* buffer, size_t size) = 0; + // Always writes the full size. Throws exception on error. + + virtual void write(ArrayPtr> pieces); + // Equivalent to write()ing each byte array in sequence, which is what the default implementation + // does. Override if you can do something better, e.g. use writev() to do the write in a single + // syscall. +}; + +class BufferedInputStream: public InputStream { + // An input stream which buffers some bytes in memory to reduce system call overhead. + // - OR - + // An input stream that actually reads from some in-memory data structure and wants to give its + // caller a direct pointer to that memory to potentially avoid a copy. + +public: + virtual ~BufferedInputStream() noexcept(false); + + ArrayPtr getReadBuffer(); + // Get a direct pointer into the read buffer, which contains the next bytes in the input. If the + // caller consumes any bytes, it should then call skip() to indicate this. This always returns a + // non-empty buffer or throws an exception. Implemented in terms of tryGetReadBuffer(). + + virtual ArrayPtr tryGetReadBuffer() = 0; + // Like getReadBuffer() but may return an empty buffer on EOF. +}; + +class BufferedOutputStream: public OutputStream { + // An output stream which buffers some bytes in memory to reduce system call overhead. + // - OR - + // An output stream that actually writes into some in-memory data structure and wants to give its + // caller a direct pointer to that memory to potentially avoid a copy. + +public: + virtual ~BufferedOutputStream() noexcept(false); + + virtual ArrayPtr getWriteBuffer() = 0; + // Get a direct pointer into the write buffer. The caller may choose to fill in some prefix of + // this buffer and then pass it to write(), in which case write() may avoid a copy. It is + // incorrect to pass to write any slice of this buffer which is not a prefix. +}; + +// ======================================================================================= +// Buffered streams implemented as wrappers around regular streams + +class BufferedInputStreamWrapper: public BufferedInputStream { + // Implements BufferedInputStream in terms of an InputStream. + // + // Note that the underlying stream's position is unpredictable once the wrapper is destroyed, + // unless the entire stream was consumed. To read a predictable number of bytes in a buffered + // way without going over, you'd need this wrapper to wrap some other wrapper which itself + // implements an artificial EOF at the desired point. Such a stream should be trivial to write + // but is not provided by the library at this time. + +public: + explicit BufferedInputStreamWrapper(InputStream& inner, ArrayPtr buffer = nullptr); + // Creates a buffered stream wrapping the given non-buffered stream. No guarantee is made about + // the position of the inner stream after a buffered wrapper has been created unless the entire + // input is read. + // + // If the second parameter is non-null, the stream uses the given buffer instead of allocating + // its own. This may improve performance if the buffer can be reused. + + KJ_DISALLOW_COPY(BufferedInputStreamWrapper); + ~BufferedInputStreamWrapper() noexcept(false); + + // implements BufferedInputStream ---------------------------------- + ArrayPtr tryGetReadBuffer() override; + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + InputStream& inner; + Array ownedBuffer; + ArrayPtr buffer; + ArrayPtr bufferAvailable; +}; + +class BufferedOutputStreamWrapper: public BufferedOutputStream { + // Implements BufferedOutputStream in terms of an OutputStream. Note that writes to the + // underlying stream may be delayed until flush() is called or the wrapper is destroyed. + +public: + explicit BufferedOutputStreamWrapper(OutputStream& inner, ArrayPtr buffer = nullptr); + // Creates a buffered stream wrapping the given non-buffered stream. + // + // If the second parameter is non-null, the stream uses the given buffer instead of allocating + // its own. This may improve performance if the buffer can be reused. + + KJ_DISALLOW_COPY(BufferedOutputStreamWrapper); + ~BufferedOutputStreamWrapper() noexcept(false); + + void flush(); + // Force the wrapper to write any remaining bytes in its buffer to the inner stream. Note that + // this only flushes this object's buffer; this object has no idea how to flush any other buffers + // that may be present in the underlying stream. + + // implements BufferedOutputStream --------------------------------- + ArrayPtr getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + OutputStream& inner; + Array ownedBuffer; + ArrayPtr buffer; + byte* bufferPos; + UnwindDetector unwindDetector; +}; + +// ======================================================================================= +// Array I/O + +class ArrayInputStream: public BufferedInputStream { +public: + explicit ArrayInputStream(ArrayPtr array); + KJ_DISALLOW_COPY(ArrayInputStream); + ~ArrayInputStream() noexcept(false); + + // implements BufferedInputStream ---------------------------------- + ArrayPtr tryGetReadBuffer() override; + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + ArrayPtr array; +}; + +class ArrayOutputStream: public BufferedOutputStream { +public: + explicit ArrayOutputStream(ArrayPtr array); + KJ_DISALLOW_COPY(ArrayOutputStream); + ~ArrayOutputStream() noexcept(false); + + ArrayPtr getArray() { + // Get the portion of the array which has been filled in. + return arrayPtr(array.begin(), fillPos); + } + + // implements BufferedInputStream ---------------------------------- + ArrayPtr getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + ArrayPtr array; + byte* fillPos; +}; + +class VectorOutputStream: public BufferedOutputStream { +public: + explicit VectorOutputStream(size_t initialCapacity = 4096); + KJ_DISALLOW_COPY(VectorOutputStream); + ~VectorOutputStream() noexcept(false); + + ArrayPtr getArray() { + // Get the portion of the array which has been filled in. + return arrayPtr(vector.begin(), fillPos); + } + + // implements BufferedInputStream ---------------------------------- + ArrayPtr getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + Array vector; + byte* fillPos; + + void grow(size_t minSize); +}; + +// ======================================================================================= +// File descriptor I/O + +class AutoCloseFd { + // A wrapper around a file descriptor which automatically closes the descriptor when destroyed. + // The wrapper supports move construction for transferring ownership of the descriptor. If + // close() returns an error, the destructor throws an exception, UNLESS the destructor is being + // called during unwind from another exception, in which case the close error is ignored. + // + // If your code is not exception-safe, you should not use AutoCloseFd. In this case you will + // have to call close() yourself and handle errors appropriately. + +public: + inline AutoCloseFd(): fd(-1) {} + inline AutoCloseFd(decltype(nullptr)): fd(-1) {} + inline explicit AutoCloseFd(int fd): fd(fd) {} + inline AutoCloseFd(AutoCloseFd&& other) noexcept: fd(other.fd) { other.fd = -1; } + KJ_DISALLOW_COPY(AutoCloseFd); + ~AutoCloseFd() noexcept(false); + + inline AutoCloseFd& operator=(AutoCloseFd&& other) { + AutoCloseFd old(kj::mv(*this)); + fd = other.fd; + other.fd = -1; + return *this; + } + + inline AutoCloseFd& operator=(decltype(nullptr)) { + AutoCloseFd old(kj::mv(*this)); + return *this; + } + + inline operator int() const { return fd; } + inline int get() const { return fd; } + + operator bool() const = delete; + // Deleting this operator prevents accidental use in boolean contexts, which + // the int conversion operator above would otherwise allow. + + inline bool operator==(decltype(nullptr)) { return fd < 0; } + inline bool operator!=(decltype(nullptr)) { return fd >= 0; } + +private: + int fd; + UnwindDetector unwindDetector; +}; + +inline auto KJ_STRINGIFY(const AutoCloseFd& fd) + -> decltype(kj::toCharSequence(implicitCast(fd))) { + return kj::toCharSequence(implicitCast(fd)); +} + +class FdInputStream: public InputStream { + // An InputStream wrapping a file descriptor. + +public: + explicit FdInputStream(int fd): fd(fd) {} + explicit FdInputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} + KJ_DISALLOW_COPY(FdInputStream); + ~FdInputStream() noexcept(false); + + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + + inline int getFd() const { return fd; } + +private: + int fd; + AutoCloseFd autoclose; +}; + +class FdOutputStream: public OutputStream { + // An OutputStream wrapping a file descriptor. + +public: + explicit FdOutputStream(int fd): fd(fd) {} + explicit FdOutputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} + KJ_DISALLOW_COPY(FdOutputStream); + ~FdOutputStream() noexcept(false); + + void write(const void* buffer, size_t size) override; + void write(ArrayPtr> pieces) override; + + inline int getFd() const { return fd; } + +private: + int fd; + AutoCloseFd autoclose; +}; + +// ======================================================================================= +// Win32 Handle I/O + +#ifdef _WIN32 + +class AutoCloseHandle { + // A wrapper around a Win32 HANDLE which automatically closes the handle when destroyed. + // The wrapper supports move construction for transferring ownership of the handle. If + // CloseHandle() returns an error, the destructor throws an exception, UNLESS the destructor is + // being called during unwind from another exception, in which case the close error is ignored. + // + // If your code is not exception-safe, you should not use AutoCloseHandle. In this case you will + // have to call close() yourself and handle errors appropriately. + +public: + inline AutoCloseHandle(): handle((void*)-1) {} + inline AutoCloseHandle(decltype(nullptr)): handle((void*)-1) {} + inline explicit AutoCloseHandle(void* handle): handle(handle) {} + inline AutoCloseHandle(AutoCloseHandle&& other) noexcept: handle(other.handle) { + other.handle = (void*)-1; + } + KJ_DISALLOW_COPY(AutoCloseHandle); + ~AutoCloseHandle() noexcept(false); + + inline AutoCloseHandle& operator=(AutoCloseHandle&& other) { + AutoCloseHandle old(kj::mv(*this)); + handle = other.handle; + other.handle = (void*)-1; + return *this; + } + + inline AutoCloseHandle& operator=(decltype(nullptr)) { + AutoCloseHandle old(kj::mv(*this)); + return *this; + } + + inline operator void*() const { return handle; } + inline void* get() const { return handle; } + + operator bool() const = delete; + // Deleting this operator prevents accidental use in boolean contexts, which + // the void* conversion operator above would otherwise allow. + + inline bool operator==(decltype(nullptr)) { return handle != (void*)-1; } + inline bool operator!=(decltype(nullptr)) { return handle == (void*)-1; } + +private: + void* handle; // -1 (aka INVALID_HANDLE_VALUE) if not valid. +}; + +class HandleInputStream: public InputStream { + // An InputStream wrapping a Win32 HANDLE. + +public: + explicit HandleInputStream(void* handle): handle(handle) {} + explicit HandleInputStream(AutoCloseHandle handle): handle(handle), autoclose(mv(handle)) {} + KJ_DISALLOW_COPY(HandleInputStream); + ~HandleInputStream() noexcept(false); + + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + +private: + void* handle; + AutoCloseHandle autoclose; +}; + +class HandleOutputStream: public OutputStream { + // An OutputStream wrapping a Win32 HANDLE. + +public: + explicit HandleOutputStream(void* handle): handle(handle) {} + explicit HandleOutputStream(AutoCloseHandle handle): handle(handle), autoclose(mv(handle)) {} + KJ_DISALLOW_COPY(HandleOutputStream); + ~HandleOutputStream() noexcept(false); + + void write(const void* buffer, size_t size) override; + +private: + void* handle; + AutoCloseHandle autoclose; +}; + +#endif // _WIN32 + +} // namespace kj + +#endif // KJ_IO_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/main.h --- a/win32-mingw/include/kj/main.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/main.h Tue May 23 09:16:54 2017 +0100 @@ -1,407 +1,407 @@ -// 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. - -#ifndef KJ_MAIN_H_ -#define KJ_MAIN_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "array.h" -#include "string.h" -#include "vector.h" -#include "function.h" - -namespace kj { - -class ProcessContext { - // Context for command-line programs. - -public: - virtual StringPtr getProgramName() = 0; - // Get argv[0] as passed to main(). - - KJ_NORETURN(virtual void exit()) = 0; - // Indicates program completion. The program is considered successful unless `error()` was - // called. Typically this exits with _Exit(), meaning that the stack is not unwound, buffers - // are not flushed, etc. -- it is the responsibility of the caller to flush any buffers that - // matter. However, an alternate context implementation e.g. for unit testing purposes could - // choose to throw an exception instead. - // - // At first this approach may sound crazy. Isn't it much better to shut down cleanly? What if - // you lose data? However, it turns out that if you look at each common class of program, _Exit() - // is almost always preferable. Let's break it down: - // - // * Commands: A typical program you might run from the command line is single-threaded and - // exits quickly and deterministically. Commands often use buffered I/O and need to flush - // those buffers before exit. However, most of the work performed by destructors is not - // flushing buffers, but rather freeing up memory, placing objects into freelists, and closing - // file descriptors. All of this is irrelevant if the process is about to exit anyway, and - // for a command that runs quickly, time wasted freeing heap space may make a real difference - // in the overall runtime of a script. Meanwhile, it is usually easy to determine exactly what - // resources need to be flushed before exit, and easy to tell if they are not being flushed - // (because the command fails to produce the expected output). Therefore, it is reasonably - // easy for commands to explicitly ensure all output is flushed before exiting, and it is - // probably a good idea for them to do so anyway, because write failures should be detected - // and handled. For commands, a good strategy is to allocate any objects that require clean - // destruction on the stack, and allow them to go out of scope before the command exits. - // Meanwhile, any resources which do not need to be cleaned up should be allocated as members - // of the command's main class, whose destructor normally will not be called. - // - // * Interactive apps: Programs that interact with the user (whether they be graphical apps - // with windows or console-based apps like emacs) generally exit only when the user asks them - // to. Such applications may store large data structures in memory which need to be synced - // to disk, such as documents or user preferences. However, relying on stack unwind or global - // destructors as the mechanism for ensuring such syncing occurs is probably wrong. First of - // all, it's 2013, and applications ought to be actively syncing changes to non-volatile - // storage the moment those changes are made. Applications can crash at any time and a crash - // should never lose data that is more than half a second old. Meanwhile, if a user actually - // does try to close an application while unsaved changes exist, the application UI should - // prompt the user to decide what to do. Such a UI mechanism is obviously too high level to - // be implemented via destructors, so KJ's use of _Exit() shouldn't make a difference here. - // - // * Servers: A good server is fault-tolerant, prepared for the possibility that at any time - // it could crash, the OS could decide to kill it off, or the machine it is running on could - // just die. So, using _Exit() should be no problem. In fact, servers generally never even - // call exit anyway; they are killed externally. - // - // * Batch jobs: A long-running batch job is something between a command and a server. It - // probably knows exactly what needs to be flushed before exiting, and it probably should be - // fault-tolerant. - // - // Meanwhile, regardless of program type, if you are adhering to KJ style, then the use of - // _Exit() shouldn't be a problem anyway: - // - // * KJ style forbids global mutable state (singletons) in general and global constructors and - // destructors in particular. Therefore, everything that could possibly need cleanup either - // lives on the stack or is transitively owned by something living on the stack. - // - // * Calling exit() simply means "Don't clean up anything older than this stack frame.". If you - // have resources that require cleanup before exit, make sure they are owned by stack frames - // beyond the one that eventually calls exit(). To be as safe as possible, don't place any - // state in your program's main class, and don't call exit() yourself. Then, runMainAndExit() - // will do it, and the only thing on the stack at that time will be your main class, which - // has no state anyway. - // - // TODO(someday): Perhaps we should use the new std::quick_exit(), so that at_quick_exit() is - // available for those who really think they need it. Unfortunately, it is not yet available - // on many platforms. - - virtual void warning(StringPtr message) = 0; - // Print the given message to standard error. A newline is printed after the message if it - // doesn't already have one. - - virtual void error(StringPtr message) = 0; - // Like `warning()`, but also sets a flag indicating that the process has failed, and that when - // it eventually exits it should indicate an error status. - - KJ_NORETURN(virtual void exitError(StringPtr message)) = 0; - // Equivalent to `error(message)` followed by `exit()`. - - KJ_NORETURN(virtual void exitInfo(StringPtr message)) = 0; - // Displays the given non-error message to the user and then calls `exit()`. This is used to - // implement things like --help. - - virtual void increaseLoggingVerbosity() = 0; - // Increase the level of detail produced by the debug logging system. `MainBuilder` invokes - // this if the caller uses the -v flag. - - // TODO(someday): Add interfaces representing standard OS resources like the filesystem, so that - // these things can be mocked out. -}; - -class TopLevelProcessContext final: public ProcessContext { - // A ProcessContext implementation appropriate for use at the actual entry point of a process - // (as opposed to when you are trying to call a program's main function from within some other - // program). This implementation writes errors to stderr, and its `exit()` method actually - // calls the C `quick_exit()` function. - -public: - explicit TopLevelProcessContext(StringPtr programName); - - struct CleanShutdownException { int exitCode; }; - // If the environment variable KJ_CLEAN_SHUTDOWN is set, then exit() will actually throw this - // exception rather than exiting. `kj::runMain()` catches this exception and returns normally. - // This is useful primarily for testing purposes, to assist tools like memory leak checkers that - // are easily confused by quick_exit(). - - StringPtr getProgramName() override; - KJ_NORETURN(void exit() override); - void warning(StringPtr message) override; - void error(StringPtr message) override; - KJ_NORETURN(void exitError(StringPtr message) override); - KJ_NORETURN(void exitInfo(StringPtr message) override); - void increaseLoggingVerbosity() override; - -private: - StringPtr programName; - bool cleanShutdown; - bool hadErrors = false; -}; - -typedef Function params)> MainFunc; - -int runMainAndExit(ProcessContext& context, MainFunc&& func, int argc, char* argv[]); -// Runs the given main function and then exits using the given context. If an exception is thrown, -// this will catch it, report it via the context and exit with an error code. -// -// Normally this function does not return, because returning would probably lead to wasting time -// on cleanup when the process is just going to exit anyway. However, to facilitate memory leak -// checkers and other tools that require a clean shutdown to do their job, if the environment -// variable KJ_CLEAN_SHUTDOWN is set, the function will in fact return an exit code, which should -// then be returned from main(). -// -// Most users will use the KJ_MAIN() macro rather than call this function directly. - -#define KJ_MAIN(MainClass) \ - int main(int argc, char* argv[]) { \ - ::kj::TopLevelProcessContext context(argv[0]); \ - MainClass mainObject(context); \ - return ::kj::runMainAndExit(context, mainObject.getMain(), argc, argv); \ - } -// Convenience macro for declaring a main function based on the given class. The class must have -// a constructor that accepts a ProcessContext& and a method getMain() which returns -// kj::MainFunc (probably building it using a MainBuilder). - -class MainBuilder { - // Builds a main() function with nice argument parsing. As options and arguments are parsed, - // corresponding callbacks are called, so that you never have to write a massive switch() - // statement to interpret arguments. Additionally, this approach encourages you to write - // main classes that have a reasonable API that can be used as an alternative to their - // command-line interface. - // - // All StringPtrs passed to MainBuilder must remain valid until option parsing completes. The - // assumption is that these strings will all be literals, making this an easy requirement. If - // not, consider allocating them in an Arena. - // - // Some flags are automatically recognized by the main functions built by this class: - // --help: Prints help text and exits. The help text is constructed based on the - // information you provide to the builder as you define each flag. - // --verbose: Increase logging verbosity. - // --version: Print version information and exit. - // - // Example usage: - // - // class FooMain { - // public: - // FooMain(kj::ProcessContext& context): context(context) {} - // - // bool setAll() { all = true; return true; } - // // Enable the --all flag. - // - // kj::MainBuilder::Validity setOutput(kj::StringPtr name) { - // // Set the output file. - // - // if (name.endsWith(".foo")) { - // outputFile = name; - // return true; - // } else { - // return "Output file must have extension .foo."; - // } - // } - // - // kj::MainBuilder::Validity processInput(kj::StringPtr name) { - // // Process an input file. - // - // if (!exists(name)) { - // return kj::str(name, ": file not found"); - // } - // // ... process the input file ... - // return true; - // } - // - // kj::MainFunc getMain() { - // return MainBuilder(context, "Foo Builder v1.5", "Reads s and builds a Foo.") - // .addOption({'a', "all"}, KJ_BIND_METHOD(*this, setAll), - // "Frob all the widgets. Otherwise, only some widgets are frobbed.") - // .addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), - // "", "Output to . Must be a .foo file.") - // .expectOneOrMoreArgs("", KJ_BIND_METHOD(*this, processInput)) - // .build(); - // } - // - // private: - // bool all = false; - // kj::StringPtr outputFile; - // kj::ProcessContext& context; - // }; - -public: - MainBuilder(ProcessContext& context, StringPtr version, - StringPtr briefDescription, StringPtr extendedDescription = nullptr); - ~MainBuilder() noexcept(false); - - class OptionName { - public: - OptionName() = default; - inline OptionName(char shortName): isLong(false), shortName(shortName) {} - inline OptionName(const char* longName): isLong(true), longName(longName) {} - - private: - bool isLong; - union { - char shortName; - const char* longName; - }; - friend class MainBuilder; - }; - - class Validity { - public: - inline Validity(bool valid) { - if (!valid) errorMessage = heapString("invalid argument"); - } - inline Validity(const char* errorMessage) - : errorMessage(heapString(errorMessage)) {} - inline Validity(String&& errorMessage) - : errorMessage(kj::mv(errorMessage)) {} - - inline const Maybe& getError() const { return errorMessage; } - inline Maybe releaseError() { return kj::mv(errorMessage); } - - private: - Maybe errorMessage; - friend class MainBuilder; - }; - - MainBuilder& addOption(std::initializer_list names, Function callback, - StringPtr helpText); - // Defines a new option (flag). `names` is a list of characters and strings that can be used to - // specify the option on the command line. Single-character names are used with "-" while string - // names are used with "--". `helpText` is a natural-language description of the flag. - // - // `callback` is called when the option is seen. Its return value indicates whether the option - // was accepted. If not, further option processing stops, and error is written, and the process - // exits. - // - // Example: - // - // builder.addOption({'a', "all"}, KJ_BIND_METHOD(*this, showAll), "Show all files."); - // - // This option could be specified in the following ways: - // - // -a - // --all - // - // Note that single-character option names can be combined into a single argument. For example, - // `-abcd` is equivalent to `-a -b -c -d`. - // - // The help text for this option would look like: - // - // -a, --all - // Show all files. - // - // Note that help text is automatically word-wrapped. - - MainBuilder& addOptionWithArg(std::initializer_list names, - Function callback, - StringPtr argumentTitle, StringPtr helpText); - // Like `addOption()`, but adds an option which accepts an argument. `argumentTitle` is used in - // the help text. The argument text is passed to the callback. - // - // Example: - // - // builder.addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), - // "", "Output to ."); - // - // This option could be specified with an argument of "foo" in the following ways: - // - // -ofoo - // -o foo - // --output=foo - // --output foo - // - // Note that single-character option names can be combined, but only the last option can have an - // argument, since the characters after the option letter are interpreted as the argument. E.g. - // `-abofoo` would be equivalent to `-a -b -o foo`. - // - // The help text for this option would look like: - // - // -o FILENAME, --output=FILENAME - // Output to FILENAME. - - MainBuilder& addSubCommand(StringPtr name, Function getSubParser, - StringPtr briefHelpText); - // If exactly the given name is seen as an argument, invoke getSubParser() and then pass all - // remaining arguments to the parser it returns. This is useful for implementing commands which - // have lots of sub-commands, like "git" (which has sub-commands "checkout", "branch", "pull", - // etc.). - // - // `getSubParser` is only called if the command is seen. This avoids building main functions - // for commands that aren't used. - // - // `briefHelpText` should be brief enough to show immediately after the command name on a single - // line. It will not be wrapped. Users can use the built-in "help" command to get extended - // help on a particular command. - - MainBuilder& expectArg(StringPtr title, Function callback); - MainBuilder& expectOptionalArg(StringPtr title, Function callback); - MainBuilder& expectZeroOrMoreArgs(StringPtr title, Function callback); - MainBuilder& expectOneOrMoreArgs(StringPtr title, Function callback); - // Set callbacks to handle arguments. `expectArg()` and `expectOptionalArg()` specify positional - // arguments with special handling, while `expect{Zero,One}OrMoreArgs()` specifies a handler for - // an argument list (the handler is called once for each argument in the list). `title` - // specifies how the argument should be represented in the usage text. - // - // All options callbacks are called before argument callbacks, regardless of their ordering on - // the command line. This matches GNU getopt's behavior of permuting non-flag arguments to the - // end of the argument list. Also matching getopt, the special option "--" indicates that the - // rest of the command line is all arguments, not options, even if they start with '-'. - // - // The interpretation of positional arguments is fairly flexible. The non-optional arguments can - // be expected at the beginning, end, or in the middle. If more arguments are specified than - // the number of non-optional args, they are assigned to the optional argument handlers in the - // order of registration. - // - // For example, say you called: - // builder.expectArg("", ...); - // builder.expectOptionalArg("", ...); - // builder.expectArg("", ...); - // builder.expectZeroOrMoreArgs("", ...); - // builder.expectArg("", ...); - // - // This command requires at least three arguments: foo, baz, and corge. If four arguments are - // given, the second is assigned to bar. If five or more arguments are specified, then the - // arguments between the third and last are assigned to qux. Note that it never makes sense - // to call `expect*OrMoreArgs()` more than once since only the first call would ever be used. - // - // In practice, you probably shouldn't create such complicated commands as in the above example. - // But, this flexibility seems necessary to support commands where the first argument is special - // as well as commands (like `cp`) where the last argument is special. - - MainBuilder& callAfterParsing(Function callback); - // Call the given function after all arguments have been parsed. - - MainFunc build(); - // Build the "main" function, which simply parses the arguments. Once this returns, the - // `MainBuilder` is no longer valid. - -private: - struct Impl; - Own impl; - - class MainImpl; -}; - -} // namespace kj - -#endif // KJ_MAIN_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. + +#ifndef KJ_MAIN_H_ +#define KJ_MAIN_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "array.h" +#include "string.h" +#include "vector.h" +#include "function.h" + +namespace kj { + +class ProcessContext { + // Context for command-line programs. + +public: + virtual StringPtr getProgramName() = 0; + // Get argv[0] as passed to main(). + + KJ_NORETURN(virtual void exit()) = 0; + // Indicates program completion. The program is considered successful unless `error()` was + // called. Typically this exits with _Exit(), meaning that the stack is not unwound, buffers + // are not flushed, etc. -- it is the responsibility of the caller to flush any buffers that + // matter. However, an alternate context implementation e.g. for unit testing purposes could + // choose to throw an exception instead. + // + // At first this approach may sound crazy. Isn't it much better to shut down cleanly? What if + // you lose data? However, it turns out that if you look at each common class of program, _Exit() + // is almost always preferable. Let's break it down: + // + // * Commands: A typical program you might run from the command line is single-threaded and + // exits quickly and deterministically. Commands often use buffered I/O and need to flush + // those buffers before exit. However, most of the work performed by destructors is not + // flushing buffers, but rather freeing up memory, placing objects into freelists, and closing + // file descriptors. All of this is irrelevant if the process is about to exit anyway, and + // for a command that runs quickly, time wasted freeing heap space may make a real difference + // in the overall runtime of a script. Meanwhile, it is usually easy to determine exactly what + // resources need to be flushed before exit, and easy to tell if they are not being flushed + // (because the command fails to produce the expected output). Therefore, it is reasonably + // easy for commands to explicitly ensure all output is flushed before exiting, and it is + // probably a good idea for them to do so anyway, because write failures should be detected + // and handled. For commands, a good strategy is to allocate any objects that require clean + // destruction on the stack, and allow them to go out of scope before the command exits. + // Meanwhile, any resources which do not need to be cleaned up should be allocated as members + // of the command's main class, whose destructor normally will not be called. + // + // * Interactive apps: Programs that interact with the user (whether they be graphical apps + // with windows or console-based apps like emacs) generally exit only when the user asks them + // to. Such applications may store large data structures in memory which need to be synced + // to disk, such as documents or user preferences. However, relying on stack unwind or global + // destructors as the mechanism for ensuring such syncing occurs is probably wrong. First of + // all, it's 2013, and applications ought to be actively syncing changes to non-volatile + // storage the moment those changes are made. Applications can crash at any time and a crash + // should never lose data that is more than half a second old. Meanwhile, if a user actually + // does try to close an application while unsaved changes exist, the application UI should + // prompt the user to decide what to do. Such a UI mechanism is obviously too high level to + // be implemented via destructors, so KJ's use of _Exit() shouldn't make a difference here. + // + // * Servers: A good server is fault-tolerant, prepared for the possibility that at any time + // it could crash, the OS could decide to kill it off, or the machine it is running on could + // just die. So, using _Exit() should be no problem. In fact, servers generally never even + // call exit anyway; they are killed externally. + // + // * Batch jobs: A long-running batch job is something between a command and a server. It + // probably knows exactly what needs to be flushed before exiting, and it probably should be + // fault-tolerant. + // + // Meanwhile, regardless of program type, if you are adhering to KJ style, then the use of + // _Exit() shouldn't be a problem anyway: + // + // * KJ style forbids global mutable state (singletons) in general and global constructors and + // destructors in particular. Therefore, everything that could possibly need cleanup either + // lives on the stack or is transitively owned by something living on the stack. + // + // * Calling exit() simply means "Don't clean up anything older than this stack frame.". If you + // have resources that require cleanup before exit, make sure they are owned by stack frames + // beyond the one that eventually calls exit(). To be as safe as possible, don't place any + // state in your program's main class, and don't call exit() yourself. Then, runMainAndExit() + // will do it, and the only thing on the stack at that time will be your main class, which + // has no state anyway. + // + // TODO(someday): Perhaps we should use the new std::quick_exit(), so that at_quick_exit() is + // available for those who really think they need it. Unfortunately, it is not yet available + // on many platforms. + + virtual void warning(StringPtr message) = 0; + // Print the given message to standard error. A newline is printed after the message if it + // doesn't already have one. + + virtual void error(StringPtr message) = 0; + // Like `warning()`, but also sets a flag indicating that the process has failed, and that when + // it eventually exits it should indicate an error status. + + KJ_NORETURN(virtual void exitError(StringPtr message)) = 0; + // Equivalent to `error(message)` followed by `exit()`. + + KJ_NORETURN(virtual void exitInfo(StringPtr message)) = 0; + // Displays the given non-error message to the user and then calls `exit()`. This is used to + // implement things like --help. + + virtual void increaseLoggingVerbosity() = 0; + // Increase the level of detail produced by the debug logging system. `MainBuilder` invokes + // this if the caller uses the -v flag. + + // TODO(someday): Add interfaces representing standard OS resources like the filesystem, so that + // these things can be mocked out. +}; + +class TopLevelProcessContext final: public ProcessContext { + // A ProcessContext implementation appropriate for use at the actual entry point of a process + // (as opposed to when you are trying to call a program's main function from within some other + // program). This implementation writes errors to stderr, and its `exit()` method actually + // calls the C `quick_exit()` function. + +public: + explicit TopLevelProcessContext(StringPtr programName); + + struct CleanShutdownException { int exitCode; }; + // If the environment variable KJ_CLEAN_SHUTDOWN is set, then exit() will actually throw this + // exception rather than exiting. `kj::runMain()` catches this exception and returns normally. + // This is useful primarily for testing purposes, to assist tools like memory leak checkers that + // are easily confused by quick_exit(). + + StringPtr getProgramName() override; + KJ_NORETURN(void exit() override); + void warning(StringPtr message) override; + void error(StringPtr message) override; + KJ_NORETURN(void exitError(StringPtr message) override); + KJ_NORETURN(void exitInfo(StringPtr message) override); + void increaseLoggingVerbosity() override; + +private: + StringPtr programName; + bool cleanShutdown; + bool hadErrors = false; +}; + +typedef Function params)> MainFunc; + +int runMainAndExit(ProcessContext& context, MainFunc&& func, int argc, char* argv[]); +// Runs the given main function and then exits using the given context. If an exception is thrown, +// this will catch it, report it via the context and exit with an error code. +// +// Normally this function does not return, because returning would probably lead to wasting time +// on cleanup when the process is just going to exit anyway. However, to facilitate memory leak +// checkers and other tools that require a clean shutdown to do their job, if the environment +// variable KJ_CLEAN_SHUTDOWN is set, the function will in fact return an exit code, which should +// then be returned from main(). +// +// Most users will use the KJ_MAIN() macro rather than call this function directly. + +#define KJ_MAIN(MainClass) \ + int main(int argc, char* argv[]) { \ + ::kj::TopLevelProcessContext context(argv[0]); \ + MainClass mainObject(context); \ + return ::kj::runMainAndExit(context, mainObject.getMain(), argc, argv); \ + } +// Convenience macro for declaring a main function based on the given class. The class must have +// a constructor that accepts a ProcessContext& and a method getMain() which returns +// kj::MainFunc (probably building it using a MainBuilder). + +class MainBuilder { + // Builds a main() function with nice argument parsing. As options and arguments are parsed, + // corresponding callbacks are called, so that you never have to write a massive switch() + // statement to interpret arguments. Additionally, this approach encourages you to write + // main classes that have a reasonable API that can be used as an alternative to their + // command-line interface. + // + // All StringPtrs passed to MainBuilder must remain valid until option parsing completes. The + // assumption is that these strings will all be literals, making this an easy requirement. If + // not, consider allocating them in an Arena. + // + // Some flags are automatically recognized by the main functions built by this class: + // --help: Prints help text and exits. The help text is constructed based on the + // information you provide to the builder as you define each flag. + // --verbose: Increase logging verbosity. + // --version: Print version information and exit. + // + // Example usage: + // + // class FooMain { + // public: + // FooMain(kj::ProcessContext& context): context(context) {} + // + // bool setAll() { all = true; return true; } + // // Enable the --all flag. + // + // kj::MainBuilder::Validity setOutput(kj::StringPtr name) { + // // Set the output file. + // + // if (name.endsWith(".foo")) { + // outputFile = name; + // return true; + // } else { + // return "Output file must have extension .foo."; + // } + // } + // + // kj::MainBuilder::Validity processInput(kj::StringPtr name) { + // // Process an input file. + // + // if (!exists(name)) { + // return kj::str(name, ": file not found"); + // } + // // ... process the input file ... + // return true; + // } + // + // kj::MainFunc getMain() { + // return MainBuilder(context, "Foo Builder v1.5", "Reads s and builds a Foo.") + // .addOption({'a', "all"}, KJ_BIND_METHOD(*this, setAll), + // "Frob all the widgets. Otherwise, only some widgets are frobbed.") + // .addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), + // "", "Output to . Must be a .foo file.") + // .expectOneOrMoreArgs("", KJ_BIND_METHOD(*this, processInput)) + // .build(); + // } + // + // private: + // bool all = false; + // kj::StringPtr outputFile; + // kj::ProcessContext& context; + // }; + +public: + MainBuilder(ProcessContext& context, StringPtr version, + StringPtr briefDescription, StringPtr extendedDescription = nullptr); + ~MainBuilder() noexcept(false); + + class OptionName { + public: + OptionName() = default; + inline OptionName(char shortName): isLong(false), shortName(shortName) {} + inline OptionName(const char* longName): isLong(true), longName(longName) {} + + private: + bool isLong; + union { + char shortName; + const char* longName; + }; + friend class MainBuilder; + }; + + class Validity { + public: + inline Validity(bool valid) { + if (!valid) errorMessage = heapString("invalid argument"); + } + inline Validity(const char* errorMessage) + : errorMessage(heapString(errorMessage)) {} + inline Validity(String&& errorMessage) + : errorMessage(kj::mv(errorMessage)) {} + + inline const Maybe& getError() const { return errorMessage; } + inline Maybe releaseError() { return kj::mv(errorMessage); } + + private: + Maybe errorMessage; + friend class MainBuilder; + }; + + MainBuilder& addOption(std::initializer_list names, Function callback, + StringPtr helpText); + // Defines a new option (flag). `names` is a list of characters and strings that can be used to + // specify the option on the command line. Single-character names are used with "-" while string + // names are used with "--". `helpText` is a natural-language description of the flag. + // + // `callback` is called when the option is seen. Its return value indicates whether the option + // was accepted. If not, further option processing stops, and error is written, and the process + // exits. + // + // Example: + // + // builder.addOption({'a', "all"}, KJ_BIND_METHOD(*this, showAll), "Show all files."); + // + // This option could be specified in the following ways: + // + // -a + // --all + // + // Note that single-character option names can be combined into a single argument. For example, + // `-abcd` is equivalent to `-a -b -c -d`. + // + // The help text for this option would look like: + // + // -a, --all + // Show all files. + // + // Note that help text is automatically word-wrapped. + + MainBuilder& addOptionWithArg(std::initializer_list names, + Function callback, + StringPtr argumentTitle, StringPtr helpText); + // Like `addOption()`, but adds an option which accepts an argument. `argumentTitle` is used in + // the help text. The argument text is passed to the callback. + // + // Example: + // + // builder.addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), + // "", "Output to ."); + // + // This option could be specified with an argument of "foo" in the following ways: + // + // -ofoo + // -o foo + // --output=foo + // --output foo + // + // Note that single-character option names can be combined, but only the last option can have an + // argument, since the characters after the option letter are interpreted as the argument. E.g. + // `-abofoo` would be equivalent to `-a -b -o foo`. + // + // The help text for this option would look like: + // + // -o FILENAME, --output=FILENAME + // Output to FILENAME. + + MainBuilder& addSubCommand(StringPtr name, Function getSubParser, + StringPtr briefHelpText); + // If exactly the given name is seen as an argument, invoke getSubParser() and then pass all + // remaining arguments to the parser it returns. This is useful for implementing commands which + // have lots of sub-commands, like "git" (which has sub-commands "checkout", "branch", "pull", + // etc.). + // + // `getSubParser` is only called if the command is seen. This avoids building main functions + // for commands that aren't used. + // + // `briefHelpText` should be brief enough to show immediately after the command name on a single + // line. It will not be wrapped. Users can use the built-in "help" command to get extended + // help on a particular command. + + MainBuilder& expectArg(StringPtr title, Function callback); + MainBuilder& expectOptionalArg(StringPtr title, Function callback); + MainBuilder& expectZeroOrMoreArgs(StringPtr title, Function callback); + MainBuilder& expectOneOrMoreArgs(StringPtr title, Function callback); + // Set callbacks to handle arguments. `expectArg()` and `expectOptionalArg()` specify positional + // arguments with special handling, while `expect{Zero,One}OrMoreArgs()` specifies a handler for + // an argument list (the handler is called once for each argument in the list). `title` + // specifies how the argument should be represented in the usage text. + // + // All options callbacks are called before argument callbacks, regardless of their ordering on + // the command line. This matches GNU getopt's behavior of permuting non-flag arguments to the + // end of the argument list. Also matching getopt, the special option "--" indicates that the + // rest of the command line is all arguments, not options, even if they start with '-'. + // + // The interpretation of positional arguments is fairly flexible. The non-optional arguments can + // be expected at the beginning, end, or in the middle. If more arguments are specified than + // the number of non-optional args, they are assigned to the optional argument handlers in the + // order of registration. + // + // For example, say you called: + // builder.expectArg("", ...); + // builder.expectOptionalArg("", ...); + // builder.expectArg("", ...); + // builder.expectZeroOrMoreArgs("", ...); + // builder.expectArg("", ...); + // + // This command requires at least three arguments: foo, baz, and corge. If four arguments are + // given, the second is assigned to bar. If five or more arguments are specified, then the + // arguments between the third and last are assigned to qux. Note that it never makes sense + // to call `expect*OrMoreArgs()` more than once since only the first call would ever be used. + // + // In practice, you probably shouldn't create such complicated commands as in the above example. + // But, this flexibility seems necessary to support commands where the first argument is special + // as well as commands (like `cp`) where the last argument is special. + + MainBuilder& callAfterParsing(Function callback); + // Call the given function after all arguments have been parsed. + + MainFunc build(); + // Build the "main" function, which simply parses the arguments. Once this returns, the + // `MainBuilder` is no longer valid. + +private: + struct Impl; + Own impl; + + class MainImpl; +}; + +} // namespace kj + +#endif // KJ_MAIN_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/memory.h --- a/win32-mingw/include/kj/memory.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/memory.h Tue May 23 09:16:54 2017 +0100 @@ -1,404 +1,406 @@ -// 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. - -#ifndef KJ_MEMORY_H_ -#define KJ_MEMORY_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" - -namespace kj { - -// ======================================================================================= -// Disposer -- Implementation details. - -class Disposer { - // Abstract interface for a thing that "disposes" of objects, where "disposing" usually means - // calling the destructor followed by freeing the underlying memory. `Own` encapsulates an - // object pointer with corresponding Disposer. - // - // Few developers will ever touch this interface. It is primarily useful for those implementing - // custom memory allocators. - -protected: - // Do not declare a destructor, as doing so will force a global initializer for each HeapDisposer - // instance. Eww! - - virtual void disposeImpl(void* pointer) const = 0; - // Disposes of the object, given a pointer to the beginning of the object. If the object is - // polymorphic, this pointer is determined by dynamic_cast(). For non-polymorphic types, - // Own does not allow any casting, so the pointer exactly matches the original one given to - // Own. - -public: - - template - void dispose(T* object) const; - // Helper wrapper around disposeImpl(). - // - // If T is polymorphic, calls `disposeImpl(dynamic_cast(object))`, otherwise calls - // `disposeImpl(implicitCast(object))`. - // - // Callers must not call dispose() on the same pointer twice, even if the first call throws - // an exception. - -private: - template - struct Dispose_; -}; - -template -class DestructorOnlyDisposer: public Disposer { - // A disposer that merely calls the type's destructor and nothing else. - -public: - static const DestructorOnlyDisposer instance; - - void disposeImpl(void* pointer) const override { - reinterpret_cast(pointer)->~T(); - } -}; - -template -const DestructorOnlyDisposer DestructorOnlyDisposer::instance = DestructorOnlyDisposer(); - -class NullDisposer: public Disposer { - // A disposer that does nothing. - -public: - static const NullDisposer instance; - - void disposeImpl(void* pointer) const override {} -}; - -// ======================================================================================= -// Own -- An owned pointer. - -template -class Own { - // A transferrable title to a T. When an Own goes out of scope, the object's Disposer is - // called to dispose of it. An Own can be efficiently passed by move, without relocating the - // underlying object; this transfers ownership. - // - // This is much like std::unique_ptr, except: - // - You cannot release(). An owned object is not necessarily allocated with new (see next - // point), so it would be hard to use release() correctly. - // - The deleter is made polymorphic by virtual call rather than by template. This is much - // more powerful -- it allows the use of custom allocators, freelists, etc. This could - // _almost_ be accomplished with unique_ptr by forcing everyone to use something like - // std::unique_ptr, except that things get hairy in the presence of multiple - // inheritance and upcasting, and anyway if you force everyone to use a custom deleter - // then you've lost any benefit to interoperating with the "standard" unique_ptr. - -public: - KJ_DISALLOW_COPY(Own); - inline Own(): disposer(nullptr), ptr(nullptr) {} - inline Own(Own&& other) noexcept - : disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; } - inline Own(Own>&& other) noexcept - : disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; } - template ()>> - inline Own(Own&& other) noexcept - : disposer(other.disposer), ptr(other.ptr) { - static_assert(__is_polymorphic(T), - "Casting owned pointers requires that the target type is polymorphic."); - other.ptr = nullptr; - } - inline Own(T* ptr, const Disposer& disposer) noexcept: disposer(&disposer), ptr(ptr) {} - - ~Own() noexcept(false) { dispose(); } - - inline Own& operator=(Own&& other) { - // Move-assingnment operator. - - // Careful, this might own `other`. Therefore we have to transfer the pointers first, then - // dispose. - const Disposer* disposerCopy = disposer; - T* ptrCopy = ptr; - disposer = other.disposer; - ptr = other.ptr; - other.ptr = nullptr; - if (ptrCopy != nullptr) { - disposerCopy->dispose(const_cast*>(ptrCopy)); - } - return *this; - } - - inline Own& operator=(decltype(nullptr)) { - dispose(); - return *this; - } - - template - Own downcast() { - // Downcast the pointer to Own, destroying the original pointer. If this pointer does not - // actually point at an instance of U, the results are undefined (throws an exception in debug - // mode if RTTI is enabled, otherwise you're on your own). - - Own result; - if (ptr != nullptr) { - result.ptr = &kj::downcast(*ptr); - result.disposer = disposer; - ptr = nullptr; - } - return result; - } - -#define NULLCHECK KJ_IREQUIRE(ptr != nullptr, "null Own<> dereference") - inline T* operator->() { NULLCHECK; return ptr; } - inline const T* operator->() const { NULLCHECK; return ptr; } - inline T& operator*() { NULLCHECK; return *ptr; } - inline const T& operator*() const { NULLCHECK; return *ptr; } -#undef NULLCHECK - inline T* get() { return ptr; } - inline const T* get() const { return ptr; } - inline operator T*() { return ptr; } - inline operator const T*() const { return ptr; } - -private: - const Disposer* disposer; // Only valid if ptr != nullptr. - T* ptr; - - inline explicit Own(decltype(nullptr)): disposer(nullptr), ptr(nullptr) {} - - inline bool operator==(decltype(nullptr)) { return ptr == nullptr; } - inline bool operator!=(decltype(nullptr)) { return ptr != nullptr; } - // Only called by Maybe>. - - inline void dispose() { - // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly - // dispose again. - T* ptrCopy = ptr; - if (ptrCopy != nullptr) { - ptr = nullptr; - disposer->dispose(const_cast*>(ptrCopy)); - } - } - - template - friend class Own; - friend class Maybe>; -}; - -namespace _ { // private - -template -class OwnOwn { -public: - inline OwnOwn(Own&& value) noexcept: value(kj::mv(value)) {} - - inline Own& operator*() & { return value; } - inline const Own& operator*() const & { return value; } - inline Own&& operator*() && { return kj::mv(value); } - inline const Own&& operator*() const && { return kj::mv(value); } - inline Own* operator->() { return &value; } - inline const Own* operator->() const { return &value; } - inline operator Own*() { return value ? &value : nullptr; } - inline operator const Own*() const { return value ? &value : nullptr; } - -private: - Own value; -}; - -template -OwnOwn readMaybe(Maybe>&& maybe) { return OwnOwn(kj::mv(maybe.ptr)); } -template -Own* readMaybe(Maybe>& maybe) { return maybe.ptr ? &maybe.ptr : nullptr; } -template -const Own* readMaybe(const Maybe>& maybe) { return maybe.ptr ? &maybe.ptr : nullptr; } - -} // namespace _ (private) - -template -class Maybe> { -public: - inline Maybe(): ptr(nullptr) {} - inline Maybe(Own&& t) noexcept: ptr(kj::mv(t)) {} - inline Maybe(Maybe&& other) noexcept: ptr(kj::mv(other.ptr)) {} - - template - inline Maybe(Maybe>&& other): ptr(mv(other.ptr)) {} - - inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} - - inline operator Maybe() { return ptr.get(); } - inline operator Maybe() const { return ptr.get(); } - - inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } - - inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } - - Own& orDefault(Own& defaultValue) { - if (ptr == nullptr) { - return defaultValue; - } else { - return ptr; - } - } - const Own& orDefault(const Own& defaultValue) const { - if (ptr == nullptr) { - return defaultValue; - } else { - return ptr; - } - } - - template - auto map(Func&& f) & -> Maybe&>()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(ptr); - } - } - - template - auto map(Func&& f) const & -> Maybe&>()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(ptr); - } - } - - template - auto map(Func&& f) && -> Maybe&&>()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(kj::mv(ptr)); - } - } - - template - auto map(Func&& f) const && -> Maybe&&>()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(kj::mv(ptr)); - } - } - -private: - Own ptr; - - template - friend class Maybe; - template - friend _::OwnOwn _::readMaybe(Maybe>&& maybe); - template - friend Own* _::readMaybe(Maybe>& maybe); - template - friend const Own* _::readMaybe(const Maybe>& maybe); -}; - -namespace _ { // private - -template -class HeapDisposer final: public Disposer { -public: - virtual void disposeImpl(void* pointer) const override { delete reinterpret_cast(pointer); } - - static const HeapDisposer instance; -}; - -template -const HeapDisposer HeapDisposer::instance = HeapDisposer(); - -} // namespace _ (private) - -template -Own heap(Params&&... params) { - // heap(...) allocates a T on the heap, forwarding the parameters to its constructor. The - // exact heap implementation is unspecified -- for now it is operator new, but you should not - // assume this. (Since we know the object size at delete time, we could actually implement an - // allocator that is more efficient than operator new.) - - return Own(new T(kj::fwd(params)...), _::HeapDisposer::instance); -} - -template -Own> heap(T&& orig) { - // Allocate a copy (or move) of the argument on the heap. - // - // The purpose of this overload is to allow you to omit the template parameter as there is only - // one argument and the purpose is to copy it. - - typedef Decay T2; - return Own(new T2(kj::fwd(orig)), _::HeapDisposer::instance); -} - -// ======================================================================================= -// SpaceFor -- assists in manual allocation - -template -class SpaceFor { - // A class which has the same size and alignment as T but does not call its constructor or - // destructor automatically. Instead, call construct() to construct a T in the space, which - // returns an Own which will take care of calling T's destructor later. - -public: - inline SpaceFor() {} - inline ~SpaceFor() {} - - template - Own construct(Params&&... params) { - ctor(value, kj::fwd(params)...); - return Own(&value, DestructorOnlyDisposer::instance); - } - -private: - union { - T value; - }; -}; - -// ======================================================================================= -// Inline implementation details - -template -struct Disposer::Dispose_ { - static void dispose(T* object, const Disposer& disposer) { - // Note that dynamic_cast does not require RTTI to be enabled, because the offset to - // the top of the object is in the vtable -- as it obviously needs to be to correctly implement - // operator delete. - disposer.disposeImpl(dynamic_cast(object)); - } -}; -template -struct Disposer::Dispose_ { - static void dispose(T* object, const Disposer& disposer) { - disposer.disposeImpl(static_cast(object)); - } -}; - -template -void Disposer::dispose(T* object) const { - Dispose_::dispose(object, *this); -} - -} // namespace kj - -#endif // KJ_MEMORY_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. + +#ifndef KJ_MEMORY_H_ +#define KJ_MEMORY_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" + +namespace kj { + +// ======================================================================================= +// Disposer -- Implementation details. + +class Disposer { + // Abstract interface for a thing that "disposes" of objects, where "disposing" usually means + // calling the destructor followed by freeing the underlying memory. `Own` encapsulates an + // object pointer with corresponding Disposer. + // + // Few developers will ever touch this interface. It is primarily useful for those implementing + // custom memory allocators. + +protected: + // Do not declare a destructor, as doing so will force a global initializer for each HeapDisposer + // instance. Eww! + + virtual void disposeImpl(void* pointer) const = 0; + // Disposes of the object, given a pointer to the beginning of the object. If the object is + // polymorphic, this pointer is determined by dynamic_cast(). For non-polymorphic types, + // Own does not allow any casting, so the pointer exactly matches the original one given to + // Own. + +public: + + template + void dispose(T* object) const; + // Helper wrapper around disposeImpl(). + // + // If T is polymorphic, calls `disposeImpl(dynamic_cast(object))`, otherwise calls + // `disposeImpl(implicitCast(object))`. + // + // Callers must not call dispose() on the same pointer twice, even if the first call throws + // an exception. + +private: + template + struct Dispose_; +}; + +template +class DestructorOnlyDisposer: public Disposer { + // A disposer that merely calls the type's destructor and nothing else. + +public: + static const DestructorOnlyDisposer instance; + + void disposeImpl(void* pointer) const override { + reinterpret_cast(pointer)->~T(); + } +}; + +template +const DestructorOnlyDisposer DestructorOnlyDisposer::instance = DestructorOnlyDisposer(); + +class NullDisposer: public Disposer { + // A disposer that does nothing. + +public: + static const NullDisposer instance; + + void disposeImpl(void* pointer) const override {} +}; + +// ======================================================================================= +// Own -- An owned pointer. + +template +class Own { + // A transferrable title to a T. When an Own goes out of scope, the object's Disposer is + // called to dispose of it. An Own can be efficiently passed by move, without relocating the + // underlying object; this transfers ownership. + // + // This is much like std::unique_ptr, except: + // - You cannot release(). An owned object is not necessarily allocated with new (see next + // point), so it would be hard to use release() correctly. + // - The deleter is made polymorphic by virtual call rather than by template. This is much + // more powerful -- it allows the use of custom allocators, freelists, etc. This could + // _almost_ be accomplished with unique_ptr by forcing everyone to use something like + // std::unique_ptr, except that things get hairy in the presence of multiple + // inheritance and upcasting, and anyway if you force everyone to use a custom deleter + // then you've lost any benefit to interoperating with the "standard" unique_ptr. + +public: + KJ_DISALLOW_COPY(Own); + inline Own(): disposer(nullptr), ptr(nullptr) {} + inline Own(Own&& other) noexcept + : disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; } + inline Own(Own>&& other) noexcept + : disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; } + template ()>> + inline Own(Own&& other) noexcept + : disposer(other.disposer), ptr(other.ptr) { + static_assert(__is_polymorphic(T), + "Casting owned pointers requires that the target type is polymorphic."); + other.ptr = nullptr; + } + inline Own(T* ptr, const Disposer& disposer) noexcept: disposer(&disposer), ptr(ptr) {} + + ~Own() noexcept(false) { dispose(); } + + inline Own& operator=(Own&& other) { + // Move-assingnment operator. + + // Careful, this might own `other`. Therefore we have to transfer the pointers first, then + // dispose. + const Disposer* disposerCopy = disposer; + T* ptrCopy = ptr; + disposer = other.disposer; + ptr = other.ptr; + other.ptr = nullptr; + if (ptrCopy != nullptr) { + disposerCopy->dispose(const_cast*>(ptrCopy)); + } + return *this; + } + + inline Own& operator=(decltype(nullptr)) { + dispose(); + return *this; + } + + template + Own downcast() { + // Downcast the pointer to Own, destroying the original pointer. If this pointer does not + // actually point at an instance of U, the results are undefined (throws an exception in debug + // mode if RTTI is enabled, otherwise you're on your own). + + Own result; + if (ptr != nullptr) { + result.ptr = &kj::downcast(*ptr); + result.disposer = disposer; + ptr = nullptr; + } + return result; + } + +#define NULLCHECK KJ_IREQUIRE(ptr != nullptr, "null Own<> dereference") + inline T* operator->() { NULLCHECK; return ptr; } + inline const T* operator->() const { NULLCHECK; return ptr; } + inline T& operator*() { NULLCHECK; return *ptr; } + inline const T& operator*() const { NULLCHECK; return *ptr; } +#undef NULLCHECK + inline T* get() { return ptr; } + inline const T* get() const { return ptr; } + inline operator T*() { return ptr; } + inline operator const T*() const { return ptr; } + +private: + const Disposer* disposer; // Only valid if ptr != nullptr. + T* ptr; + + inline explicit Own(decltype(nullptr)): disposer(nullptr), ptr(nullptr) {} + + inline bool operator==(decltype(nullptr)) { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) { return ptr != nullptr; } + // Only called by Maybe>. + + inline void dispose() { + // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly + // dispose again. + T* ptrCopy = ptr; + if (ptrCopy != nullptr) { + ptr = nullptr; + disposer->dispose(const_cast*>(ptrCopy)); + } + } + + template + friend class Own; + friend class Maybe>; +}; + +namespace _ { // private + +template +class OwnOwn { +public: + inline OwnOwn(Own&& value) noexcept: value(kj::mv(value)) {} + + inline Own& operator*() & { return value; } + inline const Own& operator*() const & { return value; } + inline Own&& operator*() && { return kj::mv(value); } + inline const Own&& operator*() const && { return kj::mv(value); } + inline Own* operator->() { return &value; } + inline const Own* operator->() const { return &value; } + inline operator Own*() { return value ? &value : nullptr; } + inline operator const Own*() const { return value ? &value : nullptr; } + +private: + Own value; +}; + +template +OwnOwn readMaybe(Maybe>&& maybe) { return OwnOwn(kj::mv(maybe.ptr)); } +template +Own* readMaybe(Maybe>& maybe) { return maybe.ptr ? &maybe.ptr : nullptr; } +template +const Own* readMaybe(const Maybe>& maybe) { return maybe.ptr ? &maybe.ptr : nullptr; } + +} // namespace _ (private) + +template +class Maybe> { +public: + inline Maybe(): ptr(nullptr) {} + inline Maybe(Own&& t) noexcept: ptr(kj::mv(t)) {} + inline Maybe(Maybe&& other) noexcept: ptr(kj::mv(other.ptr)) {} + + template + inline Maybe(Maybe>&& other): ptr(mv(other.ptr)) {} + template + inline Maybe(Own&& other): ptr(mv(other)) {} + + inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} + + inline operator Maybe() { return ptr.get(); } + inline operator Maybe() const { return ptr.get(); } + + inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } + + inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } + + Own& orDefault(Own& defaultValue) { + if (ptr == nullptr) { + return defaultValue; + } else { + return ptr; + } + } + const Own& orDefault(const Own& defaultValue) const { + if (ptr == nullptr) { + return defaultValue; + } else { + return ptr; + } + } + + template + auto map(Func&& f) & -> Maybe&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(ptr); + } + } + + template + auto map(Func&& f) const & -> Maybe&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(ptr); + } + } + + template + auto map(Func&& f) && -> Maybe&&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(ptr)); + } + } + + template + auto map(Func&& f) const && -> Maybe&&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(ptr)); + } + } + +private: + Own ptr; + + template + friend class Maybe; + template + friend _::OwnOwn _::readMaybe(Maybe>&& maybe); + template + friend Own* _::readMaybe(Maybe>& maybe); + template + friend const Own* _::readMaybe(const Maybe>& maybe); +}; + +namespace _ { // private + +template +class HeapDisposer final: public Disposer { +public: + virtual void disposeImpl(void* pointer) const override { delete reinterpret_cast(pointer); } + + static const HeapDisposer instance; +}; + +template +const HeapDisposer HeapDisposer::instance = HeapDisposer(); + +} // namespace _ (private) + +template +Own heap(Params&&... params) { + // heap(...) allocates a T on the heap, forwarding the parameters to its constructor. The + // exact heap implementation is unspecified -- for now it is operator new, but you should not + // assume this. (Since we know the object size at delete time, we could actually implement an + // allocator that is more efficient than operator new.) + + return Own(new T(kj::fwd(params)...), _::HeapDisposer::instance); +} + +template +Own> heap(T&& orig) { + // Allocate a copy (or move) of the argument on the heap. + // + // The purpose of this overload is to allow you to omit the template parameter as there is only + // one argument and the purpose is to copy it. + + typedef Decay T2; + return Own(new T2(kj::fwd(orig)), _::HeapDisposer::instance); +} + +// ======================================================================================= +// SpaceFor -- assists in manual allocation + +template +class SpaceFor { + // A class which has the same size and alignment as T but does not call its constructor or + // destructor automatically. Instead, call construct() to construct a T in the space, which + // returns an Own which will take care of calling T's destructor later. + +public: + inline SpaceFor() {} + inline ~SpaceFor() {} + + template + Own construct(Params&&... params) { + ctor(value, kj::fwd(params)...); + return Own(&value, DestructorOnlyDisposer::instance); + } + +private: + union { + T value; + }; +}; + +// ======================================================================================= +// Inline implementation details + +template +struct Disposer::Dispose_ { + static void dispose(T* object, const Disposer& disposer) { + // Note that dynamic_cast does not require RTTI to be enabled, because the offset to + // the top of the object is in the vtable -- as it obviously needs to be to correctly implement + // operator delete. + disposer.disposeImpl(dynamic_cast(object)); + } +}; +template +struct Disposer::Dispose_ { + static void dispose(T* object, const Disposer& disposer) { + disposer.disposeImpl(static_cast(object)); + } +}; + +template +void Disposer::dispose(T* object) const { + Dispose_::dispose(object, *this); +} + +} // namespace kj + +#endif // KJ_MEMORY_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/miniposix.h --- a/win32-mingw/include/kj/miniposix.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/miniposix.h Tue May 23 09:16:54 2017 +0100 @@ -1,152 +1,152 @@ -// 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. - -#ifndef KJ_MINIPOSIX_H_ -#define KJ_MINIPOSIX_H_ - -// This header provides a small subset of the POSIX API which also happens to be available on -// Windows under slightly-different names. - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#if _WIN32 -#include -#include -#include // _O_BINARY -#else -#include -#include -#endif - -#if !_WIN32 || __MINGW32__ -#include -#include -#include -#endif - -#if !_WIN32 -#include -#endif - -namespace kj { -namespace miniposix { - -#if _WIN32 && !__MINGW32__ -// We're on Windows and not MinGW. So, we need to define wrappers for the POSIX API. - -typedef int ssize_t; - -inline ssize_t read(int fd, void* buffer, size_t size) { - return ::_read(fd, buffer, size); -} -inline ssize_t write(int fd, const void* buffer, size_t size) { - return ::_write(fd, buffer, size); -} -inline int close(int fd) { - return ::_close(fd); -} - -#ifndef F_OK -#define F_OK 0 // access() existence test -#endif - -#ifndef S_ISREG -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) // stat() regular file test -#endif -#ifndef S_ISDIR -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) // stat() directory test -#endif - -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 -#endif - -#else -// We're on a POSIX system or MinGW which already defines the wrappers for us. - -using ::ssize_t; -using ::read; -using ::write; -using ::close; - -#endif - -#if _WIN32 -// We're on Windows, including MinGW. pipe() and mkdir() are non-standard even on MinGW. - -inline int pipe(int fds[2]) { - return ::_pipe(fds, 8192, _O_BINARY); -} -inline int mkdir(const char* path, int mode) { - return ::_mkdir(path); -} - -#else -// We're on real POSIX. - -using ::pipe; -using ::mkdir; - -inline size_t iovMax(size_t count) { - // Apparently, there is a maximum number of iovecs allowed per call. I don't understand why. - // Most platforms define IOV_MAX but Linux defines only UIO_MAXIOV and others, like Hurd, - // define neither. - // - // On platforms where both IOV_MAX and UIO_MAXIOV are undefined, we poke sysconf(_SC_IOV_MAX), - // then try to fall back to the POSIX-mandated minimum of _XOPEN_IOV_MAX if that fails. - // - // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html#tag_13_23_03_01 - -#if defined(IOV_MAX) - // Solaris (and others?) - return IOV_MAX; -#elif defined(UIO_MAXIOV) - // Linux - return UIO_MAXIOV; -#else - // POSIX mystery meat - - long iovmax; - - errno = 0; - if ((iovmax = sysconf(_SC_IOV_MAX)) == -1) { - // assume iovmax == -1 && errno == 0 means "unbounded" - return errno ? _XOPEN_IOV_MAX : count; - } else { - return (size_t) iovmax; - } -#endif -} - -#endif - -} // namespace miniposix -} // namespace kj - -#endif // KJ_MINIPOSIX_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. + +#ifndef KJ_MINIPOSIX_H_ +#define KJ_MINIPOSIX_H_ + +// This header provides a small subset of the POSIX API which also happens to be available on +// Windows under slightly-different names. + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#if _WIN32 +#include +#include +#include // _O_BINARY +#else +#include +#include +#endif + +#if !_WIN32 || __MINGW32__ +#include +#include +#include +#endif + +#if !_WIN32 +#include +#endif + +namespace kj { +namespace miniposix { + +#if _WIN32 && !__MINGW32__ +// We're on Windows and not MinGW. So, we need to define wrappers for the POSIX API. + +typedef int ssize_t; + +inline ssize_t read(int fd, void* buffer, size_t size) { + return ::_read(fd, buffer, size); +} +inline ssize_t write(int fd, const void* buffer, size_t size) { + return ::_write(fd, buffer, size); +} +inline int close(int fd) { + return ::_close(fd); +} + +#ifndef F_OK +#define F_OK 0 // access() existence test +#endif + +#ifndef S_ISREG +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) // stat() regular file test +#endif +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) // stat() directory test +#endif + +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + +#else +// We're on a POSIX system or MinGW which already defines the wrappers for us. + +using ::ssize_t; +using ::read; +using ::write; +using ::close; + +#endif + +#if _WIN32 +// We're on Windows, including MinGW. pipe() and mkdir() are non-standard even on MinGW. + +inline int pipe(int fds[2]) { + return ::_pipe(fds, 8192, _O_BINARY); +} +inline int mkdir(const char* path, int mode) { + return ::_mkdir(path); +} + +#else +// We're on real POSIX. + +using ::pipe; +using ::mkdir; + +inline size_t iovMax(size_t count) { + // Apparently, there is a maximum number of iovecs allowed per call. I don't understand why. + // Most platforms define IOV_MAX but Linux defines only UIO_MAXIOV and others, like Hurd, + // define neither. + // + // On platforms where both IOV_MAX and UIO_MAXIOV are undefined, we poke sysconf(_SC_IOV_MAX), + // then try to fall back to the POSIX-mandated minimum of _XOPEN_IOV_MAX if that fails. + // + // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html#tag_13_23_03_01 + +#if defined(IOV_MAX) + // Solaris (and others?) + return IOV_MAX; +#elif defined(UIO_MAXIOV) + // Linux + return UIO_MAXIOV; +#else + // POSIX mystery meat + + long iovmax; + + errno = 0; + if ((iovmax = sysconf(_SC_IOV_MAX)) == -1) { + // assume iovmax == -1 && errno == 0 means "unbounded" + return errno ? _XOPEN_IOV_MAX : count; + } else { + return (size_t) iovmax; + } +#endif +} + +#endif + +} // namespace miniposix +} // namespace kj + +#endif // KJ_MINIPOSIX_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/mutex.h --- a/win32-mingw/include/kj/mutex.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/mutex.h Tue May 23 09:16:54 2017 +0100 @@ -1,369 +1,369 @@ -// 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. - -#ifndef KJ_MUTEX_H_ -#define KJ_MUTEX_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "memory.h" -#include - -#if __linux__ && !defined(KJ_USE_FUTEX) -#define KJ_USE_FUTEX 1 -#endif - -#if !KJ_USE_FUTEX && !_WIN32 -// On Linux we use futex. On other platforms we wrap pthreads. -// TODO(someday): Write efficient low-level locking primitives for other platforms. -#include -#endif - -namespace kj { - -// ======================================================================================= -// Private details -- public interfaces follow below. - -namespace _ { // private - -class Mutex { - // Internal implementation details. See `MutexGuarded`. - -public: - Mutex(); - ~Mutex(); - KJ_DISALLOW_COPY(Mutex); - - enum Exclusivity { - EXCLUSIVE, - SHARED - }; - - void lock(Exclusivity exclusivity); - void unlock(Exclusivity exclusivity); - - void assertLockedByCaller(Exclusivity exclusivity); - // In debug mode, assert that the mutex is locked by the calling thread, or if that is - // non-trivial, assert that the mutex is locked (which should be good enough to catch problems - // in unit tests). In non-debug builds, do nothing. - -private: -#if KJ_USE_FUTEX - uint futex; - // bit 31 (msb) = set if exclusive lock held - // bit 30 (msb) = set if threads are waiting for exclusive lock - // bits 0-29 = count of readers; If an exclusive lock is held, this is the count of threads - // waiting for a read lock, otherwise it is the count of threads that currently hold a read - // lock. - - static constexpr uint EXCLUSIVE_HELD = 1u << 31; - static constexpr uint EXCLUSIVE_REQUESTED = 1u << 30; - static constexpr uint SHARED_COUNT_MASK = EXCLUSIVE_REQUESTED - 1; - -#elif _WIN32 - uintptr_t srwLock; // Actually an SRWLOCK, but don't want to #include in header. - -#else - mutable pthread_rwlock_t mutex; -#endif -}; - -class Once { - // Internal implementation details. See `Lazy`. - -public: -#if KJ_USE_FUTEX - inline Once(bool startInitialized = false) - : futex(startInitialized ? INITIALIZED : UNINITIALIZED) {} -#else - Once(bool startInitialized = false); - ~Once(); -#endif - KJ_DISALLOW_COPY(Once); - - class Initializer { - public: - virtual void run() = 0; - }; - - void runOnce(Initializer& init); - -#if _WIN32 // TODO(perf): Can we make this inline on win32 somehow? - bool isInitialized() noexcept; - -#else - inline bool isInitialized() noexcept { - // Fast path check to see if runOnce() would simply return immediately. -#if KJ_USE_FUTEX - return __atomic_load_n(&futex, __ATOMIC_ACQUIRE) == INITIALIZED; -#else - return __atomic_load_n(&state, __ATOMIC_ACQUIRE) == INITIALIZED; -#endif - } -#endif - - void reset(); - // Returns the state from initialized to uninitialized. It is an error to call this when - // not already initialized, or when runOnce() or isInitialized() might be called concurrently in - // another thread. - -private: -#if KJ_USE_FUTEX - uint futex; - - enum State { - UNINITIALIZED, - INITIALIZING, - INITIALIZING_WITH_WAITERS, - INITIALIZED - }; - -#elif _WIN32 - uintptr_t initOnce; // Actually an INIT_ONCE, but don't want to #include in header. - -#else - enum State { - UNINITIALIZED, - INITIALIZED - }; - State state; - pthread_mutex_t mutex; -#endif -}; - -} // namespace _ (private) - -// ======================================================================================= -// Public interface - -template -class Locked { - // Return type for `MutexGuarded::lock()`. `Locked` provides access to the guarded object - // and unlocks the mutex when it goes out of scope. - -public: - KJ_DISALLOW_COPY(Locked); - inline Locked(): mutex(nullptr), ptr(nullptr) {} - inline Locked(Locked&& other): mutex(other.mutex), ptr(other.ptr) { - other.mutex = nullptr; - other.ptr = nullptr; - } - inline ~Locked() { - if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); - } - - inline Locked& operator=(Locked&& other) { - if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); - mutex = other.mutex; - ptr = other.ptr; - other.mutex = nullptr; - other.ptr = nullptr; - return *this; - } - - inline void release() { - if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); - mutex = nullptr; - ptr = nullptr; - } - - inline T* operator->() { return ptr; } - inline const T* operator->() const { return ptr; } - inline T& operator*() { return *ptr; } - inline const T& operator*() const { return *ptr; } - inline T* get() { return ptr; } - inline const T* get() const { return ptr; } - inline operator T*() { return ptr; } - inline operator const T*() const { return ptr; } - -private: - _::Mutex* mutex; - T* ptr; - - inline Locked(_::Mutex& mutex, T& value): mutex(&mutex), ptr(&value) {} - - template - friend class MutexGuarded; -}; - -template -class MutexGuarded { - // An object of type T, guarded by a mutex. In order to access the object, you must lock it. - // - // Write locks are not "recursive" -- trying to lock again in a thread that already holds a lock - // will deadlock. Recursive write locks are usually a sign of bad design. - // - // Unfortunately, **READ LOCKS ARE NOT RECURSIVE** either. Common sense says they should be. - // But on many operating systems (BSD, OSX), recursively read-locking a pthread_rwlock is - // actually unsafe. The problem is that writers are "prioritized" over readers, so a read lock - // request will block if any write lock requests are outstanding. So, if thread A takes a read - // lock, thread B requests a write lock (and starts waiting), and then thread A tries to take - // another read lock recursively, the result is deadlock. - -public: - template - explicit MutexGuarded(Params&&... params); - // Initialize the mutex-guarded object by passing the given parameters to its constructor. - - Locked lockExclusive() const; - // Exclusively locks the object and returns it. The returned `Locked` can be passed by - // move, similar to `Own`. - // - // This method is declared `const` in accordance with KJ style rules which say that constness - // should be used to indicate thread-safety. It is safe to share a const pointer between threads, - // but it is not safe to share a mutable pointer. Since the whole point of MutexGuarded is to - // be shared between threads, its methods should be const, even though locking it produces a - // non-const pointer to the contained object. - - Locked lockShared() const; - // Lock the value for shared access. Multiple shared locks can be taken concurrently, but cannot - // be held at the same time as a non-shared lock. - - inline const T& getWithoutLock() const { return value; } - inline T& getWithoutLock() { return value; } - // Escape hatch for cases where some external factor guarantees that it's safe to get the - // value. You should treat these like const_cast -- be highly suspicious of any use. - - inline const T& getAlreadyLockedShared() const; - inline T& getAlreadyLockedShared(); - inline T& getAlreadyLockedExclusive() const; - // Like `getWithoutLock()`, but asserts that the lock is already held by the calling thread. - -private: - mutable _::Mutex mutex; - mutable T value; -}; - -template -class MutexGuarded { - // MutexGuarded cannot guard a const type. This would be pointless anyway, and would complicate - // the implementation of Locked, which uses constness to decide what kind of lock it holds. - static_assert(sizeof(T) < 0, "MutexGuarded's type cannot be const."); -}; - -template -class Lazy { - // A lazily-initialized value. - -public: - template - T& get(Func&& init); - template - const T& get(Func&& init) const; - // The first thread to call get() will invoke the given init function to construct the value. - // Other threads will block until construction completes, then return the same value. - // - // `init` is a functor(typically a lambda) which takes `SpaceFor&` as its parameter and returns - // `Own`. If `init` throws an exception, the exception is propagated out of that thread's - // call to `get()`, and subsequent calls behave as if `get()` hadn't been called at all yet -- - // in other words, subsequent calls retry initialization until it succeeds. - -private: - mutable _::Once once; - mutable SpaceFor space; - mutable Own value; - - template - class InitImpl; -}; - -// ======================================================================================= -// Inline implementation details - -template -template -inline MutexGuarded::MutexGuarded(Params&&... params) - : value(kj::fwd(params)...) {} - -template -inline Locked MutexGuarded::lockExclusive() const { - mutex.lock(_::Mutex::EXCLUSIVE); - return Locked(mutex, value); -} - -template -inline Locked MutexGuarded::lockShared() const { - mutex.lock(_::Mutex::SHARED); - return Locked(mutex, value); -} - -template -inline const T& MutexGuarded::getAlreadyLockedShared() const { -#ifdef KJ_DEBUG - mutex.assertLockedByCaller(_::Mutex::SHARED); -#endif - return value; -} -template -inline T& MutexGuarded::getAlreadyLockedShared() { -#ifdef KJ_DEBUG - mutex.assertLockedByCaller(_::Mutex::SHARED); -#endif - return value; -} -template -inline T& MutexGuarded::getAlreadyLockedExclusive() const { -#ifdef KJ_DEBUG - mutex.assertLockedByCaller(_::Mutex::EXCLUSIVE); -#endif - return const_cast(value); -} - -template -template -class Lazy::InitImpl: public _::Once::Initializer { -public: - inline InitImpl(const Lazy& lazy, Func&& func): lazy(lazy), func(kj::fwd(func)) {} - - void run() override { - lazy.value = func(lazy.space); - } - -private: - const Lazy& lazy; - Func func; -}; - -template -template -inline T& Lazy::get(Func&& init) { - if (!once.isInitialized()) { - InitImpl initImpl(*this, kj::fwd(init)); - once.runOnce(initImpl); - } - return *value; -} - -template -template -inline const T& Lazy::get(Func&& init) const { - if (!once.isInitialized()) { - InitImpl initImpl(*this, kj::fwd(init)); - once.runOnce(initImpl); - } - return *value; -} - -} // namespace kj - -#endif // KJ_MUTEX_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. + +#ifndef KJ_MUTEX_H_ +#define KJ_MUTEX_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "memory.h" +#include + +#if __linux__ && !defined(KJ_USE_FUTEX) +#define KJ_USE_FUTEX 1 +#endif + +#if !KJ_USE_FUTEX && !_WIN32 +// On Linux we use futex. On other platforms we wrap pthreads. +// TODO(someday): Write efficient low-level locking primitives for other platforms. +#include +#endif + +namespace kj { + +// ======================================================================================= +// Private details -- public interfaces follow below. + +namespace _ { // private + +class Mutex { + // Internal implementation details. See `MutexGuarded`. + +public: + Mutex(); + ~Mutex(); + KJ_DISALLOW_COPY(Mutex); + + enum Exclusivity { + EXCLUSIVE, + SHARED + }; + + void lock(Exclusivity exclusivity); + void unlock(Exclusivity exclusivity); + + void assertLockedByCaller(Exclusivity exclusivity); + // In debug mode, assert that the mutex is locked by the calling thread, or if that is + // non-trivial, assert that the mutex is locked (which should be good enough to catch problems + // in unit tests). In non-debug builds, do nothing. + +private: +#if KJ_USE_FUTEX + uint futex; + // bit 31 (msb) = set if exclusive lock held + // bit 30 (msb) = set if threads are waiting for exclusive lock + // bits 0-29 = count of readers; If an exclusive lock is held, this is the count of threads + // waiting for a read lock, otherwise it is the count of threads that currently hold a read + // lock. + + static constexpr uint EXCLUSIVE_HELD = 1u << 31; + static constexpr uint EXCLUSIVE_REQUESTED = 1u << 30; + static constexpr uint SHARED_COUNT_MASK = EXCLUSIVE_REQUESTED - 1; + +#elif _WIN32 + uintptr_t srwLock; // Actually an SRWLOCK, but don't want to #include in header. + +#else + mutable pthread_rwlock_t mutex; +#endif +}; + +class Once { + // Internal implementation details. See `Lazy`. + +public: +#if KJ_USE_FUTEX + inline Once(bool startInitialized = false) + : futex(startInitialized ? INITIALIZED : UNINITIALIZED) {} +#else + Once(bool startInitialized = false); + ~Once(); +#endif + KJ_DISALLOW_COPY(Once); + + class Initializer { + public: + virtual void run() = 0; + }; + + void runOnce(Initializer& init); + +#if _WIN32 // TODO(perf): Can we make this inline on win32 somehow? + bool isInitialized() noexcept; + +#else + inline bool isInitialized() noexcept { + // Fast path check to see if runOnce() would simply return immediately. +#if KJ_USE_FUTEX + return __atomic_load_n(&futex, __ATOMIC_ACQUIRE) == INITIALIZED; +#else + return __atomic_load_n(&state, __ATOMIC_ACQUIRE) == INITIALIZED; +#endif + } +#endif + + void reset(); + // Returns the state from initialized to uninitialized. It is an error to call this when + // not already initialized, or when runOnce() or isInitialized() might be called concurrently in + // another thread. + +private: +#if KJ_USE_FUTEX + uint futex; + + enum State { + UNINITIALIZED, + INITIALIZING, + INITIALIZING_WITH_WAITERS, + INITIALIZED + }; + +#elif _WIN32 + uintptr_t initOnce; // Actually an INIT_ONCE, but don't want to #include in header. + +#else + enum State { + UNINITIALIZED, + INITIALIZED + }; + State state; + pthread_mutex_t mutex; +#endif +}; + +} // namespace _ (private) + +// ======================================================================================= +// Public interface + +template +class Locked { + // Return type for `MutexGuarded::lock()`. `Locked` provides access to the bounded object + // and unlocks the mutex when it goes out of scope. + +public: + KJ_DISALLOW_COPY(Locked); + inline Locked(): mutex(nullptr), ptr(nullptr) {} + inline Locked(Locked&& other): mutex(other.mutex), ptr(other.ptr) { + other.mutex = nullptr; + other.ptr = nullptr; + } + inline ~Locked() { + if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); + } + + inline Locked& operator=(Locked&& other) { + if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); + mutex = other.mutex; + ptr = other.ptr; + other.mutex = nullptr; + other.ptr = nullptr; + return *this; + } + + inline void release() { + if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); + mutex = nullptr; + ptr = nullptr; + } + + inline T* operator->() { return ptr; } + inline const T* operator->() const { return ptr; } + inline T& operator*() { return *ptr; } + inline const T& operator*() const { return *ptr; } + inline T* get() { return ptr; } + inline const T* get() const { return ptr; } + inline operator T*() { return ptr; } + inline operator const T*() const { return ptr; } + +private: + _::Mutex* mutex; + T* ptr; + + inline Locked(_::Mutex& mutex, T& value): mutex(&mutex), ptr(&value) {} + + template + friend class MutexGuarded; +}; + +template +class MutexGuarded { + // An object of type T, bounded by a mutex. In order to access the object, you must lock it. + // + // Write locks are not "recursive" -- trying to lock again in a thread that already holds a lock + // will deadlock. Recursive write locks are usually a sign of bad design. + // + // Unfortunately, **READ LOCKS ARE NOT RECURSIVE** either. Common sense says they should be. + // But on many operating systems (BSD, OSX), recursively read-locking a pthread_rwlock is + // actually unsafe. The problem is that writers are "prioritized" over readers, so a read lock + // request will block if any write lock requests are outstanding. So, if thread A takes a read + // lock, thread B requests a write lock (and starts waiting), and then thread A tries to take + // another read lock recursively, the result is deadlock. + +public: + template + explicit MutexGuarded(Params&&... params); + // Initialize the mutex-bounded object by passing the given parameters to its constructor. + + Locked lockExclusive() const; + // Exclusively locks the object and returns it. The returned `Locked` can be passed by + // move, similar to `Own`. + // + // This method is declared `const` in accordance with KJ style rules which say that constness + // should be used to indicate thread-safety. It is safe to share a const pointer between threads, + // but it is not safe to share a mutable pointer. Since the whole point of MutexGuarded is to + // be shared between threads, its methods should be const, even though locking it produces a + // non-const pointer to the contained object. + + Locked lockShared() const; + // Lock the value for shared access. Multiple shared locks can be taken concurrently, but cannot + // be held at the same time as a non-shared lock. + + inline const T& getWithoutLock() const { return value; } + inline T& getWithoutLock() { return value; } + // Escape hatch for cases where some external factor guarantees that it's safe to get the + // value. You should treat these like const_cast -- be highly suspicious of any use. + + inline const T& getAlreadyLockedShared() const; + inline T& getAlreadyLockedShared(); + inline T& getAlreadyLockedExclusive() const; + // Like `getWithoutLock()`, but asserts that the lock is already held by the calling thread. + +private: + mutable _::Mutex mutex; + mutable T value; +}; + +template +class MutexGuarded { + // MutexGuarded cannot guard a const type. This would be pointless anyway, and would complicate + // the implementation of Locked, which uses constness to decide what kind of lock it holds. + static_assert(sizeof(T) < 0, "MutexGuarded's type cannot be const."); +}; + +template +class Lazy { + // A lazily-initialized value. + +public: + template + T& get(Func&& init); + template + const T& get(Func&& init) const; + // The first thread to call get() will invoke the given init function to construct the value. + // Other threads will block until construction completes, then return the same value. + // + // `init` is a functor(typically a lambda) which takes `SpaceFor&` as its parameter and returns + // `Own`. If `init` throws an exception, the exception is propagated out of that thread's + // call to `get()`, and subsequent calls behave as if `get()` hadn't been called at all yet -- + // in other words, subsequent calls retry initialization until it succeeds. + +private: + mutable _::Once once; + mutable SpaceFor space; + mutable Own value; + + template + class InitImpl; +}; + +// ======================================================================================= +// Inline implementation details + +template +template +inline MutexGuarded::MutexGuarded(Params&&... params) + : value(kj::fwd(params)...) {} + +template +inline Locked MutexGuarded::lockExclusive() const { + mutex.lock(_::Mutex::EXCLUSIVE); + return Locked(mutex, value); +} + +template +inline Locked MutexGuarded::lockShared() const { + mutex.lock(_::Mutex::SHARED); + return Locked(mutex, value); +} + +template +inline const T& MutexGuarded::getAlreadyLockedShared() const { +#ifdef KJ_DEBUG + mutex.assertLockedByCaller(_::Mutex::SHARED); +#endif + return value; +} +template +inline T& MutexGuarded::getAlreadyLockedShared() { +#ifdef KJ_DEBUG + mutex.assertLockedByCaller(_::Mutex::SHARED); +#endif + return value; +} +template +inline T& MutexGuarded::getAlreadyLockedExclusive() const { +#ifdef KJ_DEBUG + mutex.assertLockedByCaller(_::Mutex::EXCLUSIVE); +#endif + return const_cast(value); +} + +template +template +class Lazy::InitImpl: public _::Once::Initializer { +public: + inline InitImpl(const Lazy& lazy, Func&& func): lazy(lazy), func(kj::fwd(func)) {} + + void run() override { + lazy.value = func(lazy.space); + } + +private: + const Lazy& lazy; + Func func; +}; + +template +template +inline T& Lazy::get(Func&& init) { + if (!once.isInitialized()) { + InitImpl initImpl(*this, kj::fwd(init)); + once.runOnce(initImpl); + } + return *value; +} + +template +template +inline const T& Lazy::get(Func&& init) const { + if (!once.isInitialized()) { + InitImpl initImpl(*this, kj::fwd(init)); + once.runOnce(initImpl); + } + return *value; +} + +} // namespace kj + +#endif // KJ_MUTEX_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/one-of.h --- a/win32-mingw/include/kj/one-of.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/one-of.h Tue May 23 09:16:54 2017 +0100 @@ -1,150 +1,155 @@ -// 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. - -#ifndef KJ_ONE_OF_H_ -#define KJ_ONE_OF_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" - -namespace kj { - -namespace _ { // private - -template -struct TypeIndex_ { static constexpr uint value = TypeIndex_::value; }; -template -struct TypeIndex_ { static constexpr uint value = i; }; - -} // namespace _ (private) - -template -class OneOf { - template - static inline constexpr uint typeIndex() { return _::TypeIndex_<1, Key, Variants...>::value; } - // Get the 1-based index of Key within the type list Types. - -public: - inline OneOf(): tag(0) {} - OneOf(const OneOf& other) { copyFrom(other); } - OneOf(OneOf&& other) { moveFrom(other); } - ~OneOf() { destroy(); } - - OneOf& operator=(const OneOf& other) { if (tag != 0) destroy(); copyFrom(other); return *this; } - OneOf& operator=(OneOf&& other) { if (tag != 0) destroy(); moveFrom(other); return *this; } - - inline bool operator==(decltype(nullptr)) const { return tag == 0; } - inline bool operator!=(decltype(nullptr)) const { return tag != 0; } - - template - bool is() const { - return tag == typeIndex(); - } - - template - T& get() { - KJ_IREQUIRE(is(), "Must check OneOf::is() before calling get()."); - return *reinterpret_cast(space); - } - template - const T& get() const { - KJ_IREQUIRE(is(), "Must check OneOf::is() before calling get()."); - return *reinterpret_cast(space); - } - - template - void init(Params&&... params) { - if (tag != 0) destroy(); - ctor(*reinterpret_cast(space), kj::fwd(params)...); - tag = typeIndex(); - } - -private: - uint tag; - - static inline constexpr size_t maxSize(size_t a) { - return a; - } - template - static inline constexpr size_t maxSize(size_t a, size_t b, Rest... rest) { - return maxSize(kj::max(a, b), rest...); - } - // Returns the maximum of all the parameters. - // TODO(someday): Generalize the above template and make it common. I tried, but C++ decided to - // be difficult so I cut my losses. - - union { - byte space[maxSize(sizeof(Variants)...)]; - - void* forceAligned; - // TODO(someday): Use C++11 alignas() once we require GCC 4.8 / Clang 3.3. - }; - - template - inline void doAll(T... t) {} - - template - inline bool destroyVariant() { - if (tag == typeIndex()) { - tag = 0; - dtor(*reinterpret_cast(space)); - } - return false; - } - void destroy() { - doAll(destroyVariant()...); - } - - template - inline bool copyVariantFrom(const OneOf& other) { - if (other.is()) { - ctor(*reinterpret_cast(space), other.get()); - } - return false; - } - void copyFrom(const OneOf& other) { - // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag - // is invalid. - tag = other.tag; - doAll(copyVariantFrom(other)...); - } - - template - inline bool moveVariantFrom(OneOf& other) { - if (other.is()) { - ctor(*reinterpret_cast(space), kj::mv(other.get())); - } - return false; - } - void moveFrom(OneOf& other) { - // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag - // is invalid. - tag = other.tag; - doAll(moveVariantFrom(other)...); - } -}; - -} // namespace kj - -#endif // KJ_ONE_OF_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. + +#ifndef KJ_ONE_OF_H_ +#define KJ_ONE_OF_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" + +namespace kj { + +namespace _ { // private + +template +struct TypeIndex_ { static constexpr uint value = TypeIndex_::value; }; +template +struct TypeIndex_ { static constexpr uint value = i; }; + +} // namespace _ (private) + +template +class OneOf { + template + static inline constexpr uint typeIndex() { return _::TypeIndex_<1, Key, Variants...>::value; } + // Get the 1-based index of Key within the type list Types. + +public: + inline OneOf(): tag(0) {} + OneOf(const OneOf& other) { copyFrom(other); } + OneOf(OneOf&& other) { moveFrom(other); } + ~OneOf() { destroy(); } + + OneOf& operator=(const OneOf& other) { if (tag != 0) destroy(); copyFrom(other); return *this; } + OneOf& operator=(OneOf&& other) { if (tag != 0) destroy(); moveFrom(other); return *this; } + + inline bool operator==(decltype(nullptr)) const { return tag == 0; } + inline bool operator!=(decltype(nullptr)) const { return tag != 0; } + + template + bool is() const { + return tag == typeIndex(); + } + + template + T& get() { + KJ_IREQUIRE(is(), "Must check OneOf::is() before calling get()."); + return *reinterpret_cast(space); + } + template + const T& get() const { + KJ_IREQUIRE(is(), "Must check OneOf::is() before calling get()."); + return *reinterpret_cast(space); + } + + template + T& init(Params&&... params) { + if (tag != 0) destroy(); + ctor(*reinterpret_cast(space), kj::fwd(params)...); + tag = typeIndex(); + return *reinterpret_cast(space); + } + +private: + uint tag; + + static inline constexpr size_t maxSize(size_t a) { + return a; + } + template + static inline constexpr size_t maxSize(size_t a, size_t b, Rest... rest) { + return maxSize(kj::max(a, b), rest...); + } + // Returns the maximum of all the parameters. + // TODO(someday): Generalize the above template and make it common. I tried, but C++ decided to + // be difficult so I cut my losses. + + static constexpr auto spaceSize = maxSize(sizeof(Variants)...); + // TODO(msvc): This constant could just as well go directly inside space's bracket's, where it's + // used, but MSVC suffers a parse error on `...`. + + union { + byte space[spaceSize]; + + void* forceAligned; + // TODO(someday): Use C++11 alignas() once we require GCC 4.8 / Clang 3.3. + }; + + template + inline void doAll(T... t) {} + + template + inline bool destroyVariant() { + if (tag == typeIndex()) { + tag = 0; + dtor(*reinterpret_cast(space)); + } + return false; + } + void destroy() { + doAll(destroyVariant()...); + } + + template + inline bool copyVariantFrom(const OneOf& other) { + if (other.is()) { + ctor(*reinterpret_cast(space), other.get()); + } + return false; + } + void copyFrom(const OneOf& other) { + // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag + // is invalid. + tag = other.tag; + doAll(copyVariantFrom(other)...); + } + + template + inline bool moveVariantFrom(OneOf& other) { + if (other.is()) { + ctor(*reinterpret_cast(space), kj::mv(other.get())); + } + return false; + } + void moveFrom(OneOf& other) { + // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag + // is invalid. + tag = other.tag; + doAll(moveVariantFrom(other)...); + } +}; + +} // namespace kj + +#endif // KJ_ONE_OF_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/refcount.h --- a/win32-mingw/include/kj/refcount.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/refcount.h Tue May 23 09:16:54 2017 +0100 @@ -1,107 +1,107 @@ -// 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. - -#include "memory.h" - -#ifndef KJ_REFCOUNT_H_ -#define KJ_REFCOUNT_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -namespace kj { - -class Refcounted: private Disposer { - // Subclass this to create a class that contains a reference count. Then, use - // `kj::refcounted()` to allocate a new refcounted pointer. - // - // Do NOT use this lightly. Refcounting is a crutch. Good designs should strive to make object - // ownership clear, so that refcounting is not necessary. All that said, reference counting can - // sometimes simplify code that would otherwise become convoluted with explicit ownership, even - // when ownership relationships are clear at an abstract level. - // - // NOT THREADSAFE: This refcounting implementation assumes that an object's references are - // manipulated only in one thread, because atomic (thread-safe) refcounting is surprisingly slow. - // - // In general, abstract classes should _not_ subclass this. The concrete class at the bottom - // of the hierarchy should be the one to decide how it implements refcounting. Interfaces should - // expose only an `addRef()` method that returns `Own`. There are two reasons for - // this rule: - // 1. Interfaces would need to virtually inherit Refcounted, otherwise two refcounted interfaces - // could not be inherited by the same subclass. Virtual inheritance is awkward and - // inefficient. - // 2. An implementation may decide that it would rather return a copy than a refcount, or use - // some other strategy. - // - // TODO(cleanup): Rethink above. Virtual inheritance is not necessarily that bad. OTOH, a - // virtual function call for every refcount is sad in its own way. A Ref type to replace - // Own could also be nice. - -public: - virtual ~Refcounted() noexcept(false); - - inline bool isShared() const { return refcount > 1; } - // Check if there are multiple references to this object. This is sometimes useful for deciding - // whether it's safe to modify the object vs. make a copy. - -private: - mutable uint refcount = 0; - // "mutable" because disposeImpl() is const. Bleh. - - void disposeImpl(void* pointer) const override; - template - static Own addRefInternal(T* object); - - template - friend Own addRef(T& object); - template - friend Own refcounted(Params&&... params); -}; - -template -inline Own refcounted(Params&&... params) { - // Allocate a new refcounted instance of T, passing `params` to its constructor. Returns an - // initial reference to the object. More references can be created with `kj::addRef()`. - - return Refcounted::addRefInternal(new T(kj::fwd(params)...)); -} - -template -Own addRef(T& object) { - // Return a new reference to `object`, which must subclass Refcounted and have been allocated - // using `kj::refcounted<>()`. It is suggested that subclasses implement a non-static addRef() - // method which wraps this and returns the appropriate type. - - KJ_IREQUIRE(object.Refcounted::refcount > 0, "Object not allocated with kj::refcounted()."); - return Refcounted::addRefInternal(&object); -} - -template -Own Refcounted::addRefInternal(T* object) { - Refcounted* refcounted = object; - ++refcounted->refcount; - return Own(object, *refcounted); -} - -} // namespace kj - -#endif // KJ_REFCOUNT_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. + +#include "memory.h" + +#ifndef KJ_REFCOUNT_H_ +#define KJ_REFCOUNT_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +namespace kj { + +class Refcounted: private Disposer { + // Subclass this to create a class that contains a reference count. Then, use + // `kj::refcounted()` to allocate a new refcounted pointer. + // + // Do NOT use this lightly. Refcounting is a crutch. Good designs should strive to make object + // ownership clear, so that refcounting is not necessary. All that said, reference counting can + // sometimes simplify code that would otherwise become convoluted with explicit ownership, even + // when ownership relationships are clear at an abstract level. + // + // NOT THREADSAFE: This refcounting implementation assumes that an object's references are + // manipulated only in one thread, because atomic (thread-safe) refcounting is surprisingly slow. + // + // In general, abstract classes should _not_ subclass this. The concrete class at the bottom + // of the hierarchy should be the one to decide how it implements refcounting. Interfaces should + // expose only an `addRef()` method that returns `Own`. There are two reasons for + // this rule: + // 1. Interfaces would need to virtually inherit Refcounted, otherwise two refcounted interfaces + // could not be inherited by the same subclass. Virtual inheritance is awkward and + // inefficient. + // 2. An implementation may decide that it would rather return a copy than a refcount, or use + // some other strategy. + // + // TODO(cleanup): Rethink above. Virtual inheritance is not necessarily that bad. OTOH, a + // virtual function call for every refcount is sad in its own way. A Ref type to replace + // Own could also be nice. + +public: + virtual ~Refcounted() noexcept(false); + + inline bool isShared() const { return refcount > 1; } + // Check if there are multiple references to this object. This is sometimes useful for deciding + // whether it's safe to modify the object vs. make a copy. + +private: + mutable uint refcount = 0; + // "mutable" because disposeImpl() is const. Bleh. + + void disposeImpl(void* pointer) const override; + template + static Own addRefInternal(T* object); + + template + friend Own addRef(T& object); + template + friend Own refcounted(Params&&... params); +}; + +template +inline Own refcounted(Params&&... params) { + // Allocate a new refcounted instance of T, passing `params` to its constructor. Returns an + // initial reference to the object. More references can be created with `kj::addRef()`. + + return Refcounted::addRefInternal(new T(kj::fwd(params)...)); +} + +template +Own addRef(T& object) { + // Return a new reference to `object`, which must subclass Refcounted and have been allocated + // using `kj::refcounted<>()`. It is suggested that subclasses implement a non-static addRef() + // method which wraps this and returns the appropriate type. + + KJ_IREQUIRE(object.Refcounted::refcount > 0, "Object not allocated with kj::refcounted()."); + return Refcounted::addRefInternal(&object); +} + +template +Own Refcounted::addRefInternal(T* object) { + Refcounted* refcounted = object; + ++refcounted->refcount; + return Own(object, *refcounted); +} + +} // namespace kj + +#endif // KJ_REFCOUNT_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/string-tree.h --- a/win32-mingw/include/kj/string-tree.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/string-tree.h Tue May 23 09:16:54 2017 +0100 @@ -1,212 +1,212 @@ -// 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. - -#ifndef KJ_STRING_TREE_H_ -#define KJ_STRING_TREE_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "string.h" - -namespace kj { - -class StringTree { - // A long string, represented internally as a tree of strings. This data structure is like a - // String, but optimized for concatenation and iteration at the expense of seek time. The - // structure is intended to be used for building large text blobs from many small pieces, where - // repeatedly concatenating smaller strings into larger ones would waste copies. This structure - // is NOT intended for use cases requiring random access or computing substrings. For those, - // you should use a Rope, which is a much more complicated data structure. - // - // The proper way to construct a StringTree is via kj::strTree(...), which works just like - // kj::str(...) but returns a StringTree rather than a String. - // - // KJ_STRINGIFY() functions that construct large strings from many smaller strings are encouraged - // to return StringTree rather than a flat char container. - -public: - inline StringTree(): size_(0) {} - inline StringTree(String&& text): size_(text.size()), text(kj::mv(text)) {} - - StringTree(Array&& pieces, StringPtr delim); - // Build a StringTree by concatenating the given pieces, delimited by the given delimiter - // (e.g. ", "). - - inline size_t size() const { return size_; } - - template - void visit(Func&& func) const; - - String flatten() const; - // Return the contents as a string. - - // TODO(someday): flatten() when *this is an rvalue and when branches.size() == 0 could simply - // return `kj::mv(text)`. Requires reference qualifiers (Clang 3.3 / GCC 4.8). - - void flattenTo(char* __restrict__ target) const; - // Copy the contents to the given character array. Does not add a NUL terminator. - -private: - size_t size_; - String text; - - struct Branch; - Array branches; // In order. - - inline void fill(char* pos, size_t branchIndex); - template - void fill(char* pos, size_t branchIndex, First&& first, Rest&&... rest); - template - void fill(char* pos, size_t branchIndex, StringTree&& first, Rest&&... rest); - template - void fill(char* pos, size_t branchIndex, Array&& first, Rest&&... rest); - template - void fill(char* pos, size_t branchIndex, String&& first, Rest&&... rest); - - template - static StringTree concat(Params&&... params); - static StringTree&& concat(StringTree&& param) { return kj::mv(param); } - - template - static inline size_t flatSize(const T& t) { return t.size(); } - static inline size_t flatSize(String&& s) { return 0; } - static inline size_t flatSize(StringTree&& s) { return 0; } - - template - static inline size_t branchCount(const T& t) { return 0; } - static inline size_t branchCount(String&& s) { return 1; } - static inline size_t branchCount(StringTree&& s) { return 1; } - - template - friend StringTree strTree(Params&&... params); -}; - -inline StringTree&& KJ_STRINGIFY(StringTree&& tree) { return kj::mv(tree); } -inline const StringTree& KJ_STRINGIFY(const StringTree& tree) { return tree; } - -inline StringTree KJ_STRINGIFY(Array&& trees) { return StringTree(kj::mv(trees), ""); } - -template -StringTree strTree(Params&&... params); -// Build a StringTree by stringifying the given parameters and concatenating the results. -// If any of the parameters stringify to StringTree rvalues, they will be incorporated as -// branches to avoid a copy. - -// ======================================================================================= -// Inline implementation details - -namespace _ { // private - -template -char* fill(char* __restrict__ target, const StringTree& first, Rest&&... rest) { - // Make str() work with stringifiers that return StringTree by patching fill(). - - first.flattenTo(target); - return fill(target + first.size(), kj::fwd(rest)...); -} - -template constexpr bool isStringTree() { return false; } -template <> constexpr bool isStringTree() { return true; } - -inline StringTree&& toStringTreeOrCharSequence(StringTree&& tree) { return kj::mv(tree); } -inline StringTree toStringTreeOrCharSequence(String&& str) { return StringTree(kj::mv(str)); } - -template -inline auto toStringTreeOrCharSequence(T&& value) - -> decltype(toCharSequence(kj::fwd(value))) { - static_assert(!isStringTree>(), - "When passing a StringTree into kj::strTree(), either pass it by rvalue " - "(use kj::mv(value)) or explicitly call value.flatten() to make a copy."); - - return toCharSequence(kj::fwd(value)); -} - -} // namespace _ (private) - -struct StringTree::Branch { - size_t index; - // Index in `text` where this branch should be inserted. - - StringTree content; -}; - -template -void StringTree::visit(Func&& func) const { - size_t pos = 0; - for (auto& branch: branches) { - if (branch.index > pos) { - func(text.slice(pos, branch.index)); - pos = branch.index; - } - branch.content.visit(func); - } - if (text.size() > pos) { - func(text.slice(pos, text.size())); - } -} - -inline void StringTree::fill(char* pos, size_t branchIndex) { - KJ_IREQUIRE(pos == text.end() && branchIndex == branches.size(), - kj::str(text.end() - pos, ' ', branches.size() - branchIndex).cStr()); -} - -template -void StringTree::fill(char* pos, size_t branchIndex, First&& first, Rest&&... rest) { - pos = _::fill(pos, kj::fwd(first)); - fill(pos, branchIndex, kj::fwd(rest)...); -} - -template -void StringTree::fill(char* pos, size_t branchIndex, StringTree&& first, Rest&&... rest) { - branches[branchIndex].index = pos - text.begin(); - branches[branchIndex].content = kj::mv(first); - fill(pos, branchIndex + 1, kj::fwd(rest)...); -} - -template -void StringTree::fill(char* pos, size_t branchIndex, String&& first, Rest&&... rest) { - branches[branchIndex].index = pos - text.begin(); - branches[branchIndex].content = StringTree(kj::mv(first)); - fill(pos, branchIndex + 1, kj::fwd(rest)...); -} - -template -StringTree StringTree::concat(Params&&... params) { - StringTree result; - result.size_ = _::sum({params.size()...}); - result.text = heapString( - _::sum({StringTree::flatSize(kj::fwd(params))...})); - result.branches = heapArray( - _::sum({StringTree::branchCount(kj::fwd(params))...})); - result.fill(result.text.begin(), 0, kj::fwd(params)...); - return result; -} - -template -StringTree strTree(Params&&... params) { - return StringTree::concat(_::toStringTreeOrCharSequence(kj::fwd(params))...); -} - -} // namespace kj - -#endif // KJ_STRING_TREE_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. + +#ifndef KJ_STRING_TREE_H_ +#define KJ_STRING_TREE_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "string.h" + +namespace kj { + +class StringTree { + // A long string, represented internally as a tree of strings. This data structure is like a + // String, but optimized for concatenation and iteration at the expense of seek time. The + // structure is intended to be used for building large text blobs from many small pieces, where + // repeatedly concatenating smaller strings into larger ones would waste copies. This structure + // is NOT intended for use cases requiring random access or computing substrings. For those, + // you should use a Rope, which is a much more complicated data structure. + // + // The proper way to construct a StringTree is via kj::strTree(...), which works just like + // kj::str(...) but returns a StringTree rather than a String. + // + // KJ_STRINGIFY() functions that construct large strings from many smaller strings are encouraged + // to return StringTree rather than a flat char container. + +public: + inline StringTree(): size_(0) {} + inline StringTree(String&& text): size_(text.size()), text(kj::mv(text)) {} + + StringTree(Array&& pieces, StringPtr delim); + // Build a StringTree by concatenating the given pieces, delimited by the given delimiter + // (e.g. ", "). + + inline size_t size() const { return size_; } + + template + void visit(Func&& func) const; + + String flatten() const; + // Return the contents as a string. + + // TODO(someday): flatten() when *this is an rvalue and when branches.size() == 0 could simply + // return `kj::mv(text)`. Requires reference qualifiers (Clang 3.3 / GCC 4.8). + + void flattenTo(char* __restrict__ target) const; + // Copy the contents to the given character array. Does not add a NUL terminator. + +private: + size_t size_; + String text; + + struct Branch; + Array branches; // In order. + + inline void fill(char* pos, size_t branchIndex); + template + void fill(char* pos, size_t branchIndex, First&& first, Rest&&... rest); + template + void fill(char* pos, size_t branchIndex, StringTree&& first, Rest&&... rest); + template + void fill(char* pos, size_t branchIndex, Array&& first, Rest&&... rest); + template + void fill(char* pos, size_t branchIndex, String&& first, Rest&&... rest); + + template + static StringTree concat(Params&&... params); + static StringTree&& concat(StringTree&& param) { return kj::mv(param); } + + template + static inline size_t flatSize(const T& t) { return t.size(); } + static inline size_t flatSize(String&& s) { return 0; } + static inline size_t flatSize(StringTree&& s) { return 0; } + + template + static inline size_t branchCount(const T& t) { return 0; } + static inline size_t branchCount(String&& s) { return 1; } + static inline size_t branchCount(StringTree&& s) { return 1; } + + template + friend StringTree strTree(Params&&... params); +}; + +inline StringTree&& KJ_STRINGIFY(StringTree&& tree) { return kj::mv(tree); } +inline const StringTree& KJ_STRINGIFY(const StringTree& tree) { return tree; } + +inline StringTree KJ_STRINGIFY(Array&& trees) { return StringTree(kj::mv(trees), ""); } + +template +StringTree strTree(Params&&... params); +// Build a StringTree by stringifying the given parameters and concatenating the results. +// If any of the parameters stringify to StringTree rvalues, they will be incorporated as +// branches to avoid a copy. + +// ======================================================================================= +// Inline implementation details + +namespace _ { // private + +template +char* fill(char* __restrict__ target, const StringTree& first, Rest&&... rest) { + // Make str() work with stringifiers that return StringTree by patching fill(). + + first.flattenTo(target); + return fill(target + first.size(), kj::fwd(rest)...); +} + +template constexpr bool isStringTree() { return false; } +template <> constexpr bool isStringTree() { return true; } + +inline StringTree&& toStringTreeOrCharSequence(StringTree&& tree) { return kj::mv(tree); } +inline StringTree toStringTreeOrCharSequence(String&& str) { return StringTree(kj::mv(str)); } + +template +inline auto toStringTreeOrCharSequence(T&& value) + -> decltype(toCharSequence(kj::fwd(value))) { + static_assert(!isStringTree>(), + "When passing a StringTree into kj::strTree(), either pass it by rvalue " + "(use kj::mv(value)) or explicitly call value.flatten() to make a copy."); + + return toCharSequence(kj::fwd(value)); +} + +} // namespace _ (private) + +struct StringTree::Branch { + size_t index; + // Index in `text` where this branch should be inserted. + + StringTree content; +}; + +template +void StringTree::visit(Func&& func) const { + size_t pos = 0; + for (auto& branch: branches) { + if (branch.index > pos) { + func(text.slice(pos, branch.index)); + pos = branch.index; + } + branch.content.visit(func); + } + if (text.size() > pos) { + func(text.slice(pos, text.size())); + } +} + +inline void StringTree::fill(char* pos, size_t branchIndex) { + KJ_IREQUIRE(pos == text.end() && branchIndex == branches.size(), + kj::str(text.end() - pos, ' ', branches.size() - branchIndex).cStr()); +} + +template +void StringTree::fill(char* pos, size_t branchIndex, First&& first, Rest&&... rest) { + pos = _::fill(pos, kj::fwd(first)); + fill(pos, branchIndex, kj::fwd(rest)...); +} + +template +void StringTree::fill(char* pos, size_t branchIndex, StringTree&& first, Rest&&... rest) { + branches[branchIndex].index = pos - text.begin(); + branches[branchIndex].content = kj::mv(first); + fill(pos, branchIndex + 1, kj::fwd(rest)...); +} + +template +void StringTree::fill(char* pos, size_t branchIndex, String&& first, Rest&&... rest) { + branches[branchIndex].index = pos - text.begin(); + branches[branchIndex].content = StringTree(kj::mv(first)); + fill(pos, branchIndex + 1, kj::fwd(rest)...); +} + +template +StringTree StringTree::concat(Params&&... params) { + StringTree result; + result.size_ = _::sum({params.size()...}); + result.text = heapString( + _::sum({StringTree::flatSize(kj::fwd(params))...})); + result.branches = heapArray( + _::sum({StringTree::branchCount(kj::fwd(params))...})); + result.fill(result.text.begin(), 0, kj::fwd(params)...); + return result; +} + +template +StringTree strTree(Params&&... params) { + return StringTree::concat(_::toStringTreeOrCharSequence(kj::fwd(params))...); +} + +} // namespace kj + +#endif // KJ_STRING_TREE_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/string.h --- a/win32-mingw/include/kj/string.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/string.h Tue May 23 09:16:54 2017 +0100 @@ -1,530 +1,534 @@ -// 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. - -#ifndef KJ_STRING_H_ -#define KJ_STRING_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include -#include "array.h" -#include - -namespace kj { - -class StringPtr; -class String; - -class StringTree; // string-tree.h - -// Our STL string SFINAE trick does not work with GCC 4.7, but it works with Clang and GCC 4.8, so -// we'll just preprocess it out if not supported. -#if __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || _MSC_VER -#define KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP 1 -#endif - -// ======================================================================================= -// StringPtr -- A NUL-terminated ArrayPtr containing UTF-8 text. -// -// NUL bytes are allowed to appear before the end of the string. The only requirement is that -// a NUL byte appear immediately after the last byte of the content. This terminator byte is not -// counted in the string's size. - -class StringPtr { -public: - inline StringPtr(): content("", 1) {} - inline StringPtr(decltype(nullptr)): content("", 1) {} - inline StringPtr(const char* value): content(value, strlen(value) + 1) {} - inline StringPtr(const char* value, size_t size): content(value, size + 1) { - KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); - } - inline StringPtr(const char* begin, const char* end): StringPtr(begin, end - begin) {} - inline StringPtr(const String& value); - -#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP - template ().c_str())> - inline StringPtr(const T& t): StringPtr(t.c_str()) {} - // Allow implicit conversion from any class that has a c_str() method (namely, std::string). - // We use a template trick to detect std::string in order to avoid including the header for - // those who don't want it. - - template ().c_str())> - inline operator T() const { return cStr(); } - // Allow implicit conversion to any class that has a c_str() method (namely, std::string). - // We use a template trick to detect std::string in order to avoid including the header for - // those who don't want it. -#endif - - inline operator ArrayPtr() const; - inline ArrayPtr asArray() const; - inline ArrayPtr asBytes() const { return asArray().asBytes(); } - // Result does not include NUL terminator. - - inline const char* cStr() const { return content.begin(); } - // Returns NUL-terminated string. - - inline size_t size() const { return content.size() - 1; } - // Result does not include NUL terminator. - - inline char operator[](size_t index) const { return content[index]; } - - inline const char* begin() const { return content.begin(); } - inline const char* end() const { return content.end() - 1; } - - inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } - inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } - - inline bool operator==(const StringPtr& other) const; - inline bool operator!=(const StringPtr& other) const { return !(*this == other); } - inline bool operator< (const StringPtr& other) const; - inline bool operator> (const StringPtr& other) const { return other < *this; } - inline bool operator<=(const StringPtr& other) const { return !(other < *this); } - inline bool operator>=(const StringPtr& other) const { return !(*this < other); } - - inline StringPtr slice(size_t start) const; - inline ArrayPtr slice(size_t start, size_t end) const; - // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter - // version that assumes end = size(). - - inline bool startsWith(const StringPtr& other) const; - inline bool endsWith(const StringPtr& other) const; - - inline Maybe findFirst(char c) const; - inline Maybe findLast(char c) const; - - template - T parseAs() const; - // Parse string as template number type. - // Integer numbers prefixed by "0x" and "0X" are parsed in base 16 (like strtoi with base 0). - // Integer numbers prefixed by "0" are parsed in base 10 (unlike strtoi with base 0). - // Overflowed integer numbers throw exception. - // Overflowed floating numbers return inf. - -private: - inline StringPtr(ArrayPtr content): content(content) {} - - ArrayPtr content; -}; - -inline bool operator==(const char* a, const StringPtr& b) { return b == a; } -inline bool operator!=(const char* a, const StringPtr& b) { return b != a; } - -template <> char StringPtr::parseAs() const; -template <> signed char StringPtr::parseAs() const; -template <> unsigned char StringPtr::parseAs() const; -template <> short StringPtr::parseAs() const; -template <> unsigned short StringPtr::parseAs() const; -template <> int StringPtr::parseAs() const; -template <> unsigned StringPtr::parseAs() const; -template <> long StringPtr::parseAs() const; -template <> unsigned long StringPtr::parseAs() const; -template <> long long StringPtr::parseAs() const; -template <> unsigned long long StringPtr::parseAs() const; -template <> float StringPtr::parseAs() const; -template <> double StringPtr::parseAs() const; - -// ======================================================================================= -// String -- A NUL-terminated Array containing UTF-8 text. -// -// NUL bytes are allowed to appear before the end of the string. The only requirement is that -// a NUL byte appear immediately after the last byte of the content. This terminator byte is not -// counted in the string's size. -// -// To allocate a String, you must call kj::heapString(). We do not implement implicit copying to -// the heap because this hides potential inefficiency from the developer. - -class String { -public: - String() = default; - inline String(decltype(nullptr)): content(nullptr) {} - inline String(char* value, size_t size, const ArrayDisposer& disposer); - // Does not copy. `size` does not include NUL terminator, but `value` must be NUL-terminated. - inline explicit String(Array buffer); - // Does not copy. Requires `buffer` ends with `\0`. - - inline operator ArrayPtr(); - inline operator ArrayPtr() const; - inline ArrayPtr asArray(); - inline ArrayPtr asArray() const; - inline ArrayPtr asBytes() { return asArray().asBytes(); } - inline ArrayPtr asBytes() const { return asArray().asBytes(); } - // Result does not include NUL terminator. - - inline const char* cStr() const; - - inline size_t size() const; - // Result does not include NUL terminator. - - inline char operator[](size_t index) const; - inline char& operator[](size_t index); - - inline char* begin(); - inline char* end(); - inline const char* begin() const; - inline const char* end() const; - - inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } - inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } - - inline bool operator==(const StringPtr& other) const { return StringPtr(*this) == other; } - inline bool operator!=(const StringPtr& other) const { return StringPtr(*this) != other; } - inline bool operator< (const StringPtr& other) const { return StringPtr(*this) < other; } - inline bool operator> (const StringPtr& other) const { return StringPtr(*this) > other; } - inline bool operator<=(const StringPtr& other) const { return StringPtr(*this) <= other; } - inline bool operator>=(const StringPtr& other) const { return StringPtr(*this) >= other; } - - inline bool startsWith(const StringPtr& other) const { return StringPtr(*this).startsWith(other);} - inline bool endsWith(const StringPtr& other) const { return StringPtr(*this).endsWith(other); } - - inline StringPtr slice(size_t start) const { return StringPtr(*this).slice(start); } - inline ArrayPtr slice(size_t start, size_t end) const { - return StringPtr(*this).slice(start, end); - } - - inline Maybe findFirst(char c) const { return StringPtr(*this).findFirst(c); } - inline Maybe findLast(char c) const { return StringPtr(*this).findLast(c); } - - template - T parseAs() const { return StringPtr(*this).parseAs(); } - // Parse as number - -private: - Array content; -}; - -inline bool operator==(const char* a, const String& b) { return b == a; } -inline bool operator!=(const char* a, const String& b) { return b != a; } - -String heapString(size_t size); -// Allocate a String of the given size on the heap, not including NUL terminator. The NUL -// terminator will be initialized automatically but the rest of the content is not initialized. - -String heapString(const char* value); -String heapString(const char* value, size_t size); -String heapString(StringPtr value); -String heapString(const String& value); -String heapString(ArrayPtr value); -// Allocates a copy of the given value on the heap. - -// ======================================================================================= -// Magic str() function which transforms parameters to text and concatenates them into one big -// String. - -namespace _ { // private - -inline size_t sum(std::initializer_list nums) { - size_t result = 0; - for (auto num: nums) { - result += num; - } - return result; -} - -inline char* fill(char* ptr) { return ptr; } - -template -char* fill(char* __restrict__ target, const StringTree& first, Rest&&... rest); -// Make str() work with stringifiers that return StringTree by patching fill(). -// -// Defined in string-tree.h. - -template -char* fill(char* __restrict__ target, const First& first, Rest&&... rest) { - auto i = first.begin(); - auto end = first.end(); - while (i != end) { - *target++ = *i++; - } - return fill(target, kj::fwd(rest)...); -} - -template -String concat(Params&&... params) { - // Concatenate a bunch of containers into a single Array. The containers can be anything that - // is iterable and whose elements can be converted to `char`. - - String result = heapString(sum({params.size()...})); - fill(result.begin(), kj::fwd(params)...); - return result; -} - -inline String concat(String&& arr) { - return kj::mv(arr); -} - -struct Stringifier { - // This is a dummy type with only one instance: STR (below). To make an arbitrary type - // stringifiable, define `operator*(Stringifier, T)` to return an iterable container of `char`. - // The container type must have a `size()` method. Be sure to declare the operator in the same - // namespace as `T` **or** in the global scope. - // - // A more usual way to accomplish what we're doing here would be to require that you define - // a function like `toString(T)` and then rely on argument-dependent lookup. However, this has - // the problem that it pollutes other people's namespaces and even the global namespace. For - // example, some other project may already have functions called `toString` which do something - // different. Declaring `operator*` with `Stringifier` as the left operand cannot conflict with - // anything. - - inline ArrayPtr operator*(ArrayPtr s) const { return s; } - inline ArrayPtr operator*(ArrayPtr s) const { return s; } - inline ArrayPtr operator*(const Array& s) const { return s; } - inline ArrayPtr operator*(const Array& s) const { return s; } - template - inline ArrayPtr operator*(const CappedArray& s) const { return s; } - template - inline ArrayPtr operator*(const FixedArray& s) const { return s; } - inline ArrayPtr operator*(const char* s) const { return arrayPtr(s, strlen(s)); } - inline ArrayPtr operator*(const String& s) const { return s.asArray(); } - inline ArrayPtr operator*(const StringPtr& s) const { return s.asArray(); } - - inline Range operator*(const Range& r) const { return r; } - inline Repeat operator*(const Repeat& r) const { return r; } - - inline FixedArray operator*(char c) const { - FixedArray result; - result[0] = c; - return result; - } - - StringPtr operator*(decltype(nullptr)) const; - StringPtr operator*(bool b) const; - - CappedArray operator*(signed char i) const; - CappedArray operator*(unsigned char i) const; - CappedArray operator*(short i) const; - CappedArray operator*(unsigned short i) const; - CappedArray operator*(int i) const; - CappedArray operator*(unsigned int i) const; - CappedArray operator*(long i) const; - CappedArray operator*(unsigned long i) const; - CappedArray operator*(long long i) const; - CappedArray operator*(unsigned long long i) const; - CappedArray operator*(float f) const; - CappedArray operator*(double f) const; - CappedArray operator*(const void* s) const; - - template - String operator*(ArrayPtr arr) const; - template - String operator*(const Array& arr) const; - -#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP // supports expression SFINAE? - template ().toString())> - inline Result operator*(T&& value) const { return kj::fwd(value).toString(); } -#endif -}; -static KJ_CONSTEXPR(const) Stringifier STR = Stringifier(); - -} // namespace _ (private) - -template -auto toCharSequence(T&& value) -> decltype(_::STR * kj::fwd(value)) { - // Returns an iterable of chars that represent a textual representation of the value, suitable - // for debugging. - // - // Most users should use str() instead, but toCharSequence() may occasionally be useful to avoid - // heap allocation overhead that str() implies. - // - // To specialize this function for your type, see KJ_STRINGIFY. - - return _::STR * kj::fwd(value); -} - -CappedArray hex(unsigned char i); -CappedArray hex(unsigned short i); -CappedArray hex(unsigned int i); -CappedArray hex(unsigned long i); -CappedArray hex(unsigned long long i); - -template -String str(Params&&... params) { - // Magic function which builds a string from a bunch of arbitrary values. Example: - // str(1, " / ", 2, " = ", 0.5) - // returns: - // "1 / 2 = 0.5" - // To teach `str` how to stringify a type, see `Stringifier`. - - return _::concat(toCharSequence(kj::fwd(params))...); -} - -inline String str(String&& s) { return mv(s); } -// Overload to prevent redundant allocation. - -template -String strArray(T&& arr, const char* delim) { - size_t delimLen = strlen(delim); - KJ_STACK_ARRAY(decltype(_::STR * arr[0]), pieces, kj::size(arr), 8, 32); - size_t size = 0; - for (size_t i = 0; i < kj::size(arr); i++) { - if (i > 0) size += delimLen; - pieces[i] = _::STR * arr[i]; - size += pieces[i].size(); - } - - String result = heapString(size); - char* pos = result.begin(); - for (size_t i = 0; i < kj::size(arr); i++) { - if (i > 0) { - memcpy(pos, delim, delimLen); - pos += delimLen; - } - pos = _::fill(pos, pieces[i]); - } - return result; -} - -namespace _ { // private - -template -inline String Stringifier::operator*(ArrayPtr arr) const { - return strArray(arr, ", "); -} - -template -inline String Stringifier::operator*(const Array& arr) const { - return strArray(arr, ", "); -} - -} // namespace _ (private) - -#define KJ_STRINGIFY(...) operator*(::kj::_::Stringifier, __VA_ARGS__) -// Defines a stringifier for a custom type. Example: -// -// class Foo {...}; -// inline StringPtr KJ_STRINGIFY(const Foo& foo) { return foo.name(); } -// -// This allows Foo to be passed to str(). -// -// The function should be declared either in the same namespace as the target type or in the global -// namespace. It can return any type which is an iterable container of chars. - -// ======================================================================================= -// Inline implementation details. - -inline StringPtr::StringPtr(const String& value): content(value.begin(), value.size() + 1) {} - -inline StringPtr::operator ArrayPtr() const { - return content.slice(0, content.size() - 1); -} - -inline ArrayPtr StringPtr::asArray() const { - return content.slice(0, content.size() - 1); -} - -inline bool StringPtr::operator==(const StringPtr& other) const { - return content.size() == other.content.size() && - memcmp(content.begin(), other.content.begin(), content.size() - 1) == 0; -} - -inline bool StringPtr::operator<(const StringPtr& other) const { - bool shorter = content.size() < other.content.size(); - int cmp = memcmp(content.begin(), other.content.begin(), - shorter ? content.size() : other.content.size()); - return cmp < 0 || (cmp == 0 && shorter); -} - -inline StringPtr StringPtr::slice(size_t start) const { - return StringPtr(content.slice(start, content.size())); -} -inline ArrayPtr StringPtr::slice(size_t start, size_t end) const { - return content.slice(start, end); -} - -inline bool StringPtr::startsWith(const StringPtr& other) const { - return other.content.size() <= content.size() && - memcmp(content.begin(), other.content.begin(), other.size()) == 0; -} -inline bool StringPtr::endsWith(const StringPtr& other) const { - return other.content.size() <= content.size() && - memcmp(end() - other.size(), other.content.begin(), other.size()) == 0; -} - -inline Maybe StringPtr::findFirst(char c) const { - const char* pos = reinterpret_cast(memchr(content.begin(), c, size())); - if (pos == nullptr) { - return nullptr; - } else { - return pos - content.begin(); - } -} - -inline Maybe StringPtr::findLast(char c) const { - for (size_t i = size(); i > 0; --i) { - if (content[i-1] == c) { - return i-1; - } - } - return nullptr; -} - -inline String::operator ArrayPtr() { - return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); -} -inline String::operator ArrayPtr() const { - return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); -} - -inline ArrayPtr String::asArray() { - return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); -} -inline ArrayPtr String::asArray() const { - return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); -} - -inline const char* String::cStr() const { return content == nullptr ? "" : content.begin(); } - -inline size_t String::size() const { return content == nullptr ? 0 : content.size() - 1; } - -inline char String::operator[](size_t index) const { return content[index]; } -inline char& String::operator[](size_t index) { return content[index]; } - -inline char* String::begin() { return content == nullptr ? nullptr : content.begin(); } -inline char* String::end() { return content == nullptr ? nullptr : content.end() - 1; } -inline const char* String::begin() const { return content == nullptr ? nullptr : content.begin(); } -inline const char* String::end() const { return content == nullptr ? nullptr : content.end() - 1; } - -inline String::String(char* value, size_t size, const ArrayDisposer& disposer) - : content(value, size + 1, disposer) { - KJ_IREQUIRE(value[size] == '\0', "String must be NUL-terminated."); -} - -inline String::String(Array buffer): content(kj::mv(buffer)) { - KJ_IREQUIRE(content.size() > 0 && content.back() == '\0', "String must be NUL-terminated."); -} - -inline String heapString(const char* value) { - return heapString(value, strlen(value)); -} -inline String heapString(StringPtr value) { - return heapString(value.begin(), value.size()); -} -inline String heapString(const String& value) { - return heapString(value.begin(), value.size()); -} -inline String heapString(ArrayPtr value) { - return heapString(value.begin(), value.size()); -} - -} // namespace kj - -#endif // KJ_STRING_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. + +#ifndef KJ_STRING_H_ +#define KJ_STRING_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include +#include "array.h" +#include + +namespace kj { + +class StringPtr; +class String; + +class StringTree; // string-tree.h + +// Our STL string SFINAE trick does not work with GCC 4.7, but it works with Clang and GCC 4.8, so +// we'll just preprocess it out if not supported. +#if __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || _MSC_VER +#define KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP 1 +#endif + +// ======================================================================================= +// StringPtr -- A NUL-terminated ArrayPtr containing UTF-8 text. +// +// NUL bytes are allowed to appear before the end of the string. The only requirement is that +// a NUL byte appear immediately after the last byte of the content. This terminator byte is not +// counted in the string's size. + +class StringPtr { +public: + inline StringPtr(): content("", 1) {} + inline StringPtr(decltype(nullptr)): content("", 1) {} + inline StringPtr(const char* value): content(value, strlen(value) + 1) {} + inline StringPtr(const char* value, size_t size): content(value, size + 1) { + KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); + } + inline StringPtr(const char* begin, const char* end): StringPtr(begin, end - begin) {} + inline StringPtr(const String& value); + +#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP + template ().c_str())> + inline StringPtr(const T& t): StringPtr(t.c_str()) {} + // Allow implicit conversion from any class that has a c_str() method (namely, std::string). + // We use a template trick to detect std::string in order to avoid including the header for + // those who don't want it. + + template ().c_str())> + inline operator T() const { return cStr(); } + // Allow implicit conversion to any class that has a c_str() method (namely, std::string). + // We use a template trick to detect std::string in order to avoid including the header for + // those who don't want it. +#endif + + inline operator ArrayPtr() const; + inline ArrayPtr asArray() const; + inline ArrayPtr asBytes() const { return asArray().asBytes(); } + // Result does not include NUL terminator. + + inline const char* cStr() const { return content.begin(); } + // Returns NUL-terminated string. + + inline size_t size() const { return content.size() - 1; } + // Result does not include NUL terminator. + + inline char operator[](size_t index) const { return content[index]; } + + inline const char* begin() const { return content.begin(); } + inline const char* end() const { return content.end() - 1; } + + inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } + inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } + + inline bool operator==(const StringPtr& other) const; + inline bool operator!=(const StringPtr& other) const { return !(*this == other); } + inline bool operator< (const StringPtr& other) const; + inline bool operator> (const StringPtr& other) const { return other < *this; } + inline bool operator<=(const StringPtr& other) const { return !(other < *this); } + inline bool operator>=(const StringPtr& other) const { return !(*this < other); } + + inline StringPtr slice(size_t start) const; + inline ArrayPtr slice(size_t start, size_t end) const; + // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter + // version that assumes end = size(). + + inline bool startsWith(const StringPtr& other) const; + inline bool endsWith(const StringPtr& other) const; + + inline Maybe findFirst(char c) const; + inline Maybe findLast(char c) const; + + template + T parseAs() const; + // Parse string as template number type. + // Integer numbers prefixed by "0x" and "0X" are parsed in base 16 (like strtoi with base 0). + // Integer numbers prefixed by "0" are parsed in base 10 (unlike strtoi with base 0). + // Overflowed integer numbers throw exception. + // Overflowed floating numbers return inf. + +private: + inline StringPtr(ArrayPtr content): content(content) {} + + ArrayPtr content; +}; + +inline bool operator==(const char* a, const StringPtr& b) { return b == a; } +inline bool operator!=(const char* a, const StringPtr& b) { return b != a; } + +template <> char StringPtr::parseAs() const; +template <> signed char StringPtr::parseAs() const; +template <> unsigned char StringPtr::parseAs() const; +template <> short StringPtr::parseAs() const; +template <> unsigned short StringPtr::parseAs() const; +template <> int StringPtr::parseAs() const; +template <> unsigned StringPtr::parseAs() const; +template <> long StringPtr::parseAs() const; +template <> unsigned long StringPtr::parseAs() const; +template <> long long StringPtr::parseAs() const; +template <> unsigned long long StringPtr::parseAs() const; +template <> float StringPtr::parseAs() const; +template <> double StringPtr::parseAs() const; + +// ======================================================================================= +// String -- A NUL-terminated Array containing UTF-8 text. +// +// NUL bytes are allowed to appear before the end of the string. The only requirement is that +// a NUL byte appear immediately after the last byte of the content. This terminator byte is not +// counted in the string's size. +// +// To allocate a String, you must call kj::heapString(). We do not implement implicit copying to +// the heap because this hides potential inefficiency from the developer. + +class String { +public: + String() = default; + inline String(decltype(nullptr)): content(nullptr) {} + inline String(char* value, size_t size, const ArrayDisposer& disposer); + // Does not copy. `size` does not include NUL terminator, but `value` must be NUL-terminated. + inline explicit String(Array buffer); + // Does not copy. Requires `buffer` ends with `\0`. + + inline operator ArrayPtr(); + inline operator ArrayPtr() const; + inline ArrayPtr asArray(); + inline ArrayPtr asArray() const; + inline ArrayPtr asBytes() { return asArray().asBytes(); } + inline ArrayPtr asBytes() const { return asArray().asBytes(); } + // Result does not include NUL terminator. + + inline Array releaseArray() { return kj::mv(content); } + // Disowns the backing array (which includes the NUL terminator) and returns it. The String value + // is clobbered (as if moved away). + + inline const char* cStr() const; + + inline size_t size() const; + // Result does not include NUL terminator. + + inline char operator[](size_t index) const; + inline char& operator[](size_t index); + + inline char* begin(); + inline char* end(); + inline const char* begin() const; + inline const char* end() const; + + inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } + inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } + + inline bool operator==(const StringPtr& other) const { return StringPtr(*this) == other; } + inline bool operator!=(const StringPtr& other) const { return StringPtr(*this) != other; } + inline bool operator< (const StringPtr& other) const { return StringPtr(*this) < other; } + inline bool operator> (const StringPtr& other) const { return StringPtr(*this) > other; } + inline bool operator<=(const StringPtr& other) const { return StringPtr(*this) <= other; } + inline bool operator>=(const StringPtr& other) const { return StringPtr(*this) >= other; } + + inline bool startsWith(const StringPtr& other) const { return StringPtr(*this).startsWith(other);} + inline bool endsWith(const StringPtr& other) const { return StringPtr(*this).endsWith(other); } + + inline StringPtr slice(size_t start) const { return StringPtr(*this).slice(start); } + inline ArrayPtr slice(size_t start, size_t end) const { + return StringPtr(*this).slice(start, end); + } + + inline Maybe findFirst(char c) const { return StringPtr(*this).findFirst(c); } + inline Maybe findLast(char c) const { return StringPtr(*this).findLast(c); } + + template + T parseAs() const { return StringPtr(*this).parseAs(); } + // Parse as number + +private: + Array content; +}; + +inline bool operator==(const char* a, const String& b) { return b == a; } +inline bool operator!=(const char* a, const String& b) { return b != a; } + +String heapString(size_t size); +// Allocate a String of the given size on the heap, not including NUL terminator. The NUL +// terminator will be initialized automatically but the rest of the content is not initialized. + +String heapString(const char* value); +String heapString(const char* value, size_t size); +String heapString(StringPtr value); +String heapString(const String& value); +String heapString(ArrayPtr value); +// Allocates a copy of the given value on the heap. + +// ======================================================================================= +// Magic str() function which transforms parameters to text and concatenates them into one big +// String. + +namespace _ { // private + +inline size_t sum(std::initializer_list nums) { + size_t result = 0; + for (auto num: nums) { + result += num; + } + return result; +} + +inline char* fill(char* ptr) { return ptr; } + +template +char* fill(char* __restrict__ target, const StringTree& first, Rest&&... rest); +// Make str() work with stringifiers that return StringTree by patching fill(). +// +// Defined in string-tree.h. + +template +char* fill(char* __restrict__ target, const First& first, Rest&&... rest) { + auto i = first.begin(); + auto end = first.end(); + while (i != end) { + *target++ = *i++; + } + return fill(target, kj::fwd(rest)...); +} + +template +String concat(Params&&... params) { + // Concatenate a bunch of containers into a single Array. The containers can be anything that + // is iterable and whose elements can be converted to `char`. + + String result = heapString(sum({params.size()...})); + fill(result.begin(), kj::fwd(params)...); + return result; +} + +inline String concat(String&& arr) { + return kj::mv(arr); +} + +struct Stringifier { + // This is a dummy type with only one instance: STR (below). To make an arbitrary type + // stringifiable, define `operator*(Stringifier, T)` to return an iterable container of `char`. + // The container type must have a `size()` method. Be sure to declare the operator in the same + // namespace as `T` **or** in the global scope. + // + // A more usual way to accomplish what we're doing here would be to require that you define + // a function like `toString(T)` and then rely on argument-dependent lookup. However, this has + // the problem that it pollutes other people's namespaces and even the global namespace. For + // example, some other project may already have functions called `toString` which do something + // different. Declaring `operator*` with `Stringifier` as the left operand cannot conflict with + // anything. + + inline ArrayPtr operator*(ArrayPtr s) const { return s; } + inline ArrayPtr operator*(ArrayPtr s) const { return s; } + inline ArrayPtr operator*(const Array& s) const { return s; } + inline ArrayPtr operator*(const Array& s) const { return s; } + template + inline ArrayPtr operator*(const CappedArray& s) const { return s; } + template + inline ArrayPtr operator*(const FixedArray& s) const { return s; } + inline ArrayPtr operator*(const char* s) const { return arrayPtr(s, strlen(s)); } + inline ArrayPtr operator*(const String& s) const { return s.asArray(); } + inline ArrayPtr operator*(const StringPtr& s) const { return s.asArray(); } + + inline Range operator*(const Range& r) const { return r; } + inline Repeat operator*(const Repeat& r) const { return r; } + + inline FixedArray operator*(char c) const { + FixedArray result; + result[0] = c; + return result; + } + + StringPtr operator*(decltype(nullptr)) const; + StringPtr operator*(bool b) const; + + CappedArray operator*(signed char i) const; + CappedArray operator*(unsigned char i) const; + CappedArray operator*(short i) const; + CappedArray operator*(unsigned short i) const; + CappedArray operator*(int i) const; + CappedArray operator*(unsigned int i) const; + CappedArray operator*(long i) const; + CappedArray operator*(unsigned long i) const; + CappedArray operator*(long long i) const; + CappedArray operator*(unsigned long long i) const; + CappedArray operator*(float f) const; + CappedArray operator*(double f) const; + CappedArray operator*(const void* s) const; + + template + String operator*(ArrayPtr arr) const; + template + String operator*(const Array& arr) const; + +#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP // supports expression SFINAE? + template ().toString())> + inline Result operator*(T&& value) const { return kj::fwd(value).toString(); } +#endif +}; +static KJ_CONSTEXPR(const) Stringifier STR = Stringifier(); + +} // namespace _ (private) + +template +auto toCharSequence(T&& value) -> decltype(_::STR * kj::fwd(value)) { + // Returns an iterable of chars that represent a textual representation of the value, suitable + // for debugging. + // + // Most users should use str() instead, but toCharSequence() may occasionally be useful to avoid + // heap allocation overhead that str() implies. + // + // To specialize this function for your type, see KJ_STRINGIFY. + + return _::STR * kj::fwd(value); +} + +CappedArray hex(unsigned char i); +CappedArray hex(unsigned short i); +CappedArray hex(unsigned int i); +CappedArray hex(unsigned long i); +CappedArray hex(unsigned long long i); + +template +String str(Params&&... params) { + // Magic function which builds a string from a bunch of arbitrary values. Example: + // str(1, " / ", 2, " = ", 0.5) + // returns: + // "1 / 2 = 0.5" + // To teach `str` how to stringify a type, see `Stringifier`. + + return _::concat(toCharSequence(kj::fwd(params))...); +} + +inline String str(String&& s) { return mv(s); } +// Overload to prevent redundant allocation. + +template +String strArray(T&& arr, const char* delim) { + size_t delimLen = strlen(delim); + KJ_STACK_ARRAY(decltype(_::STR * arr[0]), pieces, kj::size(arr), 8, 32); + size_t size = 0; + for (size_t i = 0; i < kj::size(arr); i++) { + if (i > 0) size += delimLen; + pieces[i] = _::STR * arr[i]; + size += pieces[i].size(); + } + + String result = heapString(size); + char* pos = result.begin(); + for (size_t i = 0; i < kj::size(arr); i++) { + if (i > 0) { + memcpy(pos, delim, delimLen); + pos += delimLen; + } + pos = _::fill(pos, pieces[i]); + } + return result; +} + +namespace _ { // private + +template +inline String Stringifier::operator*(ArrayPtr arr) const { + return strArray(arr, ", "); +} + +template +inline String Stringifier::operator*(const Array& arr) const { + return strArray(arr, ", "); +} + +} // namespace _ (private) + +#define KJ_STRINGIFY(...) operator*(::kj::_::Stringifier, __VA_ARGS__) +// Defines a stringifier for a custom type. Example: +// +// class Foo {...}; +// inline StringPtr KJ_STRINGIFY(const Foo& foo) { return foo.name(); } +// +// This allows Foo to be passed to str(). +// +// The function should be declared either in the same namespace as the target type or in the global +// namespace. It can return any type which is an iterable container of chars. + +// ======================================================================================= +// Inline implementation details. + +inline StringPtr::StringPtr(const String& value): content(value.begin(), value.size() + 1) {} + +inline StringPtr::operator ArrayPtr() const { + return content.slice(0, content.size() - 1); +} + +inline ArrayPtr StringPtr::asArray() const { + return content.slice(0, content.size() - 1); +} + +inline bool StringPtr::operator==(const StringPtr& other) const { + return content.size() == other.content.size() && + memcmp(content.begin(), other.content.begin(), content.size() - 1) == 0; +} + +inline bool StringPtr::operator<(const StringPtr& other) const { + bool shorter = content.size() < other.content.size(); + int cmp = memcmp(content.begin(), other.content.begin(), + shorter ? content.size() : other.content.size()); + return cmp < 0 || (cmp == 0 && shorter); +} + +inline StringPtr StringPtr::slice(size_t start) const { + return StringPtr(content.slice(start, content.size())); +} +inline ArrayPtr StringPtr::slice(size_t start, size_t end) const { + return content.slice(start, end); +} + +inline bool StringPtr::startsWith(const StringPtr& other) const { + return other.content.size() <= content.size() && + memcmp(content.begin(), other.content.begin(), other.size()) == 0; +} +inline bool StringPtr::endsWith(const StringPtr& other) const { + return other.content.size() <= content.size() && + memcmp(end() - other.size(), other.content.begin(), other.size()) == 0; +} + +inline Maybe StringPtr::findFirst(char c) const { + const char* pos = reinterpret_cast(memchr(content.begin(), c, size())); + if (pos == nullptr) { + return nullptr; + } else { + return pos - content.begin(); + } +} + +inline Maybe StringPtr::findLast(char c) const { + for (size_t i = size(); i > 0; --i) { + if (content[i-1] == c) { + return i-1; + } + } + return nullptr; +} + +inline String::operator ArrayPtr() { + return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); +} +inline String::operator ArrayPtr() const { + return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); +} + +inline ArrayPtr String::asArray() { + return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); +} +inline ArrayPtr String::asArray() const { + return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); +} + +inline const char* String::cStr() const { return content == nullptr ? "" : content.begin(); } + +inline size_t String::size() const { return content == nullptr ? 0 : content.size() - 1; } + +inline char String::operator[](size_t index) const { return content[index]; } +inline char& String::operator[](size_t index) { return content[index]; } + +inline char* String::begin() { return content == nullptr ? nullptr : content.begin(); } +inline char* String::end() { return content == nullptr ? nullptr : content.end() - 1; } +inline const char* String::begin() const { return content == nullptr ? nullptr : content.begin(); } +inline const char* String::end() const { return content == nullptr ? nullptr : content.end() - 1; } + +inline String::String(char* value, size_t size, const ArrayDisposer& disposer) + : content(value, size + 1, disposer) { + KJ_IREQUIRE(value[size] == '\0', "String must be NUL-terminated."); +} + +inline String::String(Array buffer): content(kj::mv(buffer)) { + KJ_IREQUIRE(content.size() > 0 && content.back() == '\0', "String must be NUL-terminated."); +} + +inline String heapString(const char* value) { + return heapString(value, strlen(value)); +} +inline String heapString(StringPtr value) { + return heapString(value.begin(), value.size()); +} +inline String heapString(const String& value) { + return heapString(value.begin(), value.size()); +} +inline String heapString(ArrayPtr value) { + return heapString(value.begin(), value.size()); +} + +} // namespace kj + +#endif // KJ_STRING_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/test.h --- a/win32-mingw/include/kj/test.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/test.h Tue May 23 09:16:54 2017 +0100 @@ -1,144 +1,167 @@ -// 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. - -#ifndef KJ_TEST_H_ -#define KJ_TEST_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "debug.h" -#include "vector.h" - -namespace kj { - -class TestRunner; - -class TestCase { -public: - TestCase(const char* file, uint line, const char* description); - ~TestCase(); - - virtual void run() = 0; - -private: - const char* file; - uint line; - const char* description; - TestCase* next; - TestCase** prev; - bool matchedFilter; - - friend class TestRunner; -}; - -#define KJ_TEST(description) \ - /* Make sure the linker fails if tests are not in anonymous namespaces. */ \ - extern int KJ_CONCAT(YouMustWrapTestsInAnonymousNamespace, __COUNTER__) KJ_UNUSED; \ - class KJ_UNIQUE_NAME(TestCase): public ::kj::TestCase { \ - public: \ - KJ_UNIQUE_NAME(TestCase)(): ::kj::TestCase(__FILE__, __LINE__, description) {} \ - void run() override; \ - } KJ_UNIQUE_NAME(testCase); \ - void KJ_UNIQUE_NAME(TestCase)::run() - -#if _MSC_VER -#define KJ_INDIRECT_EXPAND(m, vargs) m vargs -#define KJ_FAIL_EXPECT(...) \ - KJ_INDIRECT_EXPAND(KJ_LOG, (ERROR , __VA_ARGS__)); -#define KJ_EXPECT(cond, ...) \ - if (cond); else KJ_INDIRECT_EXPAND(KJ_FAIL_EXPECT, ("failed: expected " #cond , __VA_ARGS__)) -#else -#define KJ_FAIL_EXPECT(...) \ - KJ_LOG(ERROR, ##__VA_ARGS__); -#define KJ_EXPECT(cond, ...) \ - if (cond); else KJ_FAIL_EXPECT("failed: expected " #cond, ##__VA_ARGS__) -#endif - -#define KJ_EXPECT_THROW(type, code) \ - do { \ - KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ - KJ_EXPECT(e->getType() == ::kj::Exception::Type::type, \ - "code threw wrong exception type: " #code, e->getType()); \ - } else { \ - KJ_FAIL_EXPECT("code did not throw: " #code); \ - } \ - } while (false) - -#define KJ_EXPECT_THROW_MESSAGE(message, code) \ - do { \ - KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ - KJ_EXPECT(::kj::_::hasSubstring(e->getDescription(), message), \ - "exception description didn't contain expected substring", e->getDescription()); \ - } else { \ - KJ_FAIL_EXPECT("code did not throw: " #code); \ - } \ - } while (false) - -#define KJ_EXPECT_LOG(level, substring) \ - ::kj::_::LogExpectation KJ_UNIQUE_NAME(_kjLogExpectation)(::kj::LogSeverity::level, substring) -// Expects that a log message with the given level and substring text will be printed within -// the current scope. This message will not cause the test to fail, even if it is an error. - -// ======================================================================================= - -namespace _ { // private - -bool hasSubstring(kj::StringPtr haystack, kj::StringPtr needle); - -class LogExpectation: public ExceptionCallback { -public: - LogExpectation(LogSeverity severity, StringPtr substring); - ~LogExpectation(); - - void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, - String&& text) override; - -private: - LogSeverity severity; - StringPtr substring; - bool seen; - UnwindDetector unwindDetector; -}; - -class GlobFilter { - // Implements glob filters for the --filter flag. - // - // Exposed in header only for testing. - -public: - explicit GlobFilter(const char* pattern); - explicit GlobFilter(ArrayPtr pattern); - - bool matches(StringPtr name); - -private: - String pattern; - Vector states; - - void applyState(char c, int state); -}; - -} // namespace _ (private) -} // namespace kj - -#endif // KJ_TEST_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. + +#ifndef KJ_TEST_H_ +#define KJ_TEST_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "debug.h" +#include "vector.h" +#include "function.h" + +namespace kj { + +class TestRunner; + +class TestCase { +public: + TestCase(const char* file, uint line, const char* description); + ~TestCase(); + + virtual void run() = 0; + +private: + const char* file; + uint line; + const char* description; + TestCase* next; + TestCase** prev; + bool matchedFilter; + + friend class TestRunner; +}; + +#define KJ_TEST(description) \ + /* Make sure the linker fails if tests are not in anonymous namespaces. */ \ + extern int KJ_CONCAT(YouMustWrapTestsInAnonymousNamespace, __COUNTER__) KJ_UNUSED; \ + class KJ_UNIQUE_NAME(TestCase): public ::kj::TestCase { \ + public: \ + KJ_UNIQUE_NAME(TestCase)(): ::kj::TestCase(__FILE__, __LINE__, description) {} \ + void run() override; \ + } KJ_UNIQUE_NAME(testCase); \ + void KJ_UNIQUE_NAME(TestCase)::run() + +#if _MSC_VER +#define KJ_INDIRECT_EXPAND(m, vargs) m vargs +#define KJ_FAIL_EXPECT(...) \ + KJ_INDIRECT_EXPAND(KJ_LOG, (ERROR , __VA_ARGS__)); +#define KJ_EXPECT(cond, ...) \ + if (cond); else KJ_INDIRECT_EXPAND(KJ_FAIL_EXPECT, ("failed: expected " #cond , __VA_ARGS__)) +#else +#define KJ_FAIL_EXPECT(...) \ + KJ_LOG(ERROR, ##__VA_ARGS__); +#define KJ_EXPECT(cond, ...) \ + if (cond); else KJ_FAIL_EXPECT("failed: expected " #cond, ##__VA_ARGS__) +#endif + +#define KJ_EXPECT_THROW_RECOVERABLE(type, code) \ + do { \ + KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ + KJ_EXPECT(e->getType() == ::kj::Exception::Type::type, \ + "code threw wrong exception type: " #code, e->getType()); \ + } else { \ + KJ_FAIL_EXPECT("code did not throw: " #code); \ + } \ + } while (false) + +#define KJ_EXPECT_THROW_RECOVERABLE_MESSAGE(message, code) \ + do { \ + KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ + KJ_EXPECT(::kj::_::hasSubstring(e->getDescription(), message), \ + "exception description didn't contain expected substring", e->getDescription()); \ + } else { \ + KJ_FAIL_EXPECT("code did not throw: " #code); \ + } \ + } while (false) + +#if KJ_NO_EXCEPTIONS +#define KJ_EXPECT_THROW(type, code) \ + do { \ + KJ_EXPECT(::kj::_::expectFatalThrow(type, nullptr, [&]() { code; })); \ + } while (false) +#define KJ_EXPECT_THROW_MESSAGE(message, code) \ + do { \ + KJ_EXPECT(::kj::_::expectFatalThrow(nullptr, kj::StringPtr(message), [&]() { code; })); \ + } while (false) +#else +#define KJ_EXPECT_THROW KJ_EXPECT_THROW_RECOVERABLE +#define KJ_EXPECT_THROW_MESSAGE KJ_EXPECT_THROW_RECOVERABLE_MESSAGE +#endif + +#define KJ_EXPECT_LOG(level, substring) \ + ::kj::_::LogExpectation KJ_UNIQUE_NAME(_kjLogExpectation)(::kj::LogSeverity::level, substring) +// Expects that a log message with the given level and substring text will be printed within +// the current scope. This message will not cause the test to fail, even if it is an error. + +// ======================================================================================= + +namespace _ { // private + +bool hasSubstring(kj::StringPtr haystack, kj::StringPtr needle); + +#if KJ_NO_EXCEPTIONS +bool expectFatalThrow(Maybe type, Maybe message, + Function code); +// Expects that the given code will throw a fatal exception matching the given type and/or message. +// Since exceptions are disabled, the test will fork() and run in a subprocess. On Windows, where +// fork() is not available, this always returns true. +#endif + +class LogExpectation: public ExceptionCallback { +public: + LogExpectation(LogSeverity severity, StringPtr substring); + ~LogExpectation(); + + void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text) override; + +private: + LogSeverity severity; + StringPtr substring; + bool seen; + UnwindDetector unwindDetector; +}; + +class GlobFilter { + // Implements glob filters for the --filter flag. + // + // Exposed in header only for testing. + +public: + explicit GlobFilter(const char* pattern); + explicit GlobFilter(ArrayPtr pattern); + + bool matches(StringPtr name); + +private: + String pattern; + Vector states; + + void applyState(char c, int state); +}; + +} // namespace _ (private) +} // namespace kj + +#endif // KJ_TEST_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/thread.h --- a/win32-mingw/include/kj/thread.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/thread.h Tue May 23 09:16:54 2017 +0100 @@ -1,85 +1,82 @@ -// 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. - -#ifndef KJ_THREAD_H_ -#define KJ_THREAD_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" -#include "function.h" -#include "exception.h" - -namespace kj { - -class Thread { - // A thread! Pass a lambda to the constructor, and it runs in the thread. The destructor joins - // the thread. If the function throws an exception, it is rethrown from the thread's destructor - // (if not unwinding from another exception). - -public: - explicit Thread(Function func); - KJ_DISALLOW_COPY(Thread); - - ~Thread() noexcept(false); - -#if !_WIN32 - void sendSignal(int signo); - // Send a Unix signal to the given thread, using pthread_kill or an equivalent. -#endif - - void detach(); - // Don't join the thread in ~Thread(). - // - // TODO(soon): Currently broken: the thread uses the Thread objects during its execution; instead - // the Thread object and the thread itself will need to share a refcounted object. - -private: - struct ThreadState { - Function func; - kj::Maybe exception; - - unsigned int refcount; - // Owned by the parent thread and the child thread. - - void unref(); - }; - ThreadState* state; - -#if _WIN32 - void* threadHandle; -#else - unsigned long long threadId; // actually pthread_t -#endif - bool detached = false; - -#if _WIN32 - static unsigned long __stdcall runThread(void* ptr); -#else - static void* runThread(void* ptr); -#endif -}; - -} // namespace kj - -#endif // KJ_THREAD_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. + +#ifndef KJ_THREAD_H_ +#define KJ_THREAD_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" +#include "function.h" +#include "exception.h" + +namespace kj { + +class Thread { + // A thread! Pass a lambda to the constructor, and it runs in the thread. The destructor joins + // the thread. If the function throws an exception, it is rethrown from the thread's destructor + // (if not unwinding from another exception). + +public: + explicit Thread(Function func); + KJ_DISALLOW_COPY(Thread); + + ~Thread() noexcept(false); + +#if !_WIN32 + void sendSignal(int signo); + // Send a Unix signal to the given thread, using pthread_kill or an equivalent. +#endif + + void detach(); + // Don't join the thread in ~Thread(). + +private: + struct ThreadState { + Function func; + kj::Maybe exception; + + unsigned int refcount; + // Owned by the parent thread and the child thread. + + void unref(); + }; + ThreadState* state; + +#if _WIN32 + void* threadHandle; +#else + unsigned long long threadId; // actually pthread_t +#endif + bool detached = false; + +#if _WIN32 + static unsigned long __stdcall runThread(void* ptr); +#else + static void* runThread(void* ptr); +#endif +}; + +} // namespace kj + +#endif // KJ_THREAD_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/threadlocal.h --- a/win32-mingw/include/kj/threadlocal.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/threadlocal.h Tue May 23 09:16:54 2017 +0100 @@ -1,136 +1,136 @@ -// Copyright (c) 2014, Jason Choy -// 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. - -#ifndef KJ_THREADLOCAL_H_ -#define KJ_THREADLOCAL_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif -// This file declares a macro `KJ_THREADLOCAL_PTR` for declaring thread-local pointer-typed -// variables. Use like: -// KJ_THREADLOCAL_PTR(MyType) foo = nullptr; -// This is equivalent to: -// thread_local MyType* foo = nullptr; -// This can only be used at the global scope. -// -// AVOID USING THIS. Use of thread-locals is discouraged because they often have many of the same -// properties as singletons: http://www.object-oriented-security.org/lets-argue/singletons -// -// Also, thread-locals tend to be hostile to event-driven code, which can be particularly -// surprising when using fibers (all fibers in the same thread will share the same threadlocals, -// even though they do not share a stack). -// -// That said, thread-locals are sometimes needed for runtime logistics in the KJ framework. For -// example, the current exception callback and current EventLoop are stored as thread-local -// pointers. Since KJ only ever needs to store pointers, not values, we avoid the question of -// whether these values' destructors need to be run, and we avoid the need for heap allocation. - -#include "common.h" - -#if !defined(KJ_USE_PTHREAD_THREADLOCAL) && defined(__APPLE__) -#include "TargetConditionals.h" -#if TARGET_OS_IPHONE -// iOS apparently does not support __thread (nor C++11 thread_local). -#define KJ_USE_PTHREAD_TLS 1 -#endif -#endif - -#if KJ_USE_PTHREAD_TLS -#include -#endif - -namespace kj { - -#if KJ_USE_PTHREAD_TLS -// If __thread is unavailable, we'll fall back to pthreads. - -#define KJ_THREADLOCAL_PTR(type) \ - namespace { struct KJ_UNIQUE_NAME(_kj_TlpTag); } \ - static ::kj::_::ThreadLocalPtr< type, KJ_UNIQUE_NAME(_kj_TlpTag)> -// Hack: In order to ensure each thread-local results in a unique template instance, we declare -// a one-off dummy type to use as the second type parameter. - -namespace _ { // private - -template -class ThreadLocalPtr { - // Hacky type to emulate __thread T*. We need a separate instance of the ThreadLocalPtr template - // for every thread-local variable, because we don't want to require a global constructor, and in - // order to initialize the TLS on first use we need to use a local static variable (in getKey()). - // Each template instance will get a separate such local static variable, fulfilling our need. - -public: - ThreadLocalPtr() = default; - constexpr ThreadLocalPtr(decltype(nullptr)) {} - // Allow initialization to nullptr without a global constructor. - - inline ThreadLocalPtr& operator=(T* val) { - pthread_setspecific(getKey(), val); - return *this; - } - - inline operator T*() const { - return get(); - } - - inline T& operator*() const { - return *get(); - } - - inline T* operator->() const { - return get(); - } - -private: - inline T* get() const { - return reinterpret_cast(pthread_getspecific(getKey())); - } - - inline static pthread_key_t getKey() { - static pthread_key_t key = createKey(); - return key; - } - - static pthread_key_t createKey() { - pthread_key_t key; - pthread_key_create(&key, 0); - return key; - } -}; - -} // namespace _ (private) - -#elif __GNUC__ - -#define KJ_THREADLOCAL_PTR(type) static __thread type* -// GCC's __thread is lighter-weight than thread_local and is good enough for our purposes. - -#else - -#define KJ_THREADLOCAL_PTR(type) static thread_local type* - -#endif // KJ_USE_PTHREAD_TLS - -} // namespace kj - -#endif // KJ_THREADLOCAL_H_ +// Copyright (c) 2014, Jason Choy +// 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. + +#ifndef KJ_THREADLOCAL_H_ +#define KJ_THREADLOCAL_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif +// This file declares a macro `KJ_THREADLOCAL_PTR` for declaring thread-local pointer-typed +// variables. Use like: +// KJ_THREADLOCAL_PTR(MyType) foo = nullptr; +// This is equivalent to: +// thread_local MyType* foo = nullptr; +// This can only be used at the global scope. +// +// AVOID USING THIS. Use of thread-locals is discouraged because they often have many of the same +// properties as singletons: http://www.object-oriented-security.org/lets-argue/singletons +// +// Also, thread-locals tend to be hostile to event-driven code, which can be particularly +// surprising when using fibers (all fibers in the same thread will share the same threadlocals, +// even though they do not share a stack). +// +// That said, thread-locals are sometimes needed for runtime logistics in the KJ framework. For +// example, the current exception callback and current EventLoop are stored as thread-local +// pointers. Since KJ only ever needs to store pointers, not values, we avoid the question of +// whether these values' destructors need to be run, and we avoid the need for heap allocation. + +#include "common.h" + +#if !defined(KJ_USE_PTHREAD_THREADLOCAL) && defined(__APPLE__) +#include "TargetConditionals.h" +#if TARGET_OS_IPHONE +// iOS apparently does not support __thread (nor C++11 thread_local). +#define KJ_USE_PTHREAD_TLS 1 +#endif +#endif + +#if KJ_USE_PTHREAD_TLS +#include +#endif + +namespace kj { + +#if KJ_USE_PTHREAD_TLS +// If __thread is unavailable, we'll fall back to pthreads. + +#define KJ_THREADLOCAL_PTR(type) \ + namespace { struct KJ_UNIQUE_NAME(_kj_TlpTag); } \ + static ::kj::_::ThreadLocalPtr< type, KJ_UNIQUE_NAME(_kj_TlpTag)> +// Hack: In order to ensure each thread-local results in a unique template instance, we declare +// a one-off dummy type to use as the second type parameter. + +namespace _ { // private + +template +class ThreadLocalPtr { + // Hacky type to emulate __thread T*. We need a separate instance of the ThreadLocalPtr template + // for every thread-local variable, because we don't want to require a global constructor, and in + // order to initialize the TLS on first use we need to use a local static variable (in getKey()). + // Each template instance will get a separate such local static variable, fulfilling our need. + +public: + ThreadLocalPtr() = default; + constexpr ThreadLocalPtr(decltype(nullptr)) {} + // Allow initialization to nullptr without a global constructor. + + inline ThreadLocalPtr& operator=(T* val) { + pthread_setspecific(getKey(), val); + return *this; + } + + inline operator T*() const { + return get(); + } + + inline T& operator*() const { + return *get(); + } + + inline T* operator->() const { + return get(); + } + +private: + inline T* get() const { + return reinterpret_cast(pthread_getspecific(getKey())); + } + + inline static pthread_key_t getKey() { + static pthread_key_t key = createKey(); + return key; + } + + static pthread_key_t createKey() { + pthread_key_t key; + pthread_key_create(&key, 0); + return key; + } +}; + +} // namespace _ (private) + +#elif __GNUC__ + +#define KJ_THREADLOCAL_PTR(type) static __thread type* +// GCC's __thread is lighter-weight than thread_local and is good enough for our purposes. + +#else + +#define KJ_THREADLOCAL_PTR(type) static thread_local type* + +#endif // KJ_USE_PTHREAD_TLS + +} // namespace kj + +#endif // KJ_THREADLOCAL_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/time.h --- a/win32-mingw/include/kj/time.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/time.h Tue May 23 09:16:54 2017 +0100 @@ -1,119 +1,174 @@ -// Copyright (c) 2014 Google Inc. (contributed by Remy Blank ) -// 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. - -#ifndef KJ_TIME_H_ -#define KJ_TIME_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "async.h" -#include "units.h" -#include - -namespace kj { -namespace _ { // private - -class NanosecondLabel; -class TimeLabel; -class DateLabel; - -} // namespace _ (private) - -using Duration = Quantity; -// A time value, in microseconds. - -constexpr Duration NANOSECONDS = unit(); -constexpr Duration MICROSECONDS = 1000 * NANOSECONDS; -constexpr Duration MILLISECONDS = 1000 * MICROSECONDS; -constexpr Duration SECONDS = 1000 * MILLISECONDS; -constexpr Duration MINUTES = 60 * SECONDS; -constexpr Duration HOURS = 60 * MINUTES; -constexpr Duration DAYS = 24 * HOURS; - -using TimePoint = Absolute; -// An absolute time measured by some particular instance of `Timer`. `Time`s from two different -// `Timer`s may be measured from different origins and so are not necessarily compatible. - -using Date = Absolute; -// A point in real-world time, measured relative to the Unix epoch (Jan 1, 1970 00:00:00 UTC). - -constexpr Date UNIX_EPOCH = origin(); -// The `Date` representing Jan 1, 1970 00:00:00 UTC. - -class Timer { - // Interface to time and timer functionality. - // - // Each `Timer` may have a different origin, and some `Timer`s may in fact tick at a different - // rate than real time (e.g. a `Timer` could represent CPU time consumed by a thread). However, - // all `Timer`s are monotonic: time will never appear to move backwards, even if the calendar - // date as tracked by the system is manually modified. - -public: - virtual TimePoint now() = 0; - // Returns the current value of a clock that moves steadily forward, independent of any - // changes in the wall clock. The value is updated every time the event loop waits, - // and is constant in-between waits. - - virtual Promise atTime(TimePoint time) = 0; - // Returns a promise that returns as soon as now() >= time. - - virtual Promise afterDelay(Duration delay) = 0; - // Equivalent to atTime(now() + delay). - - template - Promise timeoutAt(TimePoint time, Promise&& promise) KJ_WARN_UNUSED_RESULT; - // Return a promise equivalent to `promise` but which throws an exception (and cancels the - // original promise) if it hasn't completed by `time`. The thrown exception is of type - // "OVERLOADED". - - template - Promise timeoutAfter(Duration delay, Promise&& promise) KJ_WARN_UNUSED_RESULT; - // Return a promise equivalent to `promise` but which throws an exception (and cancels the - // original promise) if it hasn't completed after `delay` from now. The thrown exception is of - // type "OVERLOADED". - -private: - static kj::Exception makeTimeoutException(); -}; - -// ======================================================================================= -// inline implementation details - -template -Promise Timer::timeoutAt(TimePoint time, Promise&& promise) { - return promise.exclusiveJoin(atTime(time).then([]() -> kj::Promise { - return makeTimeoutException(); - })); -} - -template -Promise Timer::timeoutAfter(Duration delay, Promise&& promise) { - return promise.exclusiveJoin(afterDelay(delay).then([]() -> kj::Promise { - return makeTimeoutException(); - })); -} - -} // namespace kj - -#endif // KJ_TIME_H_ +// Copyright (c) 2014 Google Inc. (contributed by Remy Blank ) +// 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. + +#ifndef KJ_TIME_H_ +#define KJ_TIME_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "async.h" +#include "units.h" +#include + +namespace kj { +namespace _ { // private + +class NanosecondLabel; +class TimeLabel; +class DateLabel; + +} // namespace _ (private) + +using Duration = Quantity; +// A time value, in nanoseconds. + +constexpr Duration NANOSECONDS = unit(); +constexpr Duration MICROSECONDS = 1000 * NANOSECONDS; +constexpr Duration MILLISECONDS = 1000 * MICROSECONDS; +constexpr Duration SECONDS = 1000 * MILLISECONDS; +constexpr Duration MINUTES = 60 * SECONDS; +constexpr Duration HOURS = 60 * MINUTES; +constexpr Duration DAYS = 24 * HOURS; + +using TimePoint = Absolute; +// An absolute time measured by some particular instance of `Timer`. `Time`s from two different +// `Timer`s may be measured from different origins and so are not necessarily compatible. + +using Date = Absolute; +// A point in real-world time, measured relative to the Unix epoch (Jan 1, 1970 00:00:00 UTC). + +constexpr Date UNIX_EPOCH = origin(); +// The `Date` representing Jan 1, 1970 00:00:00 UTC. + +class Clock { + // Interface to read the current date and time. +public: + virtual Date now() = 0; +}; + +Clock& nullClock(); +// A clock which always returns UNIX_EPOCH as the current time. Useful when you don't care about +// time. + +class Timer { + // Interface to time and timer functionality. + // + // Each `Timer` may have a different origin, and some `Timer`s may in fact tick at a different + // rate than real time (e.g. a `Timer` could represent CPU time consumed by a thread). However, + // all `Timer`s are monotonic: time will never appear to move backwards, even if the calendar + // date as tracked by the system is manually modified. + +public: + virtual TimePoint now() = 0; + // Returns the current value of a clock that moves steadily forward, independent of any + // changes in the wall clock. The value is updated every time the event loop waits, + // and is constant in-between waits. + + virtual Promise atTime(TimePoint time) = 0; + // Returns a promise that returns as soon as now() >= time. + + virtual Promise afterDelay(Duration delay) = 0; + // Equivalent to atTime(now() + delay). + + template + Promise timeoutAt(TimePoint time, Promise&& promise) KJ_WARN_UNUSED_RESULT; + // Return a promise equivalent to `promise` but which throws an exception (and cancels the + // original promise) if it hasn't completed by `time`. The thrown exception is of type + // "OVERLOADED". + + template + Promise timeoutAfter(Duration delay, Promise&& promise) KJ_WARN_UNUSED_RESULT; + // Return a promise equivalent to `promise` but which throws an exception (and cancels the + // original promise) if it hasn't completed after `delay` from now. The thrown exception is of + // type "OVERLOADED". + +private: + static kj::Exception makeTimeoutException(); +}; + +class TimerImpl final: public Timer { + // Implementation of Timer that expects an external caller -- usually, the EventPort + // implementation -- to tell it when time has advanced. + +public: + TimerImpl(TimePoint startTime); + ~TimerImpl() noexcept(false); + + Maybe nextEvent(); + // Returns the time at which the next scheduled timer event will occur, or null if no timer + // events are scheduled. + + Maybe timeoutToNextEvent(TimePoint start, Duration unit, uint64_t max); + // Convenience method which computes a timeout value to pass to an event-waiting system call to + // cause it to time out when the next timer event occurs. + // + // `start` is the time at which the timeout starts counting. This is typically not the same as + // now() since some time may have passed since the last time advanceTo() was called. + // + // `unit` is the time unit in which the timeout is measured. This is often MILLISECONDS. Note + // that this method will fractional values *up*, to guarantee that the returned timeout waits + // until just *after* the time the event is scheduled. + // + // The timeout will be clamped to `max`. Use this to avoid an overflow if e.g. the OS wants a + // 32-bit value or a signed value. + // + // Returns nullptr if there are no future events. + + void advanceTo(TimePoint newTime); + // Set the time to `time` and fire any at() events that have been passed. + + // implements Timer ---------------------------------------------------------- + TimePoint now() override; + Promise atTime(TimePoint time) override; + Promise afterDelay(Duration delay) override; + +private: + struct Impl; + class TimerPromiseAdapter; + TimePoint time; + Own impl; +}; + +// ======================================================================================= +// inline implementation details + +template +Promise Timer::timeoutAt(TimePoint time, Promise&& promise) { + return promise.exclusiveJoin(atTime(time).then([]() -> kj::Promise { + return makeTimeoutException(); + })); +} + +template +Promise Timer::timeoutAfter(Duration delay, Promise&& promise) { + return promise.exclusiveJoin(afterDelay(delay).then([]() -> kj::Promise { + return makeTimeoutException(); + })); +} + +inline TimePoint TimerImpl::now() { return time; } + +} // namespace kj + +#endif // KJ_TIME_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/tuple.h --- a/win32-mingw/include/kj/tuple.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/tuple.h Tue May 23 09:16:54 2017 +0100 @@ -1,364 +1,364 @@ -// 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 defines a notion of tuples that is simpler that `std::tuple`. It works as follows: -// - `kj::Tuple is the type of a tuple of an A, a B, and a C. -// - `kj::tuple(a, b, c)` returns a tuple containing a, b, and c. If any of these are themselves -// tuples, they are flattened, so `tuple(a, tuple(b, c), d)` is equivalent to `tuple(a, b, c, d)`. -// - `kj::get(myTuple)` returns the element of `myTuple` at index n. -// - `kj::apply(func, ...)` calls func on the following arguments after first expanding any tuples -// in the argument list. So `kj::apply(foo, a, tuple(b, c), d)` would call `foo(a, b, c, d)`. -// -// Note that: -// - The type `Tuple` is a synonym for T. This is why `get` and `apply` are not members of the -// type. -// - It is illegal for an element of `Tuple` to itself be a tuple, as tuples are meant to be -// flattened. -// - It is illegal for an element of `Tuple` to be a reference, due to problems this would cause -// with type inference and `tuple()`. - -#ifndef KJ_TUPLE_H_ -#define KJ_TUPLE_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" - -namespace kj { -namespace _ { // private - -template -struct TypeByIndex_; -template -struct TypeByIndex_<0, First, Rest...> { - typedef First Type; -}; -template -struct TypeByIndex_ - : public TypeByIndex_ {}; -template -struct TypeByIndex_ { - static_assert(index != index, "Index out-of-range."); -}; -template -using TypeByIndex = typename TypeByIndex_::Type; -// Chose a particular type out of a list of types, by index. - -template -struct Indexes {}; -// Dummy helper type that just encapsulates a sequential list of indexes, so that we can match -// templates against them and unpack them with '...'. - -template -struct MakeIndexes_: public MakeIndexes_ {}; -template -struct MakeIndexes_<0, prefix...> { - typedef Indexes Type; -}; -template -using MakeIndexes = typename MakeIndexes_::Type; -// Equivalent to Indexes<0, 1, 2, ..., end>. - -template -class Tuple; -template -inline TypeByIndex& getImpl(Tuple& tuple); -template -inline TypeByIndex&& getImpl(Tuple&& tuple); -template -inline const TypeByIndex& getImpl(const Tuple& tuple); - -template -struct TupleElement { - // Encapsulates one element of a tuple. The actual tuple implementation multiply-inherits - // from a TupleElement for each element, which is more efficient than a recursive definition. - - T value; - TupleElement() = default; - constexpr inline TupleElement(const T& value): value(value) {} - constexpr inline TupleElement(T&& value): value(kj::mv(value)) {} -}; - -template -struct TupleElement { - // If tuples contained references, one of the following would have to be true: - // - `auto x = tuple(y, z)` would cause x to be a tuple of references to y and z, which is - // probably not what you expected. - // - `Tuple x = tuple(a, b)` would not work, because `tuple()` returned - // Tuple. - static_assert(sizeof(T*) == 0, "Sorry, tuples cannot contain references."); -}; - -template -struct TupleElement> { - static_assert(sizeof(Tuple*) == 0, - "Tuples cannot contain other tuples -- they should be flattened."); -}; - -template -struct TupleImpl; - -template -struct TupleImpl, Types...> - : public TupleElement... { - // Implementation of Tuple. The only reason we need this rather than rolling this into class - // Tuple (below) is so that we can get "indexes" as an unpackable list. - - static_assert(sizeof...(indexes) == sizeof...(Types), "Incorrect use of TupleImpl."); - - template - inline TupleImpl(Params&&... params) - : TupleElement(kj::fwd(params))... { - // Work around Clang 3.2 bug 16303 where this is not detected. (Unfortunately, Clang sometimes - // segfaults instead.) - static_assert(sizeof...(params) == sizeof...(indexes), - "Wrong number of parameters to Tuple constructor."); - } - - template - constexpr inline TupleImpl(Tuple&& other) - : TupleElement(kj::mv(getImpl(other)))... {} - template - constexpr inline TupleImpl(Tuple& other) - : TupleElement(getImpl(other))... {} - template - constexpr inline TupleImpl(const Tuple& other) - : TupleElement(getImpl(other))... {} -}; - -struct MakeTupleFunc; - -template -class Tuple { - // The actual Tuple class (used for tuples of size other than 1). - -public: - template - constexpr inline Tuple(Tuple&& other): impl(kj::mv(other)) {} - template - constexpr inline Tuple(Tuple& other): impl(other) {} - template - constexpr inline Tuple(const Tuple& other): impl(other) {} - -private: - template - constexpr Tuple(Params&&... params): impl(kj::fwd(params)...) {} - - TupleImpl, T...> impl; - - template - friend inline TypeByIndex& getImpl(Tuple& tuple); - template - friend inline TypeByIndex&& getImpl(Tuple&& tuple); - template - friend inline const TypeByIndex& getImpl(const Tuple& tuple); - friend struct MakeTupleFunc; -}; - -template <> -class Tuple<> { - // Simplified zero-member version of Tuple. In particular this is important to make sure that - // Tuple<>() is constexpr. -}; - -template -class Tuple; -// Single-element tuple should never be used. The public API should ensure this. - -template -inline TypeByIndex& getImpl(Tuple& tuple) { - // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. - static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); - return implicitCast>&>(tuple.impl).value; -} -template -inline TypeByIndex&& getImpl(Tuple&& tuple) { - // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. - static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); - return kj::mv(implicitCast>&>(tuple.impl).value); -} -template -inline const TypeByIndex& getImpl(const Tuple& tuple) { - // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. - static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); - return implicitCast>&>(tuple.impl).value; -} -template -inline T&& getImpl(T&& value) { - // Get member of a Tuple by index, e.g. `getImpl<2>(myTuple)`. - - // Non-tuples are equivalent to one-element tuples. - static_assert(index == 0, "Tuple element index out-of-bounds."); - return kj::fwd(value); -} - - -template -struct ExpandAndApplyResult_; -// Template which computes the return type of applying Func to T... after flattening tuples. -// SoFar starts as Tuple<> and accumulates the flattened parameter types -- so after this template -// is recursively expanded, T... is empty and SoFar is a Tuple containing all the parameters. - -template -struct ExpandAndApplyResult_, First, Rest...> - : public ExpandAndApplyResult_, Rest...> {}; -template -struct ExpandAndApplyResult_, Tuple, Rest...> - : public ExpandAndApplyResult_, FirstTypes&&..., Rest...> {}; -template -struct ExpandAndApplyResult_, Tuple&, Rest...> - : public ExpandAndApplyResult_, FirstTypes&..., Rest...> {}; -template -struct ExpandAndApplyResult_, const Tuple&, Rest...> - : public ExpandAndApplyResult_, const FirstTypes&..., Rest...> {}; -template -struct ExpandAndApplyResult_> { - typedef decltype(instance()(instance()...)) Type; -}; -template -using ExpandAndApplyResult = typename ExpandAndApplyResult_, T...>::Type; -// Computes the expected return type of `expandAndApply()`. - -template -inline auto expandAndApply(Func&& func) -> ExpandAndApplyResult { - return func(); -} - -template -struct ExpandAndApplyFunc { - Func&& func; - First&& first; - ExpandAndApplyFunc(Func&& func, First&& first) - : func(kj::fwd(func)), first(kj::fwd(first)) {} - template - auto operator()(T&&... params) - -> decltype(this->func(kj::fwd(first), kj::fwd(params)...)) { - return this->func(kj::fwd(first), kj::fwd(params)...); - } -}; - -template -inline auto expandAndApply(Func&& func, First&& first, Rest&&... rest) - -> ExpandAndApplyResult { - - return expandAndApply( - ExpandAndApplyFunc(kj::fwd(func), kj::fwd(first)), - kj::fwd(rest)...); -} - -template -inline auto expandAndApply(Func&& func, Tuple&& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApplyWithIndexes(MakeIndexes(), - kj::fwd(func), kj::mv(first), kj::fwd(rest)...); -} - -template -inline auto expandAndApply(Func&& func, Tuple& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApplyWithIndexes(MakeIndexes(), - kj::fwd(func), first, kj::fwd(rest)...); -} - -template -inline auto expandAndApply(Func&& func, const Tuple& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApplyWithIndexes(MakeIndexes(), - kj::fwd(func), first, kj::fwd(rest)...); -} - -template -inline auto expandAndApplyWithIndexes( - Indexes, Func&& func, Tuple&& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApply(kj::fwd(func), kj::mv(getImpl(first))..., - kj::fwd(rest)...); -} - -template -inline auto expandAndApplyWithIndexes( - Indexes, Func&& func, const Tuple& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApply(kj::fwd(func), getImpl(first)..., - kj::fwd(rest)...); -} - -struct MakeTupleFunc { - template - Tuple...> operator()(Params&&... params) { - return Tuple...>(kj::fwd(params)...); - } - template - Decay operator()(Param&& param) { - return kj::fwd(param); - } -}; - -} // namespace _ (private) - -template struct Tuple_ { typedef _::Tuple Type; }; -template struct Tuple_ { typedef T Type; }; - -template using Tuple = typename Tuple_::Type; -// Tuple type. `Tuple` (i.e. a single-element tuple) is a synonym for `T`. Tuples of size -// other than 1 expand to an internal type. Either way, you can construct a Tuple using -// `kj::tuple(...)`, get an element by index `i` using `kj::get(myTuple)`, and expand the tuple -// as arguments to a function using `kj::apply(func, myTuple)`. -// -// Tuples are always flat -- that is, no element of a Tuple is ever itself a Tuple. If you -// construct a tuple from other tuples, the elements are flattened and concatenated. - -template -inline auto tuple(Params&&... params) - -> decltype(_::expandAndApply(_::MakeTupleFunc(), kj::fwd(params)...)) { - // Construct a new tuple from the given values. Any tuples in the argument list will be - // flattened into the result. - return _::expandAndApply(_::MakeTupleFunc(), kj::fwd(params)...); -} - -template -inline auto get(Tuple&& tuple) -> decltype(_::getImpl(kj::fwd(tuple))) { - // Unpack and return the tuple element at the given index. The index is specified as a template - // parameter, e.g. `kj::get<3>(myTuple)`. - return _::getImpl(kj::fwd(tuple)); -} - -template -inline auto apply(Func&& func, Params&&... params) - -> decltype(_::expandAndApply(kj::fwd(func), kj::fwd(params)...)) { - // Apply a function to some arguments, expanding tuples into separate arguments. - return _::expandAndApply(kj::fwd(func), kj::fwd(params)...); -} - -template struct TupleSize_ { static constexpr size_t size = 1; }; -template struct TupleSize_<_::Tuple> { - static constexpr size_t size = sizeof...(T); -}; - -template -constexpr size_t tupleSize() { return TupleSize_::size; } -// Returns size of the tuple T. - -} // namespace kj - -#endif // KJ_TUPLE_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 defines a notion of tuples that is simpler that `std::tuple`. It works as follows: +// - `kj::Tuple is the type of a tuple of an A, a B, and a C. +// - `kj::tuple(a, b, c)` returns a tuple containing a, b, and c. If any of these are themselves +// tuples, they are flattened, so `tuple(a, tuple(b, c), d)` is equivalent to `tuple(a, b, c, d)`. +// - `kj::get(myTuple)` returns the element of `myTuple` at index n. +// - `kj::apply(func, ...)` calls func on the following arguments after first expanding any tuples +// in the argument list. So `kj::apply(foo, a, tuple(b, c), d)` would call `foo(a, b, c, d)`. +// +// Note that: +// - The type `Tuple` is a synonym for T. This is why `get` and `apply` are not members of the +// type. +// - It is illegal for an element of `Tuple` to itself be a tuple, as tuples are meant to be +// flattened. +// - It is illegal for an element of `Tuple` to be a reference, due to problems this would cause +// with type inference and `tuple()`. + +#ifndef KJ_TUPLE_H_ +#define KJ_TUPLE_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" + +namespace kj { +namespace _ { // private + +template +struct TypeByIndex_; +template +struct TypeByIndex_<0, First, Rest...> { + typedef First Type; +}; +template +struct TypeByIndex_ + : public TypeByIndex_ {}; +template +struct TypeByIndex_ { + static_assert(index != index, "Index out-of-range."); +}; +template +using TypeByIndex = typename TypeByIndex_::Type; +// Chose a particular type out of a list of types, by index. + +template +struct Indexes {}; +// Dummy helper type that just encapsulates a sequential list of indexes, so that we can match +// templates against them and unpack them with '...'. + +template +struct MakeIndexes_: public MakeIndexes_ {}; +template +struct MakeIndexes_<0, prefix...> { + typedef Indexes Type; +}; +template +using MakeIndexes = typename MakeIndexes_::Type; +// Equivalent to Indexes<0, 1, 2, ..., end>. + +template +class Tuple; +template +inline TypeByIndex& getImpl(Tuple& tuple); +template +inline TypeByIndex&& getImpl(Tuple&& tuple); +template +inline const TypeByIndex& getImpl(const Tuple& tuple); + +template +struct TupleElement { + // Encapsulates one element of a tuple. The actual tuple implementation multiply-inherits + // from a TupleElement for each element, which is more efficient than a recursive definition. + + T value; + TupleElement() = default; + constexpr inline TupleElement(const T& value): value(value) {} + constexpr inline TupleElement(T&& value): value(kj::mv(value)) {} +}; + +template +struct TupleElement { + // If tuples contained references, one of the following would have to be true: + // - `auto x = tuple(y, z)` would cause x to be a tuple of references to y and z, which is + // probably not what you expected. + // - `Tuple x = tuple(a, b)` would not work, because `tuple()` returned + // Tuple. + static_assert(sizeof(T*) == 0, "Sorry, tuples cannot contain references."); +}; + +template +struct TupleElement> { + static_assert(sizeof(Tuple*) == 0, + "Tuples cannot contain other tuples -- they should be flattened."); +}; + +template +struct TupleImpl; + +template +struct TupleImpl, Types...> + : public TupleElement... { + // Implementation of Tuple. The only reason we need this rather than rolling this into class + // Tuple (below) is so that we can get "indexes" as an unpackable list. + + static_assert(sizeof...(indexes) == sizeof...(Types), "Incorrect use of TupleImpl."); + + template + inline TupleImpl(Params&&... params) + : TupleElement(kj::fwd(params))... { + // Work around Clang 3.2 bug 16303 where this is not detected. (Unfortunately, Clang sometimes + // segfaults instead.) + static_assert(sizeof...(params) == sizeof...(indexes), + "Wrong number of parameters to Tuple constructor."); + } + + template + constexpr inline TupleImpl(Tuple&& other) + : TupleElement(kj::mv(getImpl(other)))... {} + template + constexpr inline TupleImpl(Tuple& other) + : TupleElement(getImpl(other))... {} + template + constexpr inline TupleImpl(const Tuple& other) + : TupleElement(getImpl(other))... {} +}; + +struct MakeTupleFunc; + +template +class Tuple { + // The actual Tuple class (used for tuples of size other than 1). + +public: + template + constexpr inline Tuple(Tuple&& other): impl(kj::mv(other)) {} + template + constexpr inline Tuple(Tuple& other): impl(other) {} + template + constexpr inline Tuple(const Tuple& other): impl(other) {} + +private: + template + constexpr Tuple(Params&&... params): impl(kj::fwd(params)...) {} + + TupleImpl, T...> impl; + + template + friend inline TypeByIndex& getImpl(Tuple& tuple); + template + friend inline TypeByIndex&& getImpl(Tuple&& tuple); + template + friend inline const TypeByIndex& getImpl(const Tuple& tuple); + friend struct MakeTupleFunc; +}; + +template <> +class Tuple<> { + // Simplified zero-member version of Tuple. In particular this is important to make sure that + // Tuple<>() is constexpr. +}; + +template +class Tuple; +// Single-element tuple should never be used. The public API should ensure this. + +template +inline TypeByIndex& getImpl(Tuple& tuple) { + // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. + static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); + return implicitCast>&>(tuple.impl).value; +} +template +inline TypeByIndex&& getImpl(Tuple&& tuple) { + // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. + static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); + return kj::mv(implicitCast>&>(tuple.impl).value); +} +template +inline const TypeByIndex& getImpl(const Tuple& tuple) { + // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. + static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); + return implicitCast>&>(tuple.impl).value; +} +template +inline T&& getImpl(T&& value) { + // Get member of a Tuple by index, e.g. `getImpl<2>(myTuple)`. + + // Non-tuples are equivalent to one-element tuples. + static_assert(index == 0, "Tuple element index out-of-bounds."); + return kj::fwd(value); +} + + +template +struct ExpandAndApplyResult_; +// Template which computes the return type of applying Func to T... after flattening tuples. +// SoFar starts as Tuple<> and accumulates the flattened parameter types -- so after this template +// is recursively expanded, T... is empty and SoFar is a Tuple containing all the parameters. + +template +struct ExpandAndApplyResult_, First, Rest...> + : public ExpandAndApplyResult_, Rest...> {}; +template +struct ExpandAndApplyResult_, Tuple, Rest...> + : public ExpandAndApplyResult_, FirstTypes&&..., Rest...> {}; +template +struct ExpandAndApplyResult_, Tuple&, Rest...> + : public ExpandAndApplyResult_, FirstTypes&..., Rest...> {}; +template +struct ExpandAndApplyResult_, const Tuple&, Rest...> + : public ExpandAndApplyResult_, const FirstTypes&..., Rest...> {}; +template +struct ExpandAndApplyResult_> { + typedef decltype(instance()(instance()...)) Type; +}; +template +using ExpandAndApplyResult = typename ExpandAndApplyResult_, T...>::Type; +// Computes the expected return type of `expandAndApply()`. + +template +inline auto expandAndApply(Func&& func) -> ExpandAndApplyResult { + return func(); +} + +template +struct ExpandAndApplyFunc { + Func&& func; + First&& first; + ExpandAndApplyFunc(Func&& func, First&& first) + : func(kj::fwd(func)), first(kj::fwd(first)) {} + template + auto operator()(T&&... params) + -> decltype(this->func(kj::fwd(first), kj::fwd(params)...)) { + return this->func(kj::fwd(first), kj::fwd(params)...); + } +}; + +template +inline auto expandAndApply(Func&& func, First&& first, Rest&&... rest) + -> ExpandAndApplyResult { + + return expandAndApply( + ExpandAndApplyFunc(kj::fwd(func), kj::fwd(first)), + kj::fwd(rest)...); +} + +template +inline auto expandAndApply(Func&& func, Tuple&& first, Rest&&... rest) + -> ExpandAndApplyResult { + return expandAndApplyWithIndexes(MakeIndexes(), + kj::fwd(func), kj::mv(first), kj::fwd(rest)...); +} + +template +inline auto expandAndApply(Func&& func, Tuple& first, Rest&&... rest) + -> ExpandAndApplyResult { + return expandAndApplyWithIndexes(MakeIndexes(), + kj::fwd(func), first, kj::fwd(rest)...); +} + +template +inline auto expandAndApply(Func&& func, const Tuple& first, Rest&&... rest) + -> ExpandAndApplyResult { + return expandAndApplyWithIndexes(MakeIndexes(), + kj::fwd(func), first, kj::fwd(rest)...); +} + +template +inline auto expandAndApplyWithIndexes( + Indexes, Func&& func, Tuple&& first, Rest&&... rest) + -> ExpandAndApplyResult { + return expandAndApply(kj::fwd(func), kj::mv(getImpl(first))..., + kj::fwd(rest)...); +} + +template +inline auto expandAndApplyWithIndexes( + Indexes, Func&& func, const Tuple& first, Rest&&... rest) + -> ExpandAndApplyResult { + return expandAndApply(kj::fwd(func), getImpl(first)..., + kj::fwd(rest)...); +} + +struct MakeTupleFunc { + template + Tuple...> operator()(Params&&... params) { + return Tuple...>(kj::fwd(params)...); + } + template + Decay operator()(Param&& param) { + return kj::fwd(param); + } +}; + +} // namespace _ (private) + +template struct Tuple_ { typedef _::Tuple Type; }; +template struct Tuple_ { typedef T Type; }; + +template using Tuple = typename Tuple_::Type; +// Tuple type. `Tuple` (i.e. a single-element tuple) is a synonym for `T`. Tuples of size +// other than 1 expand to an internal type. Either way, you can construct a Tuple using +// `kj::tuple(...)`, get an element by index `i` using `kj::get(myTuple)`, and expand the tuple +// as arguments to a function using `kj::apply(func, myTuple)`. +// +// Tuples are always flat -- that is, no element of a Tuple is ever itself a Tuple. If you +// construct a tuple from other tuples, the elements are flattened and concatenated. + +template +inline auto tuple(Params&&... params) + -> decltype(_::expandAndApply(_::MakeTupleFunc(), kj::fwd(params)...)) { + // Construct a new tuple from the given values. Any tuples in the argument list will be + // flattened into the result. + return _::expandAndApply(_::MakeTupleFunc(), kj::fwd(params)...); +} + +template +inline auto get(Tuple&& tuple) -> decltype(_::getImpl(kj::fwd(tuple))) { + // Unpack and return the tuple element at the given index. The index is specified as a template + // parameter, e.g. `kj::get<3>(myTuple)`. + return _::getImpl(kj::fwd(tuple)); +} + +template +inline auto apply(Func&& func, Params&&... params) + -> decltype(_::expandAndApply(kj::fwd(func), kj::fwd(params)...)) { + // Apply a function to some arguments, expanding tuples into separate arguments. + return _::expandAndApply(kj::fwd(func), kj::fwd(params)...); +} + +template struct TupleSize_ { static constexpr size_t size = 1; }; +template struct TupleSize_<_::Tuple> { + static constexpr size_t size = sizeof...(T); +}; + +template +constexpr size_t tupleSize() { return TupleSize_::size; } +// Returns size of the tuple T. + +} // namespace kj + +#endif // KJ_TUPLE_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/units.h --- a/win32-mingw/include/kj/units.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/units.h Tue May 23 09:16:54 2017 +0100 @@ -1,433 +1,1172 @@ -// 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 KJ_UNITS_H_ -#define KJ_UNITS_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" - -namespace kj { - -// ======================================================================================= -// IDs - -template -struct Id { - // A type-safe numeric ID. `UnderlyingType` is the underlying integer representation. `Label` - // distinguishes this Id from other Id types. Sample usage: - // - // class Foo; - // typedef Id FooId; - // - // class Bar; - // typedef Id BarId; - // - // You can now use the FooId and BarId types without any possibility of accidentally using a - // FooId when you really wanted a BarId or vice-versa. - - UnderlyingType value; - - inline constexpr Id(): value(0) {} - inline constexpr explicit Id(int value): value(value) {} - - inline constexpr bool operator==(const Id& other) const { return value == other.value; } - inline constexpr bool operator!=(const Id& other) const { return value != other.value; } - inline constexpr bool operator<=(const Id& other) const { return value <= other.value; } - inline constexpr bool operator>=(const Id& other) const { return value >= other.value; } - inline constexpr bool operator< (const Id& other) const { return value < other.value; } - inline constexpr bool operator> (const Id& other) const { return value > other.value; } -}; - -// ======================================================================================= -// Quantity and UnitRatio -- implement unit analysis via the type system - -template constexpr bool isIntegral() { return false; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } - -template -class UnitRatio { - // A multiplier used to convert Quantities of one unit to Quantities of another unit. See - // Quantity, below. - // - // Construct this type by dividing one Quantity by another of a different unit. Use this type - // by multiplying it by a Quantity, or dividing a Quantity by it. - - static_assert(isIntegral(), "Underlying type for UnitRatio must be integer."); - -public: - inline UnitRatio() {} - - constexpr explicit UnitRatio(Number unit1PerUnit2): unit1PerUnit2(unit1PerUnit2) {} - // This constructor was intended to be private, but GCC complains about it being private in a - // bunch of places that don't appear to even call it, so I made it public. Oh well. - - template - inline constexpr UnitRatio(const UnitRatio& other) - : unit1PerUnit2(other.unit1PerUnit2) {} - - template - inline constexpr UnitRatio - operator+(UnitRatio other) const { - return UnitRatio( - unit1PerUnit2 + other.unit1PerUnit2); - } - template - inline constexpr UnitRatio - operator-(UnitRatio other) const { - return UnitRatio( - unit1PerUnit2 - other.unit1PerUnit2); - } - - template - inline constexpr UnitRatio - operator*(UnitRatio other) const { - // U1 / U2 * U3 / U1 = U3 / U2 - return UnitRatio( - unit1PerUnit2 * other.unit1PerUnit2); - } - template - inline constexpr UnitRatio - operator*(UnitRatio other) const { - // U1 / U2 * U2 / U3 = U1 / U3 - return UnitRatio( - unit1PerUnit2 * other.unit1PerUnit2); - } - - template - inline constexpr UnitRatio - operator/(UnitRatio other) const { - // (U1 / U2) / (U1 / U3) = U3 / U2 - return UnitRatio( - unit1PerUnit2 / other.unit1PerUnit2); - } - template - inline constexpr UnitRatio - operator/(UnitRatio other) const { - // (U1 / U2) / (U3 / U2) = U1 / U3 - return UnitRatio( - unit1PerUnit2 / other.unit1PerUnit2); - } - - template - inline decltype(Number(1) / OtherNumber(1)) - operator/(UnitRatio other) const { - return unit1PerUnit2 / other.unit1PerUnit2; - } - - inline bool operator==(UnitRatio other) const { return unit1PerUnit2 == other.unit1PerUnit2; } - inline bool operator!=(UnitRatio other) const { return unit1PerUnit2 != other.unit1PerUnit2; } - -private: - Number unit1PerUnit2; - - template - friend class Quantity; - template - friend class UnitRatio; - - template - friend inline constexpr UnitRatio - operator*(N1, UnitRatio); -}; - -template -inline constexpr UnitRatio - operator*(N1 n, UnitRatio r) { - return UnitRatio(n * r.unit1PerUnit2); -} - -template -class Quantity { - // A type-safe numeric quantity, specified in terms of some unit. Two Quantities cannot be used - // in arithmetic unless they use the same unit. The `Unit` type parameter is only used to prevent - // accidental mixing of units; this type is never instantiated and can very well be incomplete. - // `Number` is the underlying primitive numeric type. - // - // Quantities support most basic arithmetic operators, intelligently handling units, and - // automatically casting the underlying type in the same way that the compiler would. - // - // To convert a primitive number to a Quantity, multiply it by unit>(). - // To convert a Quantity to a primitive number, divide it by unit>(). - // To convert a Quantity of one unit to another unit, multiply or divide by a UnitRatio. - // - // The Quantity class is not well-suited to hardcore physics as it does not allow multiplying - // one quantity by another. For example, multiplying meters by meters won't get you square - // meters; it will get you a compiler error. It would be interesting to see if template - // metaprogramming could properly deal with such things but this isn't needed for the present - // use case. - // - // Sample usage: - // - // class SecondsLabel; - // typedef Quantity Seconds; - // constexpr Seconds SECONDS = unit(); - // - // class MinutesLabel; - // typedef Quantity Minutes; - // constexpr Minutes MINUTES = unit(); - // - // constexpr UnitRatio SECONDS_PER_MINUTE = - // 60 * SECONDS / MINUTES; - // - // void waitFor(Seconds seconds) { - // sleep(seconds / SECONDS); - // } - // void waitFor(Minutes minutes) { - // waitFor(minutes * SECONDS_PER_MINUTE); - // } - // - // void waitThreeMinutes() { - // waitFor(3 * MINUTES); - // } - - static_assert(isIntegral(), "Underlying type for Quantity must be integer."); - -public: - inline constexpr Quantity() {} - - inline constexpr Quantity(MaxValue_): value(maxValue) {} - inline constexpr Quantity(MinValue_): value(minValue) {} - // Allow initialization from maxValue and minValue. - // TODO(msvc): decltype(maxValue) and decltype(minValue) deduce unknown-type for these function - // parameters, causing the compiler to complain of a duplicate constructor definition, so we - // specify MaxValue_ and MinValue_ types explicitly. - - inline explicit constexpr Quantity(Number value): value(value) {} - // This constructor was intended to be private, but GCC complains about it being private in a - // bunch of places that don't appear to even call it, so I made it public. Oh well. - - template - inline constexpr Quantity(const Quantity& other) - : value(other.value) {} - - template - inline constexpr Quantity - operator+(const Quantity& other) const { - return Quantity(value + other.value); - } - template - inline constexpr Quantity - operator-(const Quantity& other) const { - return Quantity(value - other.value); - } - template - inline constexpr Quantity - operator*(OtherNumber other) const { - static_assert(isIntegral(), "Multiplied Quantity by non-integer."); - return Quantity(value * other); - } - template - inline constexpr Quantity - operator/(OtherNumber other) const { - static_assert(isIntegral(), "Divided Quantity by non-integer."); - return Quantity(value / other); - } - template - inline constexpr decltype(Number(1) / OtherNumber(1)) - operator/(const Quantity& other) const { - return value / other.value; - } - template - inline constexpr decltype(Number(1) % OtherNumber(1)) - operator%(const Quantity& other) const { - return value % other.value; - } - - template - inline constexpr Quantity - operator*(const UnitRatio& ratio) const { - return Quantity( - value * ratio.unit1PerUnit2); - } - template - inline constexpr Quantity - operator/(const UnitRatio& ratio) const { - return Quantity( - value / ratio.unit1PerUnit2); - } - template - inline constexpr Quantity - operator%(const UnitRatio& ratio) const { - return Quantity( - value % ratio.unit1PerUnit2); - } - template - inline constexpr UnitRatio - operator/(const Quantity& other) const { - return UnitRatio(value / other.value); - } - - template - inline constexpr bool operator==(const Quantity& other) const { - return value == other.value; - } - template - inline constexpr bool operator!=(const Quantity& other) const { - return value != other.value; - } - template - inline constexpr bool operator<=(const Quantity& other) const { - return value <= other.value; - } - template - inline constexpr bool operator>=(const Quantity& other) const { - return value >= other.value; - } - template - inline constexpr bool operator<(const Quantity& other) const { - return value < other.value; - } - template - inline constexpr bool operator>(const Quantity& other) const { - return value > other.value; - } - - template - inline Quantity& operator+=(const Quantity& other) { - value += other.value; - return *this; - } - template - inline Quantity& operator-=(const Quantity& other) { - value -= other.value; - return *this; - } - template - inline Quantity& operator*=(OtherNumber other) { - value *= other; - return *this; - } - template - inline Quantity& operator/=(OtherNumber other) { - value /= other.value; - return *this; - } - -private: - Number value; - - template - friend class Quantity; - - template - friend inline constexpr auto operator*(Number1 a, Quantity b) - -> Quantity; - - template - friend inline constexpr T unit(); -}; - -template -inline constexpr T unit() { return T(1); } -// unit>() returns a Quantity of value 1. It also, intentionally, works on basic -// numeric types. - -template -inline constexpr auto operator*(Number1 a, Quantity b) - -> Quantity { - return Quantity(a * b.value); -} - -template -inline constexpr auto operator*(UnitRatio ratio, - Quantity measure) - -> decltype(measure * ratio) { - return measure * ratio; -} - -// ======================================================================================= -// Absolute measures - -template -class Absolute { - // Wraps some other value -- typically a Quantity -- but represents a value measured based on - // some absolute origin. For example, if `Duration` is a type representing a time duration, - // Absolute might be a calendar date. - // - // Since Absolute represents measurements relative to some arbitrary origin, the only sensible - // arithmetic to perform on them is addition and subtraction. - - // TODO(someday): Do the same automatic expansion of integer width that Quantity does? Doesn't - // matter for our time use case, where we always use 64-bit anyway. Note that fixing this - // would implicitly allow things like multiplying an Absolute by a UnitRatio to change its - // units, which is actually totally logical and kind of neat. - -public: - inline constexpr Absolute operator+(const T& other) const { return Absolute(value + other); } - inline constexpr Absolute operator-(const T& other) const { return Absolute(value - other); } - inline constexpr T operator-(const Absolute& other) const { return value - other.value; } - - inline Absolute& operator+=(const T& other) { value += other; return *this; } - inline Absolute& operator-=(const T& other) { value -= other; return *this; } - - inline constexpr bool operator==(const Absolute& other) const { return value == other.value; } - inline constexpr bool operator!=(const Absolute& other) const { return value != other.value; } - inline constexpr bool operator<=(const Absolute& other) const { return value <= other.value; } - inline constexpr bool operator>=(const Absolute& other) const { return value >= other.value; } - inline constexpr bool operator< (const Absolute& other) const { return value < other.value; } - inline constexpr bool operator> (const Absolute& other) const { return value > other.value; } - -private: - T value; - - explicit constexpr Absolute(T value): value(value) {} - - template - friend inline constexpr U origin(); -}; - -template -inline constexpr Absolute operator+(const T& a, const Absolute& b) { - return b + a; -} - -template struct UnitOf_ { typedef T Type; }; -template struct UnitOf_> { typedef T Type; }; -template -using UnitOf = typename UnitOf_::Type; -// UnitOf> is T. UnitOf is AnythingElse. - -template -inline constexpr T origin() { return T(0 * unit>()); } -// origin>() returns an Absolute of value 0. It also, intentionally, works on basic -// numeric types. - -} // namespace kj - -#endif // KJ_UNITS_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 KJ_UNITS_H_ +#define KJ_UNITS_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" +#include + +namespace kj { + +// ======================================================================================= +// IDs + +template +struct Id { + // A type-safe numeric ID. `UnderlyingType` is the underlying integer representation. `Label` + // distinguishes this Id from other Id types. Sample usage: + // + // class Foo; + // typedef Id FooId; + // + // class Bar; + // typedef Id BarId; + // + // You can now use the FooId and BarId types without any possibility of accidentally using a + // FooId when you really wanted a BarId or vice-versa. + + UnderlyingType value; + + inline constexpr Id(): value(0) {} + inline constexpr explicit Id(int value): value(value) {} + + inline constexpr bool operator==(const Id& other) const { return value == other.value; } + inline constexpr bool operator!=(const Id& other) const { return value != other.value; } + inline constexpr bool operator<=(const Id& other) const { return value <= other.value; } + inline constexpr bool operator>=(const Id& other) const { return value >= other.value; } + inline constexpr bool operator< (const Id& other) const { return value < other.value; } + inline constexpr bool operator> (const Id& other) const { return value > other.value; } +}; + +// ======================================================================================= +// Quantity and UnitRatio -- implement unit analysis via the type system + +struct Unsafe_ {}; +constexpr Unsafe_ unsafe = Unsafe_(); +// Use as a parameter to constructors that are unsafe to indicate that you really do mean it. + +template +class Bounded; +template +class BoundedConst; + +template constexpr bool isIntegral() { return false; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } + +template +struct IsIntegralOrBounded_ { static constexpr bool value = isIntegral(); }; +template +struct IsIntegralOrBounded_> { static constexpr bool value = true; }; +template +struct IsIntegralOrBounded_> { static constexpr bool value = true; }; + +template +inline constexpr bool isIntegralOrBounded() { return IsIntegralOrBounded_::value; } + +template +class UnitRatio { + // A multiplier used to convert Quantities of one unit to Quantities of another unit. See + // Quantity, below. + // + // Construct this type by dividing one Quantity by another of a different unit. Use this type + // by multiplying it by a Quantity, or dividing a Quantity by it. + + static_assert(isIntegralOrBounded(), + "Underlying type for UnitRatio must be integer."); + +public: + inline UnitRatio() {} + + constexpr UnitRatio(Number unit1PerUnit2, decltype(unsafe)): unit1PerUnit2(unit1PerUnit2) {} + // This constructor was intended to be private, but GCC complains about it being private in a + // bunch of places that don't appear to even call it, so I made it public. Oh well. + + template + inline constexpr UnitRatio(const UnitRatio& other) + : unit1PerUnit2(other.unit1PerUnit2) {} + + template + inline constexpr UnitRatio + operator+(UnitRatio other) const { + return UnitRatio( + unit1PerUnit2 + other.unit1PerUnit2, unsafe); + } + template + inline constexpr UnitRatio + operator-(UnitRatio other) const { + return UnitRatio( + unit1PerUnit2 - other.unit1PerUnit2, unsafe); + } + + template + inline constexpr UnitRatio + operator*(UnitRatio other) const { + // U1 / U2 * U3 / U1 = U3 / U2 + return UnitRatio( + unit1PerUnit2 * other.unit1PerUnit2, unsafe); + } + template + inline constexpr UnitRatio + operator*(UnitRatio other) const { + // U1 / U2 * U2 / U3 = U1 / U3 + return UnitRatio( + unit1PerUnit2 * other.unit1PerUnit2, unsafe); + } + + template + inline constexpr UnitRatio + operator/(UnitRatio other) const { + // (U1 / U2) / (U1 / U3) = U3 / U2 + return UnitRatio( + unit1PerUnit2 / other.unit1PerUnit2, unsafe); + } + template + inline constexpr UnitRatio + operator/(UnitRatio other) const { + // (U1 / U2) / (U3 / U2) = U1 / U3 + return UnitRatio( + unit1PerUnit2 / other.unit1PerUnit2, unsafe); + } + + template + inline decltype(Number() / OtherNumber()) + operator/(UnitRatio other) const { + return unit1PerUnit2 / other.unit1PerUnit2; + } + + inline bool operator==(UnitRatio other) const { return unit1PerUnit2 == other.unit1PerUnit2; } + inline bool operator!=(UnitRatio other) const { return unit1PerUnit2 != other.unit1PerUnit2; } + +private: + Number unit1PerUnit2; + + template + friend class Quantity; + template + friend class UnitRatio; + + template + friend inline constexpr UnitRatio + operator*(N1, UnitRatio); +}; + +template () && isIntegralOrBounded()>> +inline constexpr UnitRatio + operator*(N1 n, UnitRatio r) { + return UnitRatio(n * r.unit1PerUnit2, unsafe); +} + +template +class Quantity { + // A type-safe numeric quantity, specified in terms of some unit. Two Quantities cannot be used + // in arithmetic unless they use the same unit. The `Unit` type parameter is only used to prevent + // accidental mixing of units; this type is never instantiated and can very well be incomplete. + // `Number` is the underlying primitive numeric type. + // + // Quantities support most basic arithmetic operators, intelligently handling units, and + // automatically casting the underlying type in the same way that the compiler would. + // + // To convert a primitive number to a Quantity, multiply it by unit>(). + // To convert a Quantity to a primitive number, divide it by unit>(). + // To convert a Quantity of one unit to another unit, multiply or divide by a UnitRatio. + // + // The Quantity class is not well-suited to hardcore physics as it does not allow multiplying + // one quantity by another. For example, multiplying meters by meters won't get you square + // meters; it will get you a compiler error. It would be interesting to see if template + // metaprogramming could properly deal with such things but this isn't needed for the present + // use case. + // + // Sample usage: + // + // class SecondsLabel; + // typedef Quantity Seconds; + // constexpr Seconds SECONDS = unit(); + // + // class MinutesLabel; + // typedef Quantity Minutes; + // constexpr Minutes MINUTES = unit(); + // + // constexpr UnitRatio SECONDS_PER_MINUTE = + // 60 * SECONDS / MINUTES; + // + // void waitFor(Seconds seconds) { + // sleep(seconds / SECONDS); + // } + // void waitFor(Minutes minutes) { + // waitFor(minutes * SECONDS_PER_MINUTE); + // } + // + // void waitThreeMinutes() { + // waitFor(3 * MINUTES); + // } + + static_assert(isIntegralOrBounded(), + "Underlying type for Quantity must be integer."); + +public: + inline constexpr Quantity() = default; + + inline constexpr Quantity(MaxValue_): value(maxValue) {} + inline constexpr Quantity(MinValue_): value(minValue) {} + // Allow initialization from maxValue and minValue. + // TODO(msvc): decltype(maxValue) and decltype(minValue) deduce unknown-type for these function + // parameters, causing the compiler to complain of a duplicate constructor definition, so we + // specify MaxValue_ and MinValue_ types explicitly. + + inline constexpr Quantity(Number value, decltype(unsafe)): value(value) {} + // This constructor was intended to be private, but GCC complains about it being private in a + // bunch of places that don't appear to even call it, so I made it public. Oh well. + + template + inline constexpr Quantity(const Quantity& other) + : value(other.value) {} + + template + inline Quantity& operator=(const Quantity& other) { + value = other.value; + return *this; + } + + template + inline constexpr Quantity + operator+(const Quantity& other) const { + return Quantity(value + other.value, unsafe); + } + template + inline constexpr Quantity + operator-(const Quantity& other) const { + return Quantity(value - other.value, unsafe); + } + template ()>> + inline constexpr Quantity + operator*(OtherNumber other) const { + return Quantity(value * other, unsafe); + } + template ()>> + inline constexpr Quantity + operator/(OtherNumber other) const { + return Quantity(value / other, unsafe); + } + template + inline constexpr decltype(Number() / OtherNumber()) + operator/(const Quantity& other) const { + return value / other.value; + } + template + inline constexpr Quantity + operator%(const Quantity& other) const { + return Quantity(value % other.value, unsafe); + } + + template + inline constexpr Quantity + operator*(UnitRatio ratio) const { + return Quantity( + value * ratio.unit1PerUnit2, unsafe); + } + template + inline constexpr Quantity + operator/(UnitRatio ratio) const { + return Quantity( + value / ratio.unit1PerUnit2, unsafe); + } + template + inline constexpr Quantity + operator%(UnitRatio ratio) const { + return Quantity( + value % ratio.unit1PerUnit2, unsafe); + } + template + inline constexpr UnitRatio + operator/(Quantity other) const { + return UnitRatio( + value / other.value, unsafe); + } + + template + inline constexpr bool operator==(const Quantity& other) const { + return value == other.value; + } + template + inline constexpr bool operator!=(const Quantity& other) const { + return value != other.value; + } + template + inline constexpr bool operator<=(const Quantity& other) const { + return value <= other.value; + } + template + inline constexpr bool operator>=(const Quantity& other) const { + return value >= other.value; + } + template + inline constexpr bool operator<(const Quantity& other) const { + return value < other.value; + } + template + inline constexpr bool operator>(const Quantity& other) const { + return value > other.value; + } + + template + inline Quantity& operator+=(const Quantity& other) { + value += other.value; + return *this; + } + template + inline Quantity& operator-=(const Quantity& other) { + value -= other.value; + return *this; + } + template + inline Quantity& operator*=(OtherNumber other) { + value *= other; + return *this; + } + template + inline Quantity& operator/=(OtherNumber other) { + value /= other.value; + return *this; + } + +private: + Number value; + + template + friend class Quantity; + + template + friend inline constexpr auto operator*(Number1 a, Quantity b) + -> Quantity; +}; + +template struct Unit_ { + static inline constexpr T get() { return T(1); } +}; +template +struct Unit_> { + static inline constexpr Quantity::get()), U> get() { + return Quantity::get()), U>(Unit_::get(), unsafe); + } +}; + +template +inline constexpr auto unit() -> decltype(Unit_::get()) { return Unit_::get(); } +// unit>() returns a Quantity of value 1. It also, intentionally, works on basic +// numeric types. + +template +inline constexpr auto operator*(Number1 a, Quantity b) + -> Quantity { + return Quantity(a * b.value, unsafe); +} + +template +inline constexpr auto operator*(UnitRatio ratio, + Quantity measure) + -> decltype(measure * ratio) { + return measure * ratio; +} + +// ======================================================================================= +// Absolute measures + +template +class Absolute { + // Wraps some other value -- typically a Quantity -- but represents a value measured based on + // some absolute origin. For example, if `Duration` is a type representing a time duration, + // Absolute might be a calendar date. + // + // Since Absolute represents measurements relative to some arbitrary origin, the only sensible + // arithmetic to perform on them is addition and subtraction. + + // TODO(someday): Do the same automatic expansion of integer width that Quantity does? Doesn't + // matter for our time use case, where we always use 64-bit anyway. Note that fixing this + // would implicitly allow things like multiplying an Absolute by a UnitRatio to change its + // units, which is actually totally logical and kind of neat. + +public: + inline constexpr Absolute operator+(const T& other) const { return Absolute(value + other); } + inline constexpr Absolute operator-(const T& other) const { return Absolute(value - other); } + inline constexpr T operator-(const Absolute& other) const { return value - other.value; } + + inline Absolute& operator+=(const T& other) { value += other; return *this; } + inline Absolute& operator-=(const T& other) { value -= other; return *this; } + + inline constexpr bool operator==(const Absolute& other) const { return value == other.value; } + inline constexpr bool operator!=(const Absolute& other) const { return value != other.value; } + inline constexpr bool operator<=(const Absolute& other) const { return value <= other.value; } + inline constexpr bool operator>=(const Absolute& other) const { return value >= other.value; } + inline constexpr bool operator< (const Absolute& other) const { return value < other.value; } + inline constexpr bool operator> (const Absolute& other) const { return value > other.value; } + +private: + T value; + + explicit constexpr Absolute(T value): value(value) {} + + template + friend inline constexpr U origin(); +}; + +template +inline constexpr Absolute operator+(const T& a, const Absolute& b) { + return b + a; +} + +template struct UnitOf_ { typedef T Type; }; +template struct UnitOf_> { typedef T Type; }; +template +using UnitOf = typename UnitOf_::Type; +// UnitOf> is T. UnitOf is AnythingElse. + +template +inline constexpr T origin() { return T(0 * unit>()); } +// origin>() returns an Absolute of value 0. It also, intentionally, works on basic +// numeric types. + +// ======================================================================================= +// Overflow avoidance + +template +struct BitCount_ { + static constexpr uint value = BitCount_<(n >> 1), accum + 1>::value; +}; +template +struct BitCount_<0, accum> { + static constexpr uint value = accum; +}; + +template +inline constexpr uint bitCount() { return BitCount_::value; } +// Number of bits required to represent the number `n`. + +template struct AtLeastUInt_ { + static_assert(bitCountBitCount < 7, "don't know how to represent integers over 64 bits"); +}; +template <> struct AtLeastUInt_<0> { typedef uint8_t Type; }; +template <> struct AtLeastUInt_<1> { typedef uint8_t Type; }; +template <> struct AtLeastUInt_<2> { typedef uint8_t Type; }; +template <> struct AtLeastUInt_<3> { typedef uint8_t Type; }; +template <> struct AtLeastUInt_<4> { typedef uint16_t Type; }; +template <> struct AtLeastUInt_<5> { typedef uint32_t Type; }; +template <> struct AtLeastUInt_<6> { typedef uint64_t Type; }; + +template +using AtLeastUInt = typename AtLeastUInt_()>::Type; +// AtLeastUInt is an unsigned integer of at least n bits. E.g. AtLeastUInt<12> is uint16_t. + +// ------------------------------------------------------------------- + +template +class BoundedConst { + // A constant integer value on which we can do bit size analysis. + +public: + BoundedConst() = default; + + inline constexpr uint unwrap() const { return value; } + +#define OP(op, check) \ + template \ + inline constexpr BoundedConst<(value op other)> \ + operator op(BoundedConst) const { \ + static_assert(check, "overflow in BoundedConst arithmetic"); \ + return BoundedConst<(value op other)>(); \ + } +#define COMPARE_OP(op) \ + template \ + inline constexpr bool operator op(BoundedConst) const { \ + return value op other; \ + } + + OP(+, value + other >= value) + OP(-, value - other <= value) + OP(*, value * other / other == value) + OP(/, true) // div by zero already errors out; no other division ever overflows + OP(%, true) // mod by zero already errors out; no other modulus ever overflows + OP(<<, value << other >= value) + OP(>>, true) // right shift can't overflow + OP(&, true) // bitwise ops can't overflow + OP(|, true) // bitwise ops can't overflow + + COMPARE_OP(==) + COMPARE_OP(!=) + COMPARE_OP(< ) + COMPARE_OP(> ) + COMPARE_OP(<=) + COMPARE_OP(>=) +#undef OP +#undef COMPARE_OP +}; + +template +struct Unit_> { + static inline constexpr BoundedConst<1> get() { return BoundedConst<1>(); } +}; + +template +struct Unit_> { + static inline constexpr BoundedConst<1> get() { return BoundedConst<1>(); } +}; + +template +inline constexpr BoundedConst bounded() { + return BoundedConst(); +} + +template +static constexpr uint64_t boundedAdd() { + static_assert(a + b >= a, "possible overflow detected"); + return a + b; +} +template +static constexpr uint64_t boundedSub() { + static_assert(a - b <= a, "possible underflow detected"); + return a - b; +} +template +static constexpr uint64_t boundedMul() { + static_assert(a * b / b == a, "possible overflow detected"); + return a * b; +} +template +static constexpr uint64_t boundedLShift() { + static_assert(a << b >= a, "possible overflow detected"); + return a << b; +} + +template +inline constexpr BoundedConst min(BoundedConst, BoundedConst) { + return bounded(); +} +template +inline constexpr BoundedConst max(BoundedConst, BoundedConst) { + return bounded(); +} +// We need to override min() and max() between constants because the ternary operator in the +// default implementation would complain. + +// ------------------------------------------------------------------- + +template +class Bounded { +public: + static_assert(maxN <= T(kj::maxValue), "possible overflow detected"); + + Bounded() = default; + + Bounded(const Bounded& other) = default; + template ()>> + inline constexpr Bounded(OtherInt value): value(value) { + static_assert(OtherInt(maxValue) <= maxN, "possible overflow detected"); + } + template + inline constexpr Bounded(const Bounded& other) + : value(other.value) { + static_assert(otherMax <= maxN, "possible overflow detected"); + } + template + inline constexpr Bounded(BoundedConst) + : value(otherValue) { + static_assert(otherValue <= maxN, "overflow detected"); + } + + Bounded& operator=(const Bounded& other) = default; + template ()>> + Bounded& operator=(OtherInt other) { + static_assert(OtherInt(maxValue) <= maxN, "possible overflow detected"); + value = other; + return *this; + } + template + inline Bounded& operator=(const Bounded& other) { + static_assert(otherMax <= maxN, "possible overflow detected"); + value = other.value; + return *this; + } + template + inline Bounded& operator=(BoundedConst) { + static_assert(otherValue <= maxN, "overflow detected"); + value = otherValue; + return *this; + } + + inline constexpr T unwrap() const { return value; } + +#define OP(op, newMax) \ + template \ + inline constexpr Bounded \ + operator op(const Bounded& other) const { \ + return Bounded(value op other.value, unsafe); \ + } +#define COMPARE_OP(op) \ + template \ + inline constexpr bool operator op(const Bounded& other) const { \ + return value op other.value; \ + } + + OP(+, (boundedAdd())) + OP(*, (boundedMul())) + OP(/, maxN) + OP(%, otherMax - 1) + + // operator- is intentionally omitted because we mostly use this with unsigned types, and + // subtraction requires proof that subtrahend is not greater than the minuend. + + COMPARE_OP(==) + COMPARE_OP(!=) + COMPARE_OP(< ) + COMPARE_OP(> ) + COMPARE_OP(<=) + COMPARE_OP(>=) + +#undef OP +#undef COMPARE_OP + + template + inline Bounded assertMax(ErrorFunc&& func) const { + // Assert that the number is no more than `newMax`. Otherwise, call `func`. + static_assert(newMax < maxN, "this bounded size assertion is redundant"); + if (KJ_UNLIKELY(value > newMax)) func(); + return Bounded(value, unsafe); + } + + template + inline Bounded subtractChecked( + const Bounded& other, ErrorFunc&& func) const { + // Subtract a number, calling func() if the result would underflow. + if (KJ_UNLIKELY(value < other.value)) func(); + return Bounded(value - other.value, unsafe); + } + + template + inline Bounded subtractChecked( + BoundedConst, ErrorFunc&& func) const { + // Subtract a number, calling func() if the result would underflow. + static_assert(otherValue <= maxN, "underflow detected"); + if (KJ_UNLIKELY(value < otherValue)) func(); + return Bounded(value - otherValue, unsafe); + } + + template + inline Maybe> trySubtract( + const Bounded& other) const { + // Subtract a number, calling func() if the result would underflow. + if (value < other.value) { + return nullptr; + } else { + return Bounded(value - other.value, unsafe); + } + } + + template + inline Maybe> trySubtract(BoundedConst) const { + // Subtract a number, calling func() if the result would underflow. + if (value < otherValue) { + return nullptr; + } else { + return Bounded(value - otherValue, unsafe); + } + } + + inline constexpr Bounded(T value, decltype(unsafe)): value(value) {} + template + inline constexpr Bounded(Bounded value, decltype(unsafe)) + : value(value.value) {} + // Mainly for internal use. + // + // Only use these as a last resort, with ample commentary on why you think it's safe. + +private: + T value; + + template + friend class Bounded; +}; + +template +inline constexpr Bounded bounded(Number value) { + return Bounded(value, unsafe); +} + +inline constexpr Bounded<1, uint8_t> bounded(bool value) { + return Bounded<1, uint8_t>(value, unsafe); +} + +template +inline constexpr Bounded(), Number> assumeBits(Number value) { + return Bounded(), Number>(value, unsafe); +} + +template +inline constexpr Bounded(), T> assumeBits(Bounded value) { + return Bounded(), T>(value, unsafe); +} + +template +inline constexpr auto assumeBits(Quantity value) + -> Quantity(value / unit>())), Unit> { + return Quantity(value / unit>())), Unit>( + assumeBits(value / unit>()), unsafe); +} + +template +inline constexpr Bounded assumeMax(Number value) { + return Bounded(value, unsafe); +} + +template +inline constexpr Bounded assumeMax(Bounded value) { + return Bounded(value, unsafe); +} + +template +inline constexpr auto assumeMax(Quantity value) + -> Quantity(value / unit>())), Unit> { + return Quantity(value / unit>())), Unit>( + assumeMax(value / unit>()), unsafe); +} + +template +inline constexpr Bounded assumeMax(BoundedConst, Number value) { + return assumeMax(value); +} + +template +inline constexpr Bounded assumeMax(BoundedConst, Bounded value) { + return assumeMax(value); +} + +template +inline constexpr auto assumeMax(Quantity, Unit>, Quantity value) + -> decltype(assumeMax(value)) { + return assumeMax(value); +} + +template +inline Bounded assertMax(Bounded value, ErrorFunc&& errorFunc) { + // Assert that the bounded value is less than or equal to the given maximum, calling errorFunc() + // if not. + static_assert(newMax < maxN, "this bounded size assertion is redundant"); + return value.template assertMax(kj::fwd(errorFunc)); +} + +template +inline Quantity, Unit> assertMax( + Quantity, Unit> value, ErrorFunc&& errorFunc) { + // Assert that the bounded value is less than or equal to the given maximum, calling errorFunc() + // if not. + static_assert(newMax < maxN, "this bounded size assertion is redundant"); + return (value / unit()).template assertMax( + kj::fwd(errorFunc)) * unit(); +} + +template +inline Bounded assertMax( + BoundedConst, Bounded value, ErrorFunc&& errorFunc) { + return assertMax(value, kj::mv(errorFunc)); +} + +template +inline Quantity, Unit> assertMax( + Quantity, Unit>, + Quantity, Unit> value, ErrorFunc&& errorFunc) { + return assertMax(value, kj::mv(errorFunc)); +} + +template +inline Bounded(), T> assertMaxBits( + Bounded value, ErrorFunc&& errorFunc = ErrorFunc()) { + // Assert that the bounded value requires no more than the given number of bits, calling + // errorFunc() if not. + return assertMax()>(value, kj::fwd(errorFunc)); +} + +template +inline Quantity(), T>, Unit> assertMaxBits( + Quantity, Unit> value, ErrorFunc&& errorFunc = ErrorFunc()) { + // Assert that the bounded value requires no more than the given number of bits, calling + // errorFunc() if not. + return assertMax()>(value, kj::fwd(errorFunc)); +} + +template +inline constexpr Bounded upgradeBound(Bounded value) { + return value; +} + +template +inline constexpr Quantity, Unit> upgradeBound( + Quantity, Unit> value) { + return value; +} + +template +inline auto subtractChecked(Bounded value, Other other, ErrorFunc&& errorFunc) + -> decltype(value.subtractChecked(other, kj::fwd(errorFunc))) { + return value.subtractChecked(other, kj::fwd(errorFunc)); +} + +template +inline auto subtractChecked(Quantity value, Quantity other, ErrorFunc&& errorFunc) + -> Quantity(errorFunc))), Unit> { + return subtractChecked(value / unit>(), + other / unit>(), + kj::fwd(errorFunc)) + * unit>(); +} + +template +inline auto trySubtract(Bounded value, Other other) + -> decltype(value.trySubtract(other)) { + return value.trySubtract(other); +} + +template +inline auto trySubtract(Quantity value, Quantity other) + -> Maybe> { + return trySubtract(value / unit>(), + other / unit>()) + .map([](decltype(subtractChecked(T(), U(), int())) x) { + return x * unit>(); + }); +} + +template +inline constexpr Bounded> +min(Bounded a, Bounded b) { + return Bounded>(kj::min(a.unwrap(), b.unwrap()), unsafe); +} +template +inline constexpr Bounded> +max(Bounded a, Bounded b) { + return Bounded>(kj::max(a.unwrap(), b.unwrap()), unsafe); +} +// We need to override min() and max() because: +// 1) WiderType<> might not choose the correct bounds. +// 2) One of the two sides of the ternary operator in the default implementation would fail to +// typecheck even though it is OK in practice. + +// ------------------------------------------------------------------- +// Operators between Bounded and BoundedConst + +#define OP(op, newMax) \ +template \ +inline constexpr Bounded<(newMax), decltype(T() op uint())> operator op( \ + Bounded value, BoundedConst) { \ + return Bounded<(newMax), decltype(T() op uint())>(value.unwrap() op cvalue, unsafe); \ +} + +#define REVERSE_OP(op, newMax) \ +template \ +inline constexpr Bounded<(newMax), decltype(uint() op T())> operator op( \ + BoundedConst, Bounded value) { \ + return Bounded<(newMax), decltype(uint() op T())>(cvalue op value.unwrap(), unsafe); \ +} + +#define COMPARE_OP(op) \ +template \ +inline constexpr bool operator op(Bounded value, BoundedConst) { \ + return value.unwrap() op cvalue; \ +} \ +template \ +inline constexpr bool operator op(BoundedConst, Bounded value) { \ + return cvalue op value.unwrap(); \ +} + +OP(+, (boundedAdd())) +REVERSE_OP(+, (boundedAdd())) + +OP(*, (boundedMul())) +REVERSE_OP(*, (boundedAdd())) + +OP(/, maxN / cvalue) +REVERSE_OP(/, cvalue) // denominator could be 1 + +OP(%, cvalue - 1) +REVERSE_OP(%, maxN - 1) + +OP(<<, (boundedLShift())) +REVERSE_OP(<<, (boundedLShift())) + +OP(>>, maxN >> cvalue) +REVERSE_OP(>>, cvalue >> maxN) + +OP(&, maxValueForBits()>() & cvalue) +REVERSE_OP(&, maxValueForBits()>() & cvalue) + +OP(|, maxN | cvalue) +REVERSE_OP(|, maxN | cvalue) + +COMPARE_OP(==) +COMPARE_OP(!=) +COMPARE_OP(< ) +COMPARE_OP(> ) +COMPARE_OP(<=) +COMPARE_OP(>=) + +#undef OP +#undef REVERSE_OP +#undef COMPARE_OP + +template +inline constexpr Bounded + operator-(BoundedConst, Bounded value) { + // We allow subtraction of a variable from a constant only if the constant is greater than or + // equal to the maximum possible value of the variable. Since the variable could be zero, the + // result can be as large as the constant. + // + // We do not allow subtraction of a constant from a variable because there's never a guarantee it + // won't underflow (unless the constant is zero, which is silly). + static_assert(cvalue >= maxN, "possible underflow detected"); + return Bounded(cvalue - value.unwrap(), unsafe); +} + +template +inline constexpr Bounded min(Bounded a, BoundedConst) { + return Bounded(kj::min(b, a.unwrap()), unsafe); +} +template +inline constexpr Bounded min(BoundedConst, Bounded a) { + return Bounded(kj::min(a.unwrap(), b), unsafe); +} +template +inline constexpr Bounded max(Bounded a, BoundedConst) { + return Bounded(kj::max(b, a.unwrap()), unsafe); +} +template +inline constexpr Bounded max(BoundedConst, Bounded a) { + return Bounded(kj::max(a.unwrap(), b), unsafe); +} +// We need to override min() between a Bounded and a constant since: +// 1) WiderType<> might choose BoundedConst over a 1-byte Bounded, which is wrong. +// 2) To clamp the bounds of the output type. +// 3) Same ternary operator typechecking issues. + +// ------------------------------------------------------------------- + +template +class SafeUnwrapper { +public: + inline explicit constexpr SafeUnwrapper(Bounded value): value(value.unwrap()) {} + + template ()>> + inline constexpr operator U() const { + static_assert(maxN <= U(maxValue), "possible truncation detected"); + return value; + } + + inline constexpr operator bool() const { + static_assert(maxN <= 1, "possible truncation detected"); + return value; + } + +private: + T value; +}; + +template +inline constexpr SafeUnwrapper unbound(Bounded bounded) { + // Unwraps the bounded value, returning a value that can be implicitly cast to any integer type. + // If this implicit cast could truncate, a compile-time error will be raised. + return SafeUnwrapper(bounded); +} + +template +class SafeConstUnwrapper { +public: + template ()>> + inline constexpr operator T() const { + static_assert(value <= T(maxValue), "this operation will truncate"); + return value; + } + + inline constexpr operator bool() const { + static_assert(value <= 1, "this operation will truncate"); + return value; + } +}; + +template +inline constexpr SafeConstUnwrapper unbound(BoundedConst) { + return SafeConstUnwrapper(); +} + +template +inline constexpr T unboundAs(U value) { + return unbound(value); +} + +template +inline constexpr T unboundMax(Bounded value) { + // Explicitly ungaurd expecting a value that is at most `maxN`. + static_assert(maxN <= requestedMax, "possible overflow detected"); + return value.unwrap(); +} + +template +inline constexpr uint unboundMax(BoundedConst) { + // Explicitly ungaurd expecting a value that is at most `maxN`. + static_assert(value <= requestedMax, "overflow detected"); + return value; +} + +template +inline constexpr auto unboundMaxBits(T value) -> + decltype(unboundMax()>(value)) { + // Explicitly ungaurd expecting a value that fits into `bits` bits. + return unboundMax()>(value); +} + +#define OP(op) \ +template \ +inline constexpr auto operator op(T a, SafeUnwrapper b) -> decltype(a op (T)b) { \ + return a op (AtLeastUInt)b; \ +} \ +template \ +inline constexpr auto operator op(SafeUnwrapper b, T a) -> decltype((T)b op a) { \ + return (AtLeastUInt)b op a; \ +} \ +template \ +inline constexpr auto operator op(T a, SafeConstUnwrapper b) -> decltype(a op (T)b) { \ + return a op (AtLeastUInt)b; \ +} \ +template \ +inline constexpr auto operator op(SafeConstUnwrapper b, T a) -> decltype((T)b op a) { \ + return (AtLeastUInt)b op a; \ +} + +OP(+) +OP(-) +OP(*) +OP(/) +OP(%) +OP(<<) +OP(>>) +OP(&) +OP(|) +OP(==) +OP(!=) +OP(<=) +OP(>=) +OP(<) +OP(>) + +#undef OP + +// ------------------------------------------------------------------- + +template +class Range> { +public: + inline constexpr Range(Bounded begin, Bounded end) + : inner(unbound(begin), unbound(end)) {} + inline explicit constexpr Range(Bounded end) + : inner(unbound(end)) {} + + class Iterator { + public: + Iterator() = default; + inline explicit Iterator(typename Range::Iterator inner): inner(inner) {} + + inline Bounded operator* () const { return Bounded(*inner, unsafe); } + inline Iterator& operator++() { ++inner; return *this; } + + inline bool operator==(const Iterator& other) const { return inner == other.inner; } + inline bool operator!=(const Iterator& other) const { return inner != other.inner; } + + private: + typename Range::Iterator inner; + }; + + inline Iterator begin() const { return Iterator(inner.begin()); } + inline Iterator end() const { return Iterator(inner.end()); } + +private: + Range inner; +}; + +template +class Range> { +public: + inline constexpr Range(Quantity begin, Quantity end) + : inner(begin / unit>(), end / unit>()) {} + inline explicit constexpr Range(Quantity end) + : inner(end / unit>()) {} + + class Iterator { + public: + Iterator() = default; + inline explicit Iterator(typename Range::Iterator inner): inner(inner) {} + + inline Quantity operator* () const { return *inner * unit>(); } + inline Iterator& operator++() { ++inner; return *this; } + + inline bool operator==(const Iterator& other) const { return inner == other.inner; } + inline bool operator!=(const Iterator& other) const { return inner != other.inner; } + + private: + typename Range::Iterator inner; + }; + + inline Iterator begin() const { return Iterator(inner.begin()); } + inline Iterator end() const { return Iterator(inner.end()); } + +private: + Range inner; +}; + +template +inline constexpr Range> zeroTo(BoundedConst end) { + return Range>(end); +} + +template +inline constexpr Range, Unit>> + zeroTo(Quantity, Unit> end) { + return Range, Unit>>(end); +} + +} // namespace kj + +#endif // KJ_UNITS_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/vector.h --- a/win32-mingw/include/kj/vector.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/vector.h Tue May 23 09:16:54 2017 +0100 @@ -1,145 +1,144 @@ -// 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. - -#ifndef KJ_VECTOR_H_ -#define KJ_VECTOR_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "array.h" - -namespace kj { - -template -class Vector { - // Similar to std::vector, but based on KJ framework. - // - // This implementation always uses move constructors when growing the backing array. If the - // move constructor throws, the Vector is left in an inconsistent state. This is acceptable - // under KJ exception theory which assumes that exceptions leave things in inconsistent states. - - // TODO(someday): Allow specifying a custom allocator. - -public: - inline Vector() = default; - inline explicit Vector(size_t capacity): builder(heapArrayBuilder(capacity)) {} - - inline operator ArrayPtr() { return builder; } - inline operator ArrayPtr() const { return builder; } - inline ArrayPtr asPtr() { return builder.asPtr(); } - inline ArrayPtr asPtr() const { return builder.asPtr(); } - - inline size_t size() const { return builder.size(); } - inline bool empty() const { return size() == 0; } - inline size_t capacity() const { return builder.capacity(); } - inline T& operator[](size_t index) const { return builder[index]; } - - inline const T* begin() const { return builder.begin(); } - inline const T* end() const { return builder.end(); } - inline const T& front() const { return builder.front(); } - inline const T& back() const { return builder.back(); } - inline T* begin() { return builder.begin(); } - inline T* end() { return builder.end(); } - inline T& front() { return builder.front(); } - inline T& back() { return builder.back(); } - - inline Array releaseAsArray() { - // TODO(perf): Avoid a copy/move by allowing Array to point to incomplete space? - if (!builder.isFull()) { - setCapacity(size()); - } - return builder.finish(); - } - - template - inline T& add(Params&&... params) { - if (builder.isFull()) grow(); - return builder.add(kj::fwd(params)...); - } - - template - inline void addAll(Iterator begin, Iterator end) { - size_t needed = builder.size() + (end - begin); - if (needed > builder.capacity()) grow(needed); - builder.addAll(begin, end); - } - - template - inline void addAll(Container&& container) { - addAll(container.begin(), container.end()); - } - - inline void removeLast() { - builder.removeLast(); - } - - inline void resize(size_t size) { - if (size > builder.capacity()) grow(size); - while (builder.size() < size) { - builder.add(T()); - } - while (builder.size() > size) { - builder.removeLast(); - } - } - - inline void operator=(decltype(nullptr)) { - builder = nullptr; - } - - inline void clear() { - while (builder.size() > 0) { - builder.removeLast(); - } - } - - inline void truncate(size_t size) { - while (builder.size() > size) { - builder.removeLast(); - } - } - -private: - ArrayBuilder builder; - - void grow(size_t minCapacity = 0) { - setCapacity(kj::max(minCapacity, capacity() == 0 ? 4 : capacity() * 2)); - } - void setCapacity(size_t newSize) { - ArrayBuilder newBuilder = heapArrayBuilder(newSize); - size_t moveCount = kj::min(newSize, builder.size()); - for (size_t i = 0; i < moveCount; i++) { - newBuilder.add(kj::mv(builder[i])); - } - builder = kj::mv(newBuilder); - } -}; - -template -inline auto KJ_STRINGIFY(const Vector& v) -> decltype(toCharSequence(v.asPtr())) { - return toCharSequence(v.asPtr()); -} - -} // namespace kj - -#endif // KJ_VECTOR_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. + +#ifndef KJ_VECTOR_H_ +#define KJ_VECTOR_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "array.h" + +namespace kj { + +template +class Vector { + // Similar to std::vector, but based on KJ framework. + // + // This implementation always uses move constructors when growing the backing array. If the + // move constructor throws, the Vector is left in an inconsistent state. This is acceptable + // under KJ exception theory which assumes that exceptions leave things in inconsistent states. + + // TODO(someday): Allow specifying a custom allocator. + +public: + inline Vector() = default; + inline explicit Vector(size_t capacity): builder(heapArrayBuilder(capacity)) {} + + inline operator ArrayPtr() { return builder; } + inline operator ArrayPtr() const { return builder; } + inline ArrayPtr asPtr() { return builder.asPtr(); } + inline ArrayPtr asPtr() const { return builder.asPtr(); } + + inline size_t size() const { return builder.size(); } + inline bool empty() const { return size() == 0; } + inline size_t capacity() const { return builder.capacity(); } + inline T& operator[](size_t index) const { return builder[index]; } + + inline const T* begin() const { return builder.begin(); } + inline const T* end() const { return builder.end(); } + inline const T& front() const { return builder.front(); } + inline const T& back() const { return builder.back(); } + inline T* begin() { return builder.begin(); } + inline T* end() { return builder.end(); } + inline T& front() { return builder.front(); } + inline T& back() { return builder.back(); } + + inline Array releaseAsArray() { + // TODO(perf): Avoid a copy/move by allowing Array to point to incomplete space? + if (!builder.isFull()) { + setCapacity(size()); + } + return builder.finish(); + } + + template + inline T& add(Params&&... params) { + if (builder.isFull()) grow(); + return builder.add(kj::fwd(params)...); + } + + template + inline void addAll(Iterator begin, Iterator end) { + size_t needed = builder.size() + (end - begin); + if (needed > builder.capacity()) grow(needed); + builder.addAll(begin, end); + } + + template + inline void addAll(Container&& container) { + addAll(container.begin(), container.end()); + } + + inline void removeLast() { + builder.removeLast(); + } + + inline void resize(size_t size) { + if (size > builder.capacity()) grow(size); + builder.resize(size); + } + + inline void operator=(decltype(nullptr)) { + builder = nullptr; + } + + inline void clear() { + while (builder.size() > 0) { + builder.removeLast(); + } + } + + inline void truncate(size_t size) { + builder.truncate(size); + } + + inline void reserve(size_t size) { + if (size > builder.capacity()) { + setCapacity(size); + } + } + +private: + ArrayBuilder builder; + + void grow(size_t minCapacity = 0) { + setCapacity(kj::max(minCapacity, capacity() == 0 ? 4 : capacity() * 2)); + } + void setCapacity(size_t newSize) { + if (builder.size() > newSize) { + builder.truncate(newSize); + } + ArrayBuilder newBuilder = heapArrayBuilder(newSize); + newBuilder.addAll(kj::mv(builder)); + builder = kj::mv(newBuilder); + } +}; + +template +inline auto KJ_STRINGIFY(const Vector& v) -> decltype(toCharSequence(v.asPtr())) { + return toCharSequence(v.asPtr()); +} + +} // namespace kj + +#endif // KJ_VECTOR_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/include/kj/windows-sanity.h --- a/win32-mingw/include/kj/windows-sanity.h Mon May 22 18:56:49 2017 +0100 +++ b/win32-mingw/include/kj/windows-sanity.h Tue May 23 09:16:54 2017 +0100 @@ -1,41 +1,41 @@ -// 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. - -#ifndef KJ_WINDOWS_SANITY_H_ -#define KJ_WINDOWS_SANITY_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#ifndef _INC_WINDOWS -#error "windows.h needs to be included before kj/windows-sanity.h (or perhaps you don't need either?)" -#endif - -namespace win32 { - const auto ERROR_ = ERROR; -#undef ERROR - const auto ERROR = ERROR_; -} - -using win32::ERROR; - -#endif // KJ_WINDOWS_SANITY_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. + +#ifndef KJ_WINDOWS_SANITY_H_ +#define KJ_WINDOWS_SANITY_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#ifndef _INC_WINDOWS +#error "windows.h needs to be included before kj/windows-sanity.h (or perhaps you don't need either?)" +#endif + +namespace win32 { + const auto ERROR_ = ERROR; +#undef ERROR + const auto ERROR = ERROR_; +} + +using win32::ERROR; + +#endif // KJ_WINDOWS_SANITY_H_ diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/lib/libcapnp.a Binary file win32-mingw/lib/libcapnp.a has changed diff -r b4bfdf10c4b3 -r 279b18cc7785 win32-mingw/lib/libkj.a Binary file win32-mingw/lib/libkj.a has changed diff -r b4bfdf10c4b3 -r 279b18cc7785 win64-msvc/bin/capnp.exe Binary file win64-msvc/bin/capnp.exe has changed diff -r b4bfdf10c4b3 -r 279b18cc7785 win64-msvc/bin/capnpc-c++.exe Binary file win64-msvc/bin/capnpc-c++.exe has changed diff -r b4bfdf10c4b3 -r 279b18cc7785 win64-msvc/bin/capnpc-capnp.exe Binary file win64-msvc/bin/capnpc-capnp.exe has changed