annotate osx/include/capnp/any.h @ 83:ae30d91d2ffe

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