annotate win64-msvc/include/capnp/any.h @ 166:cbd6d7e562c7

Merge build update
author Chris Cannam <cannam@all-day-breakfast.com>
date Thu, 31 Oct 2019 13:36:58 +0000
parents b4bfdf10c4b3
children
rev   line source
cannam@148 1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
cannam@148 2 // Licensed under the MIT License:
cannam@148 3 //
cannam@148 4 // Permission is hereby granted, free of charge, to any person obtaining a copy
cannam@148 5 // of this software and associated documentation files (the "Software"), to deal
cannam@148 6 // in the Software without restriction, including without limitation the rights
cannam@148 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
cannam@148 8 // copies of the Software, and to permit persons to whom the Software is
cannam@148 9 // furnished to do so, subject to the following conditions:
cannam@148 10 //
cannam@148 11 // The above copyright notice and this permission notice shall be included in
cannam@148 12 // all copies or substantial portions of the Software.
cannam@148 13 //
cannam@148 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
cannam@148 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
cannam@148 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
cannam@148 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
cannam@148 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
cannam@148 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
cannam@148 20 // THE SOFTWARE.
cannam@148 21
cannam@148 22 #ifndef CAPNP_ANY_H_
cannam@148 23 #define CAPNP_ANY_H_
cannam@148 24
cannam@148 25 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
cannam@148 26 #pragma GCC system_header
cannam@148 27 #endif
cannam@148 28
cannam@148 29 #include "layout.h"
cannam@148 30 #include "pointer-helpers.h"
cannam@148 31 #include "orphan.h"
cannam@148 32 #include "list.h"
cannam@148 33
cannam@148 34 namespace capnp {
cannam@148 35
cannam@148 36 class StructSchema;
cannam@148 37 class ListSchema;
cannam@148 38 class InterfaceSchema;
cannam@148 39 class Orphanage;
cannam@148 40 class ClientHook;
cannam@148 41 class PipelineHook;
cannam@148 42 struct PipelineOp;
cannam@148 43 struct AnyPointer;
cannam@148 44
cannam@148 45 struct AnyList {
cannam@148 46 AnyList() = delete;
cannam@148 47
cannam@148 48 class Reader;
cannam@148 49 class Builder;
cannam@148 50 };
cannam@148 51
cannam@148 52 struct AnyStruct {
cannam@148 53 AnyStruct() = delete;
cannam@148 54
cannam@148 55 class Reader;
cannam@148 56 class Builder;
cannam@148 57 class Pipeline;
cannam@148 58 };
cannam@148 59
cannam@148 60 template<>
cannam@148 61 struct List<AnyStruct, Kind::OTHER> {
cannam@148 62 List() = delete;
cannam@148 63
cannam@148 64 class Reader;
cannam@148 65 class Builder;
cannam@148 66 };
cannam@148 67
cannam@148 68 namespace _ { // private
cannam@148 69 template <> struct Kind_<AnyPointer> { static constexpr Kind kind = Kind::OTHER; };
cannam@148 70 template <> struct Kind_<AnyStruct> { static constexpr Kind kind = Kind::OTHER; };
cannam@148 71 template <> struct Kind_<AnyList> { static constexpr Kind kind = Kind::OTHER; };
cannam@148 72 } // namespace _ (private)
cannam@148 73
cannam@148 74 // =======================================================================================
cannam@148 75 // AnyPointer!
cannam@148 76
cannam@148 77 enum class Equality {
cannam@148 78 NOT_EQUAL,
cannam@148 79 EQUAL,
cannam@148 80 UNKNOWN_CONTAINS_CAPS
cannam@148 81 };
cannam@148 82
cannam@148 83 kj::StringPtr KJ_STRINGIFY(Equality res);
cannam@148 84
cannam@148 85 struct AnyPointer {
cannam@148 86 // Reader/Builder for the `AnyPointer` field type, i.e. a pointer that can point to an arbitrary
cannam@148 87 // object.
cannam@148 88
cannam@148 89 AnyPointer() = delete;
cannam@148 90
cannam@148 91 class Reader {
cannam@148 92 public:
cannam@148 93 typedef AnyPointer Reads;
cannam@148 94
cannam@148 95 Reader() = default;
cannam@148 96 inline Reader(_::PointerReader reader): reader(reader) {}
cannam@148 97
cannam@148 98 inline MessageSize targetSize() const;
cannam@148 99 // Get the total size of the target object and all its children.
cannam@148 100
cannam@148 101 inline PointerType getPointerType() const;
cannam@148 102
cannam@148 103 inline bool isNull() const { return getPointerType() == PointerType::NULL_; }
cannam@148 104 inline bool isStruct() const { return getPointerType() == PointerType::STRUCT; }
cannam@148 105 inline bool isList() const { return getPointerType() == PointerType::LIST; }
cannam@148 106 inline bool isCapability() const { return getPointerType() == PointerType::CAPABILITY; }
cannam@148 107
cannam@148 108 Equality equals(AnyPointer::Reader right);
cannam@148 109 bool operator==(AnyPointer::Reader right);
cannam@148 110 inline bool operator!=(AnyPointer::Reader right) {
cannam@148 111 return !(*this == right);
cannam@148 112 }
cannam@148 113
cannam@148 114 template <typename T>
cannam@148 115 inline ReaderFor<T> getAs() const;
cannam@148 116 // Valid for T = any generated struct type, interface type, List<U>, Text, or Data.
cannam@148 117
cannam@148 118 template <typename T>
cannam@148 119 inline ReaderFor<T> getAs(StructSchema schema) const;
cannam@148 120 // Only valid for T = DynamicStruct. Requires `#include <capnp/dynamic.h>`.
cannam@148 121
cannam@148 122 template <typename T>
cannam@148 123 inline ReaderFor<T> getAs(ListSchema schema) const;
cannam@148 124 // Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
cannam@148 125
cannam@148 126 template <typename T>
cannam@148 127 inline ReaderFor<T> getAs(InterfaceSchema schema) const;
cannam@148 128 // Only valid for T = DynamicCapability. Requires `#include <capnp/dynamic.h>`.
cannam@148 129
cannam@148 130 #if !CAPNP_LITE
cannam@148 131 kj::Own<ClientHook> getPipelinedCap(kj::ArrayPtr<const PipelineOp> ops) const;
cannam@148 132 // Used by RPC system to implement pipelining. Applications generally shouldn't use this
cannam@148 133 // directly.
cannam@148 134 #endif // !CAPNP_LITE
cannam@148 135
cannam@148 136 private:
cannam@148 137 _::PointerReader reader;
cannam@148 138 friend struct AnyPointer;
cannam@148 139 friend class Orphanage;
cannam@148 140 friend class CapReaderContext;
cannam@148 141 friend struct _::PointerHelpers<AnyPointer>;
cannam@148 142 };
cannam@148 143
cannam@148 144 class Builder {
cannam@148 145 public:
cannam@148 146 typedef AnyPointer Builds;
cannam@148 147
cannam@148 148 Builder() = delete;
cannam@148 149 inline Builder(decltype(nullptr)) {}
cannam@148 150 inline Builder(_::PointerBuilder builder): builder(builder) {}
cannam@148 151
cannam@148 152 inline MessageSize targetSize() const;
cannam@148 153 // Get the total size of the target object and all its children.
cannam@148 154
cannam@148 155 inline PointerType getPointerType();
cannam@148 156
cannam@148 157 inline bool isNull() { return getPointerType() == PointerType::NULL_; }
cannam@148 158 inline bool isStruct() { return getPointerType() == PointerType::STRUCT; }
cannam@148 159 inline bool isList() { return getPointerType() == PointerType::LIST; }
cannam@148 160 inline bool isCapability() { return getPointerType() == PointerType::CAPABILITY; }
cannam@148 161
cannam@148 162 inline Equality equals(AnyPointer::Reader right) {
cannam@148 163 return asReader().equals(right);
cannam@148 164 }
cannam@148 165 inline bool operator==(AnyPointer::Reader right) {
cannam@148 166 return asReader() == right;
cannam@148 167 }
cannam@148 168 inline bool operator!=(AnyPointer::Reader right) {
cannam@148 169 return !(*this == right);
cannam@148 170 }
cannam@148 171
cannam@148 172 inline void clear();
cannam@148 173 // Set to null.
cannam@148 174
cannam@148 175 template <typename T>
cannam@148 176 inline BuilderFor<T> getAs();
cannam@148 177 // Valid for T = any generated struct type, List<U>, Text, or Data.
cannam@148 178
cannam@148 179 template <typename T>
cannam@148 180 inline BuilderFor<T> getAs(StructSchema schema);
cannam@148 181 // Only valid for T = DynamicStruct. Requires `#include <capnp/dynamic.h>`.
cannam@148 182
cannam@148 183 template <typename T>
cannam@148 184 inline BuilderFor<T> getAs(ListSchema schema);
cannam@148 185 // Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
cannam@148 186
cannam@148 187 template <typename T>
cannam@148 188 inline BuilderFor<T> getAs(InterfaceSchema schema);
cannam@148 189 // Only valid for T = DynamicCapability. Requires `#include <capnp/dynamic.h>`.
cannam@148 190
cannam@148 191 template <typename T>
cannam@148 192 inline BuilderFor<T> initAs();
cannam@148 193 // Valid for T = any generated struct type.
cannam@148 194
cannam@148 195 template <typename T>
cannam@148 196 inline BuilderFor<T> initAs(uint elementCount);
cannam@148 197 // Valid for T = List<U>, Text, or Data.
cannam@148 198
cannam@148 199 template <typename T>
cannam@148 200 inline BuilderFor<T> initAs(StructSchema schema);
cannam@148 201 // Only valid for T = DynamicStruct. Requires `#include <capnp/dynamic.h>`.
cannam@148 202
cannam@148 203 template <typename T>
cannam@148 204 inline BuilderFor<T> initAs(ListSchema schema, uint elementCount);
cannam@148 205 // Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
cannam@148 206
cannam@148 207 inline AnyList::Builder initAsAnyList(ElementSize elementSize, uint elementCount);
cannam@148 208 // Note: Does not accept INLINE_COMPOSITE for elementSize.
cannam@148 209
cannam@148 210 inline List<AnyStruct>::Builder initAsListOfAnyStruct(
cannam@148 211 uint16_t dataWordCount, uint16_t pointerCount, uint elementCount);
cannam@148 212
cannam@148 213 inline AnyStruct::Builder initAsAnyStruct(uint16_t dataWordCount, uint16_t pointerCount);
cannam@148 214
cannam@148 215 template <typename T>
cannam@148 216 inline void setAs(ReaderFor<T> value);
cannam@148 217 // Valid for ReaderType = T::Reader for T = any generated struct type, List<U>, Text, Data,
cannam@148 218 // DynamicStruct, or DynamicList (the dynamic types require `#include <capnp/dynamic.h>`).
cannam@148 219
cannam@148 220 template <typename T>
cannam@148 221 inline void setAs(std::initializer_list<ReaderFor<ListElementType<T>>> list);
cannam@148 222 // Valid for T = List<?>.
cannam@148 223
cannam@148 224 template <typename T>
cannam@148 225 inline void setCanonicalAs(ReaderFor<T> value);
cannam@148 226
cannam@148 227 inline void set(Reader value) { builder.copyFrom(value.reader); }
cannam@148 228 // Set to a copy of another AnyPointer.
cannam@148 229
cannam@148 230 inline void setCanonical(Reader value) { builder.copyFrom(value.reader, true); }
cannam@148 231
cannam@148 232 template <typename T>
cannam@148 233 inline void adopt(Orphan<T>&& orphan);
cannam@148 234 // Valid for T = any generated struct type, List<U>, Text, Data, DynamicList, DynamicStruct,
cannam@148 235 // or DynamicValue (the dynamic types require `#include <capnp/dynamic.h>`).
cannam@148 236
cannam@148 237 template <typename T>
cannam@148 238 inline Orphan<T> disownAs();
cannam@148 239 // Valid for T = any generated struct type, List<U>, Text, Data.
cannam@148 240
cannam@148 241 template <typename T>
cannam@148 242 inline Orphan<T> disownAs(StructSchema schema);
cannam@148 243 // Only valid for T = DynamicStruct. Requires `#include <capnp/dynamic.h>`.
cannam@148 244
cannam@148 245 template <typename T>
cannam@148 246 inline Orphan<T> disownAs(ListSchema schema);
cannam@148 247 // Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`.
cannam@148 248
cannam@148 249 template <typename T>
cannam@148 250 inline Orphan<T> disownAs(InterfaceSchema schema);
cannam@148 251 // Only valid for T = DynamicCapability. Requires `#include <capnp/dynamic.h>`.
cannam@148 252
cannam@148 253 inline Orphan<AnyPointer> disown();
cannam@148 254 // Disown without a type.
cannam@148 255
cannam@148 256 inline Reader asReader() const { return Reader(builder.asReader()); }
cannam@148 257 inline operator Reader() const { return Reader(builder.asReader()); }
cannam@148 258
cannam@148 259 private:
cannam@148 260 _::PointerBuilder builder;
cannam@148 261 friend class Orphanage;
cannam@148 262 friend class CapBuilderContext;
cannam@148 263 friend struct _::PointerHelpers<AnyPointer>;
cannam@148 264 };
cannam@148 265
cannam@148 266 #if !CAPNP_LITE
cannam@148 267 class Pipeline {
cannam@148 268 public:
cannam@148 269 typedef AnyPointer Pipelines;
cannam@148 270
cannam@148 271 inline Pipeline(decltype(nullptr)) {}
cannam@148 272 inline explicit Pipeline(kj::Own<PipelineHook>&& hook): hook(kj::mv(hook)) {}
cannam@148 273
cannam@148 274 Pipeline noop();
cannam@148 275 // Just make a copy.
cannam@148 276
cannam@148 277 Pipeline getPointerField(uint16_t pointerIndex);
cannam@148 278 // Deprecated. In the future, we should use .asAnyStruct.getPointerField.
cannam@148 279
cannam@148 280 inline AnyStruct::Pipeline asAnyStruct();
cannam@148 281
cannam@148 282 kj::Own<ClientHook> asCap();
cannam@148 283 // Expect that the result is a capability and construct a pipelined version of it now.
cannam@148 284
cannam@148 285 inline kj::Own<PipelineHook> releasePipelineHook() { return kj::mv(hook); }
cannam@148 286 // For use by RPC implementations.
cannam@148 287
cannam@148 288 template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromClient<T>) == Kind::INTERFACE>>
cannam@148 289 inline operator T() { return T(asCap()); }
cannam@148 290
cannam@148 291 private:
cannam@148 292 kj::Own<PipelineHook> hook;
cannam@148 293 kj::Array<PipelineOp> ops;
cannam@148 294
cannam@148 295 inline Pipeline(kj::Own<PipelineHook>&& hook, kj::Array<PipelineOp>&& ops)
cannam@148 296 : hook(kj::mv(hook)), ops(kj::mv(ops)) {}
cannam@148 297
cannam@148 298 friend class LocalClient;
cannam@148 299 friend class PipelineHook;
cannam@148 300 friend class AnyStruct::Pipeline;
cannam@148 301 };
cannam@148 302 #endif // !CAPNP_LITE
cannam@148 303 };
cannam@148 304
cannam@148 305 template <>
cannam@148 306 class Orphan<AnyPointer> {
cannam@148 307 // An orphaned object of unknown type.
cannam@148 308
cannam@148 309 public:
cannam@148 310 Orphan() = default;
cannam@148 311 KJ_DISALLOW_COPY(Orphan);
cannam@148 312 Orphan(Orphan&&) = default;
cannam@148 313 inline Orphan(_::OrphanBuilder&& builder)
cannam@148 314 : builder(kj::mv(builder)) {}
cannam@148 315
cannam@148 316 Orphan& operator=(Orphan&&) = default;
cannam@148 317
cannam@148 318 template <typename T>
cannam@148 319 inline Orphan(Orphan<T>&& other): builder(kj::mv(other.builder)) {}
cannam@148 320 template <typename T>
cannam@148 321 inline Orphan& operator=(Orphan<T>&& other) { builder = kj::mv(other.builder); return *this; }
cannam@148 322 // Cast from typed orphan.
cannam@148 323
cannam@148 324 // It's not possible to get an AnyPointer::{Reader,Builder} directly since there is no
cannam@148 325 // underlying pointer (the pointer would normally live in the parent, but this object is
cannam@148 326 // orphaned). It is possible, however, to request typed readers/builders.
cannam@148 327
cannam@148 328 template <typename T>
cannam@148 329 inline BuilderFor<T> getAs();
cannam@148 330 template <typename T>
cannam@148 331 inline BuilderFor<T> getAs(StructSchema schema);
cannam@148 332 template <typename T>
cannam@148 333 inline BuilderFor<T> getAs(ListSchema schema);
cannam@148 334 template <typename T>
cannam@148 335 inline typename T::Client getAs(InterfaceSchema schema);
cannam@148 336 template <typename T>
cannam@148 337 inline ReaderFor<T> getAsReader() const;
cannam@148 338 template <typename T>
cannam@148 339 inline ReaderFor<T> getAsReader(StructSchema schema) const;
cannam@148 340 template <typename T>
cannam@148 341 inline ReaderFor<T> getAsReader(ListSchema schema) const;
cannam@148 342 template <typename T>
cannam@148 343 inline typename T::Client getAsReader(InterfaceSchema schema) const;
cannam@148 344
cannam@148 345 template <typename T>
cannam@148 346 inline Orphan<T> releaseAs();
cannam@148 347 template <typename T>
cannam@148 348 inline Orphan<T> releaseAs(StructSchema schema);
cannam@148 349 template <typename T>
cannam@148 350 inline Orphan<T> releaseAs(ListSchema schema);
cannam@148 351 template <typename T>
cannam@148 352 inline Orphan<T> releaseAs(InterfaceSchema schema);
cannam@148 353 // Down-cast the orphan to a specific type.
cannam@148 354
cannam@148 355 inline bool operator==(decltype(nullptr)) const { return builder == nullptr; }
cannam@148 356 inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; }
cannam@148 357
cannam@148 358 private:
cannam@148 359 _::OrphanBuilder builder;
cannam@148 360
cannam@148 361 template <typename, Kind>
cannam@148 362 friend struct _::PointerHelpers;
cannam@148 363 friend class Orphanage;
cannam@148 364 template <typename U>
cannam@148 365 friend class Orphan;
cannam@148 366 friend class AnyPointer::Builder;
cannam@148 367 };
cannam@148 368
cannam@148 369 template <Kind k> struct AnyTypeFor_;
cannam@148 370 template <> struct AnyTypeFor_<Kind::STRUCT> { typedef AnyStruct Type; };
cannam@148 371 template <> struct AnyTypeFor_<Kind::LIST> { typedef AnyList Type; };
cannam@148 372
cannam@148 373 template <typename T>
cannam@148 374 using AnyTypeFor = typename AnyTypeFor_<CAPNP_KIND(T)>::Type;
cannam@148 375
cannam@148 376 template <typename T>
cannam@148 377 inline ReaderFor<AnyTypeFor<FromReader<T>>> toAny(T&& value) {
cannam@148 378 return ReaderFor<AnyTypeFor<FromReader<T>>>(
cannam@148 379 _::PointerHelpers<FromReader<T>>::getInternalReader(value));
cannam@148 380 }
cannam@148 381 template <typename T>
cannam@148 382 inline BuilderFor<AnyTypeFor<FromBuilder<T>>> toAny(T&& value) {
cannam@148 383 return BuilderFor<AnyTypeFor<FromBuilder<T>>>(
cannam@148 384 _::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::mv(value)));
cannam@148 385 }
cannam@148 386
cannam@148 387 template <>
cannam@148 388 struct List<AnyPointer, Kind::OTHER> {
cannam@148 389 // Note: This cannot be used for a list of structs, since such lists are not encoded as pointer
cannam@148 390 // lists! Use List<AnyStruct>.
cannam@148 391
cannam@148 392 List() = delete;
cannam@148 393
cannam@148 394 class Reader {
cannam@148 395 public:
cannam@148 396 typedef List<AnyPointer> Reads;
cannam@148 397
cannam@148 398 inline Reader(): reader(ElementSize::POINTER) {}
cannam@148 399 inline explicit Reader(_::ListReader reader): reader(reader) {}
cannam@148 400
cannam@148 401 inline uint size() const { return unbound(reader.size() / ELEMENTS); }
cannam@148 402 inline AnyPointer::Reader operator[](uint index) const {
cannam@148 403 KJ_IREQUIRE(index < size());
cannam@148 404 return AnyPointer::Reader(reader.getPointerElement(bounded(index) * ELEMENTS));
cannam@148 405 }
cannam@148 406
cannam@148 407 typedef _::IndexingIterator<const Reader, typename AnyPointer::Reader> Iterator;
cannam@148 408 inline Iterator begin() const { return Iterator(this, 0); }
cannam@148 409 inline Iterator end() const { return Iterator(this, size()); }
cannam@148 410
cannam@148 411 private:
cannam@148 412 _::ListReader reader;
cannam@148 413 template <typename U, Kind K>
cannam@148 414 friend struct _::PointerHelpers;
cannam@148 415 template <typename U, Kind K>
cannam@148 416 friend struct List;
cannam@148 417 friend class Orphanage;
cannam@148 418 template <typename U, Kind K>
cannam@148 419 friend struct ToDynamic_;
cannam@148 420 };
cannam@148 421
cannam@148 422 class Builder {
cannam@148 423 public:
cannam@148 424 typedef List<AnyPointer> Builds;
cannam@148 425
cannam@148 426 Builder() = delete;
cannam@148 427 inline Builder(decltype(nullptr)): builder(ElementSize::POINTER) {}
cannam@148 428 inline explicit Builder(_::ListBuilder builder): builder(builder) {}
cannam@148 429
cannam@148 430 inline operator Reader() const { return Reader(builder.asReader()); }
cannam@148 431 inline Reader asReader() const { return Reader(builder.asReader()); }
cannam@148 432
cannam@148 433 inline uint size() const { return unbound(builder.size() / ELEMENTS); }
cannam@148 434 inline AnyPointer::Builder operator[](uint index) {
cannam@148 435 KJ_IREQUIRE(index < size());
cannam@148 436 return AnyPointer::Builder(builder.getPointerElement(bounded(index) * ELEMENTS));
cannam@148 437 }
cannam@148 438
cannam@148 439 typedef _::IndexingIterator<Builder, typename AnyPointer::Builder> Iterator;
cannam@148 440 inline Iterator begin() { return Iterator(this, 0); }
cannam@148 441 inline Iterator end() { return Iterator(this, size()); }
cannam@148 442
cannam@148 443 private:
cannam@148 444 _::ListBuilder builder;
cannam@148 445 template <typename, Kind>
cannam@148 446 friend struct _::PointerHelpers;
cannam@148 447 friend class Orphanage;
cannam@148 448 template <typename, Kind>
cannam@148 449 friend struct ToDynamic_;
cannam@148 450 };
cannam@148 451 };
cannam@148 452
cannam@148 453 class AnyStruct::Reader {
cannam@148 454 public:
cannam@148 455 typedef AnyStruct Reads;
cannam@148 456
cannam@148 457 Reader() = default;
cannam@148 458 inline Reader(_::StructReader reader): _reader(reader) {}
cannam@148 459
cannam@148 460 template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromReader<T>) == Kind::STRUCT>>
cannam@148 461 inline Reader(T&& value)
cannam@148 462 : _reader(_::PointerHelpers<FromReader<T>>::getInternalReader(kj::fwd<T>(value))) {}
cannam@148 463
cannam@148 464 kj::ArrayPtr<const byte> getDataSection() {
cannam@148 465 return _reader.getDataSectionAsBlob();
cannam@148 466 }
cannam@148 467 List<AnyPointer>::Reader getPointerSection() {
cannam@148 468 return List<AnyPointer>::Reader(_reader.getPointerSectionAsList());
cannam@148 469 }
cannam@148 470
cannam@148 471 kj::Array<word> canonicalize() {
cannam@148 472 return _reader.canonicalize();
cannam@148 473 }
cannam@148 474
cannam@148 475 Equality equals(AnyStruct::Reader right);
cannam@148 476 bool operator==(AnyStruct::Reader right);
cannam@148 477 inline bool operator!=(AnyStruct::Reader right) {
cannam@148 478 return !(*this == right);
cannam@148 479 }
cannam@148 480
cannam@148 481 template <typename T>
cannam@148 482 ReaderFor<T> as() const {
cannam@148 483 // T must be a struct type.
cannam@148 484 return typename T::Reader(_reader);
cannam@148 485 }
cannam@148 486 private:
cannam@148 487 _::StructReader _reader;
cannam@148 488
cannam@148 489 template <typename, Kind>
cannam@148 490 friend struct _::PointerHelpers;
cannam@148 491 friend class Orphanage;
cannam@148 492 };
cannam@148 493
cannam@148 494 class AnyStruct::Builder {
cannam@148 495 public:
cannam@148 496 typedef AnyStruct Builds;
cannam@148 497
cannam@148 498 inline Builder(decltype(nullptr)) {}
cannam@148 499 inline Builder(_::StructBuilder builder): _builder(builder) {}
cannam@148 500
cannam@148 501 #if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves.
cannam@148 502 template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromBuilder<T>) == Kind::STRUCT>>
cannam@148 503 inline Builder(T&& value)
cannam@148 504 : _builder(_::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::fwd<T>(value))) {}
cannam@148 505 #endif
cannam@148 506
cannam@148 507 inline kj::ArrayPtr<byte> getDataSection() {
cannam@148 508 return _builder.getDataSectionAsBlob();
cannam@148 509 }
cannam@148 510 List<AnyPointer>::Builder getPointerSection() {
cannam@148 511 return List<AnyPointer>::Builder(_builder.getPointerSectionAsList());
cannam@148 512 }
cannam@148 513
cannam@148 514 inline Equality equals(AnyStruct::Reader right) {
cannam@148 515 return asReader().equals(right);
cannam@148 516 }
cannam@148 517 inline bool operator==(AnyStruct::Reader right) {
cannam@148 518 return asReader() == right;
cannam@148 519 }
cannam@148 520 inline bool operator!=(AnyStruct::Reader right) {
cannam@148 521 return !(*this == right);
cannam@148 522 }
cannam@148 523
cannam@148 524 inline operator Reader() const { return Reader(_builder.asReader()); }
cannam@148 525 inline Reader asReader() const { return Reader(_builder.asReader()); }
cannam@148 526
cannam@148 527 template <typename T>
cannam@148 528 BuilderFor<T> as() {
cannam@148 529 // T must be a struct type.
cannam@148 530 return typename T::Builder(_builder);
cannam@148 531 }
cannam@148 532 private:
cannam@148 533 _::StructBuilder _builder;
cannam@148 534 friend class Orphanage;
cannam@148 535 friend class CapBuilderContext;
cannam@148 536 };
cannam@148 537
cannam@148 538 #if !CAPNP_LITE
cannam@148 539 class AnyStruct::Pipeline {
cannam@148 540 public:
cannam@148 541 inline Pipeline(decltype(nullptr)): typeless(nullptr) {}
cannam@148 542 inline explicit Pipeline(AnyPointer::Pipeline&& typeless)
cannam@148 543 : typeless(kj::mv(typeless)) {}
cannam@148 544
cannam@148 545 inline AnyPointer::Pipeline getPointerField(uint16_t pointerIndex) {
cannam@148 546 // Return a new Promise representing a sub-object of the result. `pointerIndex` is the index
cannam@148 547 // of the sub-object within the pointer section of the result (the result must be a struct).
cannam@148 548 //
cannam@148 549 // TODO(perf): On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies.
cannam@148 550 // Also make `ops` into a Vector to optimize this.
cannam@148 551 return typeless.getPointerField(pointerIndex);
cannam@148 552 }
cannam@148 553
cannam@148 554 private:
cannam@148 555 AnyPointer::Pipeline typeless;
cannam@148 556 };
cannam@148 557 #endif // !CAPNP_LITE
cannam@148 558
cannam@148 559 class List<AnyStruct, Kind::OTHER>::Reader {
cannam@148 560 public:
cannam@148 561 typedef List<AnyStruct> Reads;
cannam@148 562
cannam@148 563 inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {}
cannam@148 564 inline explicit Reader(_::ListReader reader): reader(reader) {}
cannam@148 565
cannam@148 566 inline uint size() const { return unbound(reader.size() / ELEMENTS); }
cannam@148 567 inline AnyStruct::Reader operator[](uint index) const {
cannam@148 568 KJ_IREQUIRE(index < size());
cannam@148 569 return AnyStruct::Reader(reader.getStructElement(bounded(index) * ELEMENTS));
cannam@148 570 }
cannam@148 571
cannam@148 572 typedef _::IndexingIterator<const Reader, typename AnyStruct::Reader> Iterator;
cannam@148 573 inline Iterator begin() const { return Iterator(this, 0); }
cannam@148 574 inline Iterator end() const { return Iterator(this, size()); }
cannam@148 575
cannam@148 576 private:
cannam@148 577 _::ListReader reader;
cannam@148 578 template <typename U, Kind K>
cannam@148 579 friend struct _::PointerHelpers;
cannam@148 580 template <typename U, Kind K>
cannam@148 581 friend struct List;
cannam@148 582 friend class Orphanage;
cannam@148 583 template <typename U, Kind K>
cannam@148 584 friend struct ToDynamic_;
cannam@148 585 };
cannam@148 586
cannam@148 587 class List<AnyStruct, Kind::OTHER>::Builder {
cannam@148 588 public:
cannam@148 589 typedef List<AnyStruct> Builds;
cannam@148 590
cannam@148 591 Builder() = delete;
cannam@148 592 inline Builder(decltype(nullptr)): builder(ElementSize::INLINE_COMPOSITE) {}
cannam@148 593 inline explicit Builder(_::ListBuilder builder): builder(builder) {}
cannam@148 594
cannam@148 595 inline operator Reader() const { return Reader(builder.asReader()); }
cannam@148 596 inline Reader asReader() const { return Reader(builder.asReader()); }
cannam@148 597
cannam@148 598 inline uint size() const { return unbound(builder.size() / ELEMENTS); }
cannam@148 599 inline AnyStruct::Builder operator[](uint index) {
cannam@148 600 KJ_IREQUIRE(index < size());
cannam@148 601 return AnyStruct::Builder(builder.getStructElement(bounded(index) * ELEMENTS));
cannam@148 602 }
cannam@148 603
cannam@148 604 typedef _::IndexingIterator<Builder, typename AnyStruct::Builder> Iterator;
cannam@148 605 inline Iterator begin() { return Iterator(this, 0); }
cannam@148 606 inline Iterator end() { return Iterator(this, size()); }
cannam@148 607
cannam@148 608 private:
cannam@148 609 _::ListBuilder builder;
cannam@148 610 template <typename U, Kind K>
cannam@148 611 friend struct _::PointerHelpers;
cannam@148 612 friend class Orphanage;
cannam@148 613 template <typename U, Kind K>
cannam@148 614 friend struct ToDynamic_;
cannam@148 615 };
cannam@148 616
cannam@148 617 class AnyList::Reader {
cannam@148 618 public:
cannam@148 619 typedef AnyList Reads;
cannam@148 620
cannam@148 621 inline Reader(): _reader(ElementSize::VOID) {}
cannam@148 622 inline Reader(_::ListReader reader): _reader(reader) {}
cannam@148 623
cannam@148 624 #if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves.
cannam@148 625 template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromReader<T>) == Kind::LIST>>
cannam@148 626 inline Reader(T&& value)
cannam@148 627 : _reader(_::PointerHelpers<FromReader<T>>::getInternalReader(kj::fwd<T>(value))) {}
cannam@148 628 #endif
cannam@148 629
cannam@148 630 inline ElementSize getElementSize() { return _reader.getElementSize(); }
cannam@148 631 inline uint size() { return unbound(_reader.size() / ELEMENTS); }
cannam@148 632
cannam@148 633 inline kj::ArrayPtr<const byte> getRawBytes() { return _reader.asRawBytes(); }
cannam@148 634
cannam@148 635 Equality equals(AnyList::Reader right);
cannam@148 636 bool operator==(AnyList::Reader right);
cannam@148 637 inline bool operator!=(AnyList::Reader right) {
cannam@148 638 return !(*this == right);
cannam@148 639 }
cannam@148 640
cannam@148 641 template <typename T> ReaderFor<T> as() {
cannam@148 642 // T must be List<U>.
cannam@148 643 return ReaderFor<T>(_reader);
cannam@148 644 }
cannam@148 645 private:
cannam@148 646 _::ListReader _reader;
cannam@148 647
cannam@148 648 template <typename, Kind>
cannam@148 649 friend struct _::PointerHelpers;
cannam@148 650 friend class Orphanage;
cannam@148 651 };
cannam@148 652
cannam@148 653 class AnyList::Builder {
cannam@148 654 public:
cannam@148 655 typedef AnyList Builds;
cannam@148 656
cannam@148 657 inline Builder(decltype(nullptr)): _builder(ElementSize::VOID) {}
cannam@148 658 inline Builder(_::ListBuilder builder): _builder(builder) {}
cannam@148 659
cannam@148 660 #if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves.
cannam@148 661 template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromBuilder<T>) == Kind::LIST>>
cannam@148 662 inline Builder(T&& value)
cannam@148 663 : _builder(_::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::fwd<T>(value))) {}
cannam@148 664 #endif
cannam@148 665
cannam@148 666 inline ElementSize getElementSize() { return _builder.getElementSize(); }
cannam@148 667 inline uint size() { return unbound(_builder.size() / ELEMENTS); }
cannam@148 668
cannam@148 669 Equality equals(AnyList::Reader right);
cannam@148 670 inline bool operator==(AnyList::Reader right) {
cannam@148 671 return asReader() == right;
cannam@148 672 }
cannam@148 673 inline bool operator!=(AnyList::Reader right) {
cannam@148 674 return !(*this == right);
cannam@148 675 }
cannam@148 676
cannam@148 677 template <typename T> BuilderFor<T> as() {
cannam@148 678 // T must be List<U>.
cannam@148 679 return BuilderFor<T>(_builder);
cannam@148 680 }
cannam@148 681
cannam@148 682 inline operator Reader() const { return Reader(_builder.asReader()); }
cannam@148 683 inline Reader asReader() const { return Reader(_builder.asReader()); }
cannam@148 684
cannam@148 685 private:
cannam@148 686 _::ListBuilder _builder;
cannam@148 687
cannam@148 688 friend class Orphanage;
cannam@148 689 };
cannam@148 690
cannam@148 691 // =======================================================================================
cannam@148 692 // Pipeline helpers
cannam@148 693 //
cannam@148 694 // These relate to capabilities, but we don't declare them in capability.h because generated code
cannam@148 695 // for structs needs to know about these, even in files that contain no interfaces.
cannam@148 696
cannam@148 697 #if !CAPNP_LITE
cannam@148 698
cannam@148 699 struct PipelineOp {
cannam@148 700 // Corresponds to rpc.capnp's PromisedAnswer.Op.
cannam@148 701
cannam@148 702 enum Type {
cannam@148 703 NOOP, // for convenience
cannam@148 704
cannam@148 705 GET_POINTER_FIELD
cannam@148 706
cannam@148 707 // There may be other types in the future...
cannam@148 708 };
cannam@148 709
cannam@148 710 Type type;
cannam@148 711 union {
cannam@148 712 uint16_t pointerIndex; // for GET_POINTER_FIELD
cannam@148 713 };
cannam@148 714 };
cannam@148 715
cannam@148 716 class PipelineHook {
cannam@148 717 // Represents a currently-running call, and implements pipelined requests on its result.
cannam@148 718
cannam@148 719 public:
cannam@148 720 virtual kj::Own<PipelineHook> addRef() = 0;
cannam@148 721 // Increment this object's reference count.
cannam@148 722
cannam@148 723 virtual kj::Own<ClientHook> getPipelinedCap(kj::ArrayPtr<const PipelineOp> ops) = 0;
cannam@148 724 // Extract a promised Capability from the results.
cannam@148 725
cannam@148 726 virtual kj::Own<ClientHook> getPipelinedCap(kj::Array<PipelineOp>&& ops);
cannam@148 727 // Version of getPipelinedCap() passing the array by move. May avoid a copy in some cases.
cannam@148 728 // Default implementation just calls the other version.
cannam@148 729
cannam@148 730 template <typename Pipeline, typename = FromPipeline<Pipeline>>
cannam@148 731 static inline kj::Own<PipelineHook> from(Pipeline&& pipeline);
cannam@148 732
cannam@148 733 private:
cannam@148 734 template <typename T> struct FromImpl;
cannam@148 735 };
cannam@148 736
cannam@148 737 #endif // !CAPNP_LITE
cannam@148 738
cannam@148 739 // =======================================================================================
cannam@148 740 // Inline implementation details
cannam@148 741
cannam@148 742 inline MessageSize AnyPointer::Reader::targetSize() const {
cannam@148 743 return reader.targetSize().asPublic();
cannam@148 744 }
cannam@148 745
cannam@148 746 inline PointerType AnyPointer::Reader::getPointerType() const {
cannam@148 747 return reader.getPointerType();
cannam@148 748 }
cannam@148 749
cannam@148 750 template <typename T>
cannam@148 751 inline ReaderFor<T> AnyPointer::Reader::getAs() const {
cannam@148 752 return _::PointerHelpers<T>::get(reader);
cannam@148 753 }
cannam@148 754
cannam@148 755 inline MessageSize AnyPointer::Builder::targetSize() const {
cannam@148 756 return asReader().targetSize();
cannam@148 757 }
cannam@148 758
cannam@148 759 inline PointerType AnyPointer::Builder::getPointerType() {
cannam@148 760 return builder.getPointerType();
cannam@148 761 }
cannam@148 762
cannam@148 763 inline void AnyPointer::Builder::clear() {
cannam@148 764 return builder.clear();
cannam@148 765 }
cannam@148 766
cannam@148 767 template <typename T>
cannam@148 768 inline BuilderFor<T> AnyPointer::Builder::getAs() {
cannam@148 769 return _::PointerHelpers<T>::get(builder);
cannam@148 770 }
cannam@148 771
cannam@148 772 template <typename T>
cannam@148 773 inline BuilderFor<T> AnyPointer::Builder::initAs() {
cannam@148 774 return _::PointerHelpers<T>::init(builder);
cannam@148 775 }
cannam@148 776
cannam@148 777 template <typename T>
cannam@148 778 inline BuilderFor<T> AnyPointer::Builder::initAs(uint elementCount) {
cannam@148 779 return _::PointerHelpers<T>::init(builder, elementCount);
cannam@148 780 }
cannam@148 781
cannam@148 782 inline AnyList::Builder AnyPointer::Builder::initAsAnyList(
cannam@148 783 ElementSize elementSize, uint elementCount) {
cannam@148 784 return AnyList::Builder(builder.initList(elementSize, bounded(elementCount) * ELEMENTS));
cannam@148 785 }
cannam@148 786
cannam@148 787 inline List<AnyStruct>::Builder AnyPointer::Builder::initAsListOfAnyStruct(
cannam@148 788 uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) {
cannam@148 789 return List<AnyStruct>::Builder(builder.initStructList(bounded(elementCount) * ELEMENTS,
cannam@148 790 _::StructSize(bounded(dataWordCount) * WORDS,
cannam@148 791 bounded(pointerCount) * POINTERS)));
cannam@148 792 }
cannam@148 793
cannam@148 794 inline AnyStruct::Builder AnyPointer::Builder::initAsAnyStruct(
cannam@148 795 uint16_t dataWordCount, uint16_t pointerCount) {
cannam@148 796 return AnyStruct::Builder(builder.initStruct(
cannam@148 797 _::StructSize(bounded(dataWordCount) * WORDS,
cannam@148 798 bounded(pointerCount) * POINTERS)));
cannam@148 799 }
cannam@148 800
cannam@148 801 template <typename T>
cannam@148 802 inline void AnyPointer::Builder::setAs(ReaderFor<T> value) {
cannam@148 803 return _::PointerHelpers<T>::set(builder, value);
cannam@148 804 }
cannam@148 805
cannam@148 806 template <typename T>
cannam@148 807 inline void AnyPointer::Builder::setCanonicalAs(ReaderFor<T> value) {
cannam@148 808 return _::PointerHelpers<T>::setCanonical(builder, value);
cannam@148 809 }
cannam@148 810
cannam@148 811 template <typename T>
cannam@148 812 inline void AnyPointer::Builder::setAs(
cannam@148 813 std::initializer_list<ReaderFor<ListElementType<T>>> list) {
cannam@148 814 return _::PointerHelpers<T>::set(builder, list);
cannam@148 815 }
cannam@148 816
cannam@148 817 template <typename T>
cannam@148 818 inline void AnyPointer::Builder::adopt(Orphan<T>&& orphan) {
cannam@148 819 _::PointerHelpers<T>::adopt(builder, kj::mv(orphan));
cannam@148 820 }
cannam@148 821
cannam@148 822 template <typename T>
cannam@148 823 inline Orphan<T> AnyPointer::Builder::disownAs() {
cannam@148 824 return _::PointerHelpers<T>::disown(builder);
cannam@148 825 }
cannam@148 826
cannam@148 827 inline Orphan<AnyPointer> AnyPointer::Builder::disown() {
cannam@148 828 return Orphan<AnyPointer>(builder.disown());
cannam@148 829 }
cannam@148 830
cannam@148 831 template <> struct ReaderFor_ <AnyPointer, Kind::OTHER> { typedef AnyPointer::Reader Type; };
cannam@148 832 template <> struct BuilderFor_<AnyPointer, Kind::OTHER> { typedef AnyPointer::Builder Type; };
cannam@148 833 template <> struct ReaderFor_ <AnyStruct, Kind::OTHER> { typedef AnyStruct::Reader Type; };
cannam@148 834 template <> struct BuilderFor_<AnyStruct, Kind::OTHER> { typedef AnyStruct::Builder Type; };
cannam@148 835
cannam@148 836 template <>
cannam@148 837 struct Orphanage::GetInnerReader<AnyPointer, Kind::OTHER> {
cannam@148 838 static inline _::PointerReader apply(const AnyPointer::Reader& t) {
cannam@148 839 return t.reader;
cannam@148 840 }
cannam@148 841 };
cannam@148 842
cannam@148 843 template <>
cannam@148 844 struct Orphanage::GetInnerBuilder<AnyPointer, Kind::OTHER> {
cannam@148 845 static inline _::PointerBuilder apply(AnyPointer::Builder& t) {
cannam@148 846 return t.builder;
cannam@148 847 }
cannam@148 848 };
cannam@148 849
cannam@148 850 template <>
cannam@148 851 struct Orphanage::GetInnerReader<AnyStruct, Kind::OTHER> {
cannam@148 852 static inline _::StructReader apply(const AnyStruct::Reader& t) {
cannam@148 853 return t._reader;
cannam@148 854 }
cannam@148 855 };
cannam@148 856
cannam@148 857 template <>
cannam@148 858 struct Orphanage::GetInnerBuilder<AnyStruct, Kind::OTHER> {
cannam@148 859 static inline _::StructBuilder apply(AnyStruct::Builder& t) {
cannam@148 860 return t._builder;
cannam@148 861 }
cannam@148 862 };
cannam@148 863
cannam@148 864 template <>
cannam@148 865 struct Orphanage::GetInnerReader<AnyList, Kind::OTHER> {
cannam@148 866 static inline _::ListReader apply(const AnyList::Reader& t) {
cannam@148 867 return t._reader;
cannam@148 868 }
cannam@148 869 };
cannam@148 870
cannam@148 871 template <>
cannam@148 872 struct Orphanage::GetInnerBuilder<AnyList, Kind::OTHER> {
cannam@148 873 static inline _::ListBuilder apply(AnyList::Builder& t) {
cannam@148 874 return t._builder;
cannam@148 875 }
cannam@148 876 };
cannam@148 877
cannam@148 878 template <typename T>
cannam@148 879 inline BuilderFor<T> Orphan<AnyPointer>::getAs() {
cannam@148 880 return _::OrphanGetImpl<T>::apply(builder);
cannam@148 881 }
cannam@148 882 template <typename T>
cannam@148 883 inline ReaderFor<T> Orphan<AnyPointer>::getAsReader() const {
cannam@148 884 return _::OrphanGetImpl<T>::applyReader(builder);
cannam@148 885 }
cannam@148 886 template <typename T>
cannam@148 887 inline Orphan<T> Orphan<AnyPointer>::releaseAs() {
cannam@148 888 return Orphan<T>(kj::mv(builder));
cannam@148 889 }
cannam@148 890
cannam@148 891 // Using AnyPointer as the template type should work...
cannam@148 892
cannam@148 893 template <>
cannam@148 894 inline typename AnyPointer::Reader AnyPointer::Reader::getAs<AnyPointer>() const {
cannam@148 895 return *this;
cannam@148 896 }
cannam@148 897 template <>
cannam@148 898 inline typename AnyPointer::Builder AnyPointer::Builder::getAs<AnyPointer>() {
cannam@148 899 return *this;
cannam@148 900 }
cannam@148 901 template <>
cannam@148 902 inline typename AnyPointer::Builder AnyPointer::Builder::initAs<AnyPointer>() {
cannam@148 903 clear();
cannam@148 904 return *this;
cannam@148 905 }
cannam@148 906 template <>
cannam@148 907 inline void AnyPointer::Builder::setAs<AnyPointer>(AnyPointer::Reader value) {
cannam@148 908 return builder.copyFrom(value.reader);
cannam@148 909 }
cannam@148 910 template <>
cannam@148 911 inline void AnyPointer::Builder::adopt<AnyPointer>(Orphan<AnyPointer>&& orphan) {
cannam@148 912 builder.adopt(kj::mv(orphan.builder));
cannam@148 913 }
cannam@148 914 template <>
cannam@148 915 inline Orphan<AnyPointer> AnyPointer::Builder::disownAs<AnyPointer>() {
cannam@148 916 return Orphan<AnyPointer>(builder.disown());
cannam@148 917 }
cannam@148 918 template <>
cannam@148 919 inline Orphan<AnyPointer> Orphan<AnyPointer>::releaseAs() {
cannam@148 920 return kj::mv(*this);
cannam@148 921 }
cannam@148 922
cannam@148 923 namespace _ { // private
cannam@148 924
cannam@148 925 // Specialize PointerHelpers for AnyPointer.
cannam@148 926
cannam@148 927 template <>
cannam@148 928 struct PointerHelpers<AnyPointer, Kind::OTHER> {
cannam@148 929 static inline AnyPointer::Reader get(PointerReader reader,
cannam@148 930 const void* defaultValue = nullptr,
cannam@148 931 uint defaultBytes = 0) {
cannam@148 932 return AnyPointer::Reader(reader);
cannam@148 933 }
cannam@148 934 static inline AnyPointer::Builder get(PointerBuilder builder,
cannam@148 935 const void* defaultValue = nullptr,
cannam@148 936 uint defaultBytes = 0) {
cannam@148 937 return AnyPointer::Builder(builder);
cannam@148 938 }
cannam@148 939 static inline void set(PointerBuilder builder, AnyPointer::Reader value) {
cannam@148 940 AnyPointer::Builder(builder).set(value);
cannam@148 941 }
cannam@148 942 static inline void adopt(PointerBuilder builder, Orphan<AnyPointer>&& value) {
cannam@148 943 builder.adopt(kj::mv(value.builder));
cannam@148 944 }
cannam@148 945 static inline Orphan<AnyPointer> disown(PointerBuilder builder) {
cannam@148 946 return Orphan<AnyPointer>(builder.disown());
cannam@148 947 }
cannam@148 948 static inline _::PointerReader getInternalReader(const AnyPointer::Reader& reader) {
cannam@148 949 return reader.reader;
cannam@148 950 }
cannam@148 951 static inline _::PointerBuilder getInternalBuilder(AnyPointer::Builder&& builder) {
cannam@148 952 return builder.builder;
cannam@148 953 }
cannam@148 954 };
cannam@148 955
cannam@148 956 template <>
cannam@148 957 struct PointerHelpers<AnyStruct, Kind::OTHER> {
cannam@148 958 static inline AnyStruct::Reader get(
cannam@148 959 PointerReader reader, const word* defaultValue = nullptr) {
cannam@148 960 return AnyStruct::Reader(reader.getStruct(defaultValue));
cannam@148 961 }
cannam@148 962 static inline AnyStruct::Builder get(
cannam@148 963 PointerBuilder builder, const word* defaultValue = nullptr) {
cannam@148 964 // TODO(someday): Allow specifying the size somehow?
cannam@148 965 return AnyStruct::Builder(builder.getStruct(
cannam@148 966 _::StructSize(ZERO * WORDS, ZERO * POINTERS), defaultValue));
cannam@148 967 }
cannam@148 968 static inline void set(PointerBuilder builder, AnyStruct::Reader value) {
cannam@148 969 builder.setStruct(value._reader);
cannam@148 970 }
cannam@148 971 static inline AnyStruct::Builder init(
cannam@148 972 PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount) {
cannam@148 973 return AnyStruct::Builder(builder.initStruct(
cannam@148 974 StructSize(bounded(dataWordCount) * WORDS,
cannam@148 975 bounded(pointerCount) * POINTERS)));
cannam@148 976 }
cannam@148 977
cannam@148 978 static void adopt(PointerBuilder builder, Orphan<AnyStruct>&& value) {
cannam@148 979 builder.adopt(kj::mv(value.builder));
cannam@148 980 }
cannam@148 981 static Orphan<AnyStruct> disown(PointerBuilder builder) {
cannam@148 982 return Orphan<AnyStruct>(builder.disown());
cannam@148 983 }
cannam@148 984 };
cannam@148 985
cannam@148 986 template <>
cannam@148 987 struct PointerHelpers<AnyList, Kind::OTHER> {
cannam@148 988 static inline AnyList::Reader get(
cannam@148 989 PointerReader reader, const word* defaultValue = nullptr) {
cannam@148 990 return AnyList::Reader(reader.getListAnySize(defaultValue));
cannam@148 991 }
cannam@148 992 static inline AnyList::Builder get(
cannam@148 993 PointerBuilder builder, const word* defaultValue = nullptr) {
cannam@148 994 return AnyList::Builder(builder.getListAnySize(defaultValue));
cannam@148 995 }
cannam@148 996 static inline void set(PointerBuilder builder, AnyList::Reader value) {
cannam@148 997 builder.setList(value._reader);
cannam@148 998 }
cannam@148 999 static inline AnyList::Builder init(
cannam@148 1000 PointerBuilder builder, ElementSize elementSize, uint elementCount) {
cannam@148 1001 return AnyList::Builder(builder.initList(
cannam@148 1002 elementSize, bounded(elementCount) * ELEMENTS));
cannam@148 1003 }
cannam@148 1004 static inline AnyList::Builder init(
cannam@148 1005 PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) {
cannam@148 1006 return AnyList::Builder(builder.initStructList(
cannam@148 1007 bounded(elementCount) * ELEMENTS,
cannam@148 1008 StructSize(bounded(dataWordCount) * WORDS,
cannam@148 1009 bounded(pointerCount) * POINTERS)));
cannam@148 1010 }
cannam@148 1011
cannam@148 1012 static void adopt(PointerBuilder builder, Orphan<AnyList>&& value) {
cannam@148 1013 builder.adopt(kj::mv(value.builder));
cannam@148 1014 }
cannam@148 1015 static Orphan<AnyList> disown(PointerBuilder builder) {
cannam@148 1016 return Orphan<AnyList>(builder.disown());
cannam@148 1017 }
cannam@148 1018 };
cannam@148 1019
cannam@148 1020 template <>
cannam@148 1021 struct OrphanGetImpl<AnyStruct, Kind::OTHER> {
cannam@148 1022 static inline AnyStruct::Builder apply(_::OrphanBuilder& builder) {
cannam@148 1023 return AnyStruct::Builder(builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS)));
cannam@148 1024 }
cannam@148 1025 static inline AnyStruct::Reader applyReader(const _::OrphanBuilder& builder) {
cannam@148 1026 return AnyStruct::Reader(builder.asStructReader(_::StructSize(ZERO * WORDS, ZERO * POINTERS)));
cannam@148 1027 }
cannam@148 1028 static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) {
cannam@148 1029 builder.truncate(size, _::StructSize(ZERO * WORDS, ZERO * POINTERS));
cannam@148 1030 }
cannam@148 1031 };
cannam@148 1032
cannam@148 1033 template <>
cannam@148 1034 struct OrphanGetImpl<AnyList, Kind::OTHER> {
cannam@148 1035 static inline AnyList::Builder apply(_::OrphanBuilder& builder) {
cannam@148 1036 return AnyList::Builder(builder.asListAnySize());
cannam@148 1037 }
cannam@148 1038 static inline AnyList::Reader applyReader(const _::OrphanBuilder& builder) {
cannam@148 1039 return AnyList::Reader(builder.asListReaderAnySize());
cannam@148 1040 }
cannam@148 1041 static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) {
cannam@148 1042 builder.truncate(size, ElementSize::POINTER);
cannam@148 1043 }
cannam@148 1044 };
cannam@148 1045
cannam@148 1046 } // namespace _ (private)
cannam@148 1047
cannam@148 1048 #if !CAPNP_LITE
cannam@148 1049
cannam@148 1050 template <typename T>
cannam@148 1051 struct PipelineHook::FromImpl {
cannam@148 1052 static inline kj::Own<PipelineHook> apply(typename T::Pipeline&& pipeline) {
cannam@148 1053 return from(kj::mv(pipeline._typeless));
cannam@148 1054 }
cannam@148 1055 };
cannam@148 1056
cannam@148 1057 template <>
cannam@148 1058 struct PipelineHook::FromImpl<AnyPointer> {
cannam@148 1059 static inline kj::Own<PipelineHook> apply(AnyPointer::Pipeline&& pipeline) {
cannam@148 1060 return kj::mv(pipeline.hook);
cannam@148 1061 }
cannam@148 1062 };
cannam@148 1063
cannam@148 1064 template <typename Pipeline, typename T>
cannam@148 1065 inline kj::Own<PipelineHook> PipelineHook::from(Pipeline&& pipeline) {
cannam@148 1066 return FromImpl<T>::apply(kj::fwd<Pipeline>(pipeline));
cannam@148 1067 }
cannam@148 1068
cannam@148 1069 #endif // !CAPNP_LITE
cannam@148 1070
cannam@148 1071 } // namespace capnp
cannam@148 1072
cannam@148 1073 #endif // CAPNP_ANY_H_