annotate osx/include/capnp/list.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_LIST_H_
cannam@62 23 #define CAPNP_LIST_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 "orphan.h"
cannam@62 31 #include <initializer_list>
cannam@62 32 #ifdef KJ_STD_COMPAT
cannam@62 33 #include <iterator>
cannam@62 34 #endif // KJ_STD_COMPAT
cannam@62 35
cannam@62 36 namespace capnp {
cannam@62 37 namespace _ { // private
cannam@62 38
cannam@62 39 template <typename T>
cannam@62 40 class TemporaryPointer {
cannam@62 41 // This class is a little hack which lets us define operator->() in cases where it needs to
cannam@62 42 // return a pointer to a temporary value. We instead construct a TemporaryPointer and return that
cannam@62 43 // (by value). The compiler then invokes operator->() on the TemporaryPointer, which itself is
cannam@62 44 // able to return a real pointer to its member.
cannam@62 45
cannam@62 46 public:
cannam@62 47 TemporaryPointer(T&& value): value(kj::mv(value)) {}
cannam@62 48 TemporaryPointer(const T& value): value(value) {}
cannam@62 49
cannam@62 50 inline T* operator->() { return &value; }
cannam@62 51 private:
cannam@62 52 T value;
cannam@62 53 };
cannam@62 54
cannam@62 55 template <typename Container, typename Element>
cannam@62 56 class IndexingIterator {
cannam@62 57 public:
cannam@62 58 IndexingIterator() = default;
cannam@62 59
cannam@62 60 inline Element operator*() const { return (*container)[index]; }
cannam@62 61 inline TemporaryPointer<Element> operator->() const {
cannam@62 62 return TemporaryPointer<Element>((*container)[index]);
cannam@62 63 }
cannam@62 64 inline Element operator[]( int off) const { return (*container)[index]; }
cannam@62 65 inline Element operator[](uint off) const { return (*container)[index]; }
cannam@62 66
cannam@62 67 inline IndexingIterator& operator++() { ++index; return *this; }
cannam@62 68 inline IndexingIterator operator++(int) { IndexingIterator other = *this; ++index; return other; }
cannam@62 69 inline IndexingIterator& operator--() { --index; return *this; }
cannam@62 70 inline IndexingIterator operator--(int) { IndexingIterator other = *this; --index; return other; }
cannam@62 71
cannam@62 72 inline IndexingIterator operator+(uint amount) const { return IndexingIterator(container, index + amount); }
cannam@62 73 inline IndexingIterator operator-(uint amount) const { return IndexingIterator(container, index - amount); }
cannam@62 74 inline IndexingIterator operator+( int amount) const { return IndexingIterator(container, index + amount); }
cannam@62 75 inline IndexingIterator operator-( int amount) const { return IndexingIterator(container, index - amount); }
cannam@62 76
cannam@62 77 inline int operator-(const IndexingIterator& other) const { return index - other.index; }
cannam@62 78
cannam@62 79 inline IndexingIterator& operator+=(uint amount) { index += amount; return *this; }
cannam@62 80 inline IndexingIterator& operator-=(uint amount) { index -= amount; return *this; }
cannam@62 81 inline IndexingIterator& operator+=( int amount) { index += amount; return *this; }
cannam@62 82 inline IndexingIterator& operator-=( int amount) { index -= amount; return *this; }
cannam@62 83
cannam@62 84 // STL says comparing iterators of different containers is not allowed, so we only compare
cannam@62 85 // indices here.
cannam@62 86 inline bool operator==(const IndexingIterator& other) const { return index == other.index; }
cannam@62 87 inline bool operator!=(const IndexingIterator& other) const { return index != other.index; }
cannam@62 88 inline bool operator<=(const IndexingIterator& other) const { return index <= other.index; }
cannam@62 89 inline bool operator>=(const IndexingIterator& other) const { return index >= other.index; }
cannam@62 90 inline bool operator< (const IndexingIterator& other) const { return index < other.index; }
cannam@62 91 inline bool operator> (const IndexingIterator& other) const { return index > other.index; }
cannam@62 92
cannam@62 93 private:
cannam@62 94 Container* container;
cannam@62 95 uint index;
cannam@62 96
cannam@62 97 friend Container;
cannam@62 98 inline IndexingIterator(Container* container, uint index)
cannam@62 99 : container(container), index(index) {}
cannam@62 100 };
cannam@62 101
cannam@62 102 } // namespace _ (private)
cannam@62 103
cannam@62 104 template <typename T>
cannam@62 105 struct List<T, Kind::PRIMITIVE> {
cannam@62 106 // List of primitives.
cannam@62 107
cannam@62 108 List() = delete;
cannam@62 109
cannam@62 110 class Reader {
cannam@62 111 public:
cannam@62 112 typedef List<T> Reads;
cannam@62 113
cannam@62 114 inline Reader(): reader(_::elementSizeForType<T>()) {}
cannam@62 115 inline explicit Reader(_::ListReader reader): reader(reader) {}
cannam@62 116
cannam@62 117 inline uint size() const { return unbound(reader.size() / ELEMENTS); }
cannam@62 118 inline T operator[](uint index) const {
cannam@62 119 KJ_IREQUIRE(index < size());
cannam@62 120 return reader.template getDataElement<T>(bounded(index) * ELEMENTS);
cannam@62 121 }
cannam@62 122
cannam@62 123 typedef _::IndexingIterator<const Reader, T> Iterator;
cannam@62 124 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 125 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 126
cannam@62 127 private:
cannam@62 128 _::ListReader reader;
cannam@62 129 template <typename U, Kind K>
cannam@62 130 friend struct _::PointerHelpers;
cannam@62 131 template <typename U, Kind K>
cannam@62 132 friend struct List;
cannam@62 133 friend class Orphanage;
cannam@62 134 template <typename U, Kind K>
cannam@62 135 friend struct ToDynamic_;
cannam@62 136 };
cannam@62 137
cannam@62 138 class Builder {
cannam@62 139 public:
cannam@62 140 typedef List<T> Builds;
cannam@62 141
cannam@62 142 inline Builder(): builder(_::elementSizeForType<T>()) {}
cannam@62 143 inline Builder(decltype(nullptr)): Builder() {}
cannam@62 144 inline explicit Builder(_::ListBuilder builder): builder(builder) {}
cannam@62 145
cannam@62 146 inline operator Reader() const { return Reader(builder.asReader()); }
cannam@62 147 inline Reader asReader() const { return Reader(builder.asReader()); }
cannam@62 148
cannam@62 149 inline uint size() const { return unbound(builder.size() / ELEMENTS); }
cannam@62 150 inline T operator[](uint index) {
cannam@62 151 KJ_IREQUIRE(index < size());
cannam@62 152 return builder.template getDataElement<T>(bounded(index) * ELEMENTS);
cannam@62 153 }
cannam@62 154 inline void set(uint index, T value) {
cannam@62 155 // Alas, it is not possible to make operator[] return a reference to which you can assign,
cannam@62 156 // since the encoded representation does not necessarily match the compiler's representation
cannam@62 157 // of the type. We can't even return a clever class that implements operator T() and
cannam@62 158 // operator=() because it will lead to surprising behavior when using type inference (e.g.
cannam@62 159 // calling a template function with inferred argument types, or using "auto" or "decltype").
cannam@62 160
cannam@62 161 builder.template setDataElement<T>(bounded(index) * ELEMENTS, value);
cannam@62 162 }
cannam@62 163
cannam@62 164 typedef _::IndexingIterator<Builder, T> Iterator;
cannam@62 165 inline Iterator begin() { return Iterator(this, 0); }
cannam@62 166 inline Iterator end() { return Iterator(this, size()); }
cannam@62 167
cannam@62 168 private:
cannam@62 169 _::ListBuilder builder;
cannam@62 170 template <typename U, Kind K>
cannam@62 171 friend struct _::PointerHelpers;
cannam@62 172 friend class Orphanage;
cannam@62 173 template <typename U, Kind K>
cannam@62 174 friend struct ToDynamic_;
cannam@62 175 };
cannam@62 176
cannam@62 177 class Pipeline {};
cannam@62 178
cannam@62 179 private:
cannam@62 180 inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) {
cannam@62 181 return builder.initList(_::elementSizeForType<T>(), bounded(size) * ELEMENTS);
cannam@62 182 }
cannam@62 183 inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) {
cannam@62 184 return builder.getList(_::elementSizeForType<T>(), defaultValue);
cannam@62 185 }
cannam@62 186 inline static _::ListReader getFromPointer(
cannam@62 187 const _::PointerReader& reader, const word* defaultValue) {
cannam@62 188 return reader.getList(_::elementSizeForType<T>(), defaultValue);
cannam@62 189 }
cannam@62 190
cannam@62 191 template <typename U, Kind k>
cannam@62 192 friend struct List;
cannam@62 193 template <typename U, Kind K>
cannam@62 194 friend struct _::PointerHelpers;
cannam@62 195 };
cannam@62 196
cannam@62 197 template <typename T>
cannam@62 198 struct List<T, Kind::ENUM>: public List<T, Kind::PRIMITIVE> {};
cannam@62 199
cannam@62 200 template <typename T>
cannam@62 201 struct List<T, Kind::STRUCT> {
cannam@62 202 // List of structs.
cannam@62 203
cannam@62 204 List() = delete;
cannam@62 205
cannam@62 206 class Reader {
cannam@62 207 public:
cannam@62 208 typedef List<T> Reads;
cannam@62 209
cannam@62 210 inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {}
cannam@62 211 inline explicit Reader(_::ListReader reader): reader(reader) {}
cannam@62 212
cannam@62 213 inline uint size() const { return unbound(reader.size() / ELEMENTS); }
cannam@62 214 inline typename T::Reader operator[](uint index) const {
cannam@62 215 KJ_IREQUIRE(index < size());
cannam@62 216 return typename T::Reader(reader.getStructElement(bounded(index) * ELEMENTS));
cannam@62 217 }
cannam@62 218
cannam@62 219 typedef _::IndexingIterator<const Reader, typename T::Reader> Iterator;
cannam@62 220 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 221 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 222
cannam@62 223 private:
cannam@62 224 _::ListReader reader;
cannam@62 225 template <typename U, Kind K>
cannam@62 226 friend struct _::PointerHelpers;
cannam@62 227 template <typename U, Kind K>
cannam@62 228 friend struct List;
cannam@62 229 friend class Orphanage;
cannam@62 230 template <typename U, Kind K>
cannam@62 231 friend struct ToDynamic_;
cannam@62 232 };
cannam@62 233
cannam@62 234 class Builder {
cannam@62 235 public:
cannam@62 236 typedef List<T> Builds;
cannam@62 237
cannam@62 238 inline Builder(): builder(ElementSize::INLINE_COMPOSITE) {}
cannam@62 239 inline Builder(decltype(nullptr)): Builder() {}
cannam@62 240 inline explicit Builder(_::ListBuilder builder): builder(builder) {}
cannam@62 241
cannam@62 242 inline operator Reader() const { return Reader(builder.asReader()); }
cannam@62 243 inline Reader asReader() const { return Reader(builder.asReader()); }
cannam@62 244
cannam@62 245 inline uint size() const { return unbound(builder.size() / ELEMENTS); }
cannam@62 246 inline typename T::Builder operator[](uint index) {
cannam@62 247 KJ_IREQUIRE(index < size());
cannam@62 248 return typename T::Builder(builder.getStructElement(bounded(index) * ELEMENTS));
cannam@62 249 }
cannam@62 250
cannam@62 251 inline void adoptWithCaveats(uint index, Orphan<T>&& orphan) {
cannam@62 252 // Mostly behaves like you'd expect `adopt` to behave, but with two caveats originating from
cannam@62 253 // the fact that structs in a struct list are allocated inline rather than by pointer:
cannam@62 254 // * This actually performs a shallow copy, effectively adopting each of the orphan's
cannam@62 255 // children rather than adopting the orphan itself. The orphan ends up being discarded,
cannam@62 256 // possibly wasting space in the message object.
cannam@62 257 // * If the orphan is larger than the target struct -- say, because the orphan was built
cannam@62 258 // using a newer version of the schema that has additional fields -- it will be truncated,
cannam@62 259 // losing data.
cannam@62 260
cannam@62 261 KJ_IREQUIRE(index < size());
cannam@62 262
cannam@62 263 // We pass a zero-valued StructSize to asStruct() because we do not want the struct to be
cannam@62 264 // expanded under any circumstances. We're just going to throw it away anyway, and
cannam@62 265 // transferContentFrom() already carefully compares the struct sizes before transferring.
cannam@62 266 builder.getStructElement(bounded(index) * ELEMENTS).transferContentFrom(
cannam@62 267 orphan.builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS)));
cannam@62 268 }
cannam@62 269 inline void setWithCaveats(uint index, const typename T::Reader& reader) {
cannam@62 270 // Mostly behaves like you'd expect `set` to behave, but with a caveat originating from
cannam@62 271 // the fact that structs in a struct list are allocated inline rather than by pointer:
cannam@62 272 // If the source struct is larger than the target struct -- say, because the source was built
cannam@62 273 // using a newer version of the schema that has additional fields -- it will be truncated,
cannam@62 274 // losing data.
cannam@62 275 //
cannam@62 276 // Note: If you are trying to concatenate some lists, use Orphanage::newOrphanConcat() to
cannam@62 277 // do it without losing any data in case the source lists come from a newer version of the
cannam@62 278 // protocol. (Plus, it's easier to use anyhow.)
cannam@62 279
cannam@62 280 KJ_IREQUIRE(index < size());
cannam@62 281 builder.getStructElement(bounded(index) * ELEMENTS).copyContentFrom(reader._reader);
cannam@62 282 }
cannam@62 283
cannam@62 284 // There are no init(), set(), adopt(), or disown() methods for lists of structs because the
cannam@62 285 // elements of the list are inlined and are initialized when the list is initialized. This
cannam@62 286 // means that init() would be redundant, and set() would risk data loss if the input struct
cannam@62 287 // were from a newer version of the protocol.
cannam@62 288
cannam@62 289 typedef _::IndexingIterator<Builder, typename T::Builder> Iterator;
cannam@62 290 inline Iterator begin() { return Iterator(this, 0); }
cannam@62 291 inline Iterator end() { return Iterator(this, size()); }
cannam@62 292
cannam@62 293 private:
cannam@62 294 _::ListBuilder builder;
cannam@62 295 template <typename U, Kind K>
cannam@62 296 friend struct _::PointerHelpers;
cannam@62 297 friend class Orphanage;
cannam@62 298 template <typename U, Kind K>
cannam@62 299 friend struct ToDynamic_;
cannam@62 300 };
cannam@62 301
cannam@62 302 class Pipeline {};
cannam@62 303
cannam@62 304 private:
cannam@62 305 inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) {
cannam@62 306 return builder.initStructList(bounded(size) * ELEMENTS, _::structSize<T>());
cannam@62 307 }
cannam@62 308 inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) {
cannam@62 309 return builder.getStructList(_::structSize<T>(), defaultValue);
cannam@62 310 }
cannam@62 311 inline static _::ListReader getFromPointer(
cannam@62 312 const _::PointerReader& reader, const word* defaultValue) {
cannam@62 313 return reader.getList(ElementSize::INLINE_COMPOSITE, defaultValue);
cannam@62 314 }
cannam@62 315
cannam@62 316 template <typename U, Kind k>
cannam@62 317 friend struct List;
cannam@62 318 template <typename U, Kind K>
cannam@62 319 friend struct _::PointerHelpers;
cannam@62 320 };
cannam@62 321
cannam@62 322 template <typename T>
cannam@62 323 struct List<List<T>, Kind::LIST> {
cannam@62 324 // List of lists.
cannam@62 325
cannam@62 326 List() = delete;
cannam@62 327
cannam@62 328 class Reader {
cannam@62 329 public:
cannam@62 330 typedef List<List<T>> Reads;
cannam@62 331
cannam@62 332 inline Reader(): reader(ElementSize::POINTER) {}
cannam@62 333 inline explicit Reader(_::ListReader reader): reader(reader) {}
cannam@62 334
cannam@62 335 inline uint size() const { return unbound(reader.size() / ELEMENTS); }
cannam@62 336 inline typename List<T>::Reader operator[](uint index) const {
cannam@62 337 KJ_IREQUIRE(index < size());
cannam@62 338 return typename List<T>::Reader(_::PointerHelpers<List<T>>::get(
cannam@62 339 reader.getPointerElement(bounded(index) * ELEMENTS)));
cannam@62 340 }
cannam@62 341
cannam@62 342 typedef _::IndexingIterator<const Reader, typename List<T>::Reader> Iterator;
cannam@62 343 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 344 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 345
cannam@62 346 private:
cannam@62 347 _::ListReader reader;
cannam@62 348 template <typename U, Kind K>
cannam@62 349 friend struct _::PointerHelpers;
cannam@62 350 template <typename U, Kind K>
cannam@62 351 friend struct List;
cannam@62 352 friend class Orphanage;
cannam@62 353 template <typename U, Kind K>
cannam@62 354 friend struct ToDynamic_;
cannam@62 355 };
cannam@62 356
cannam@62 357 class Builder {
cannam@62 358 public:
cannam@62 359 typedef List<List<T>> Builds;
cannam@62 360
cannam@62 361 inline Builder(): builder(ElementSize::POINTER) {}
cannam@62 362 inline Builder(decltype(nullptr)): Builder() {}
cannam@62 363 inline explicit Builder(_::ListBuilder builder): builder(builder) {}
cannam@62 364
cannam@62 365 inline operator Reader() const { return Reader(builder.asReader()); }
cannam@62 366 inline Reader asReader() const { return Reader(builder.asReader()); }
cannam@62 367
cannam@62 368 inline uint size() const { return unbound(builder.size() / ELEMENTS); }
cannam@62 369 inline typename List<T>::Builder operator[](uint index) {
cannam@62 370 KJ_IREQUIRE(index < size());
cannam@62 371 return typename List<T>::Builder(_::PointerHelpers<List<T>>::get(
cannam@62 372 builder.getPointerElement(bounded(index) * ELEMENTS)));
cannam@62 373 }
cannam@62 374 inline typename List<T>::Builder init(uint index, uint size) {
cannam@62 375 KJ_IREQUIRE(index < this->size());
cannam@62 376 return typename List<T>::Builder(_::PointerHelpers<List<T>>::init(
cannam@62 377 builder.getPointerElement(bounded(index) * ELEMENTS), size));
cannam@62 378 }
cannam@62 379 inline void set(uint index, typename List<T>::Reader value) {
cannam@62 380 KJ_IREQUIRE(index < size());
cannam@62 381 builder.getPointerElement(bounded(index) * ELEMENTS).setList(value.reader);
cannam@62 382 }
cannam@62 383 void set(uint index, std::initializer_list<ReaderFor<T>> value) {
cannam@62 384 KJ_IREQUIRE(index < size());
cannam@62 385 auto l = init(index, value.size());
cannam@62 386 uint i = 0;
cannam@62 387 for (auto& element: value) {
cannam@62 388 l.set(i++, element);
cannam@62 389 }
cannam@62 390 }
cannam@62 391 inline void adopt(uint index, Orphan<T>&& value) {
cannam@62 392 KJ_IREQUIRE(index < size());
cannam@62 393 builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value.builder));
cannam@62 394 }
cannam@62 395 inline Orphan<T> disown(uint index) {
cannam@62 396 KJ_IREQUIRE(index < size());
cannam@62 397 return Orphan<T>(builder.getPointerElement(bounded(index) * ELEMENTS).disown());
cannam@62 398 }
cannam@62 399
cannam@62 400 typedef _::IndexingIterator<Builder, typename List<T>::Builder> Iterator;
cannam@62 401 inline Iterator begin() { return Iterator(this, 0); }
cannam@62 402 inline Iterator end() { return Iterator(this, size()); }
cannam@62 403
cannam@62 404 private:
cannam@62 405 _::ListBuilder builder;
cannam@62 406 template <typename U, Kind K>
cannam@62 407 friend struct _::PointerHelpers;
cannam@62 408 friend class Orphanage;
cannam@62 409 template <typename U, Kind K>
cannam@62 410 friend struct ToDynamic_;
cannam@62 411 };
cannam@62 412
cannam@62 413 class Pipeline {};
cannam@62 414
cannam@62 415 private:
cannam@62 416 inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) {
cannam@62 417 return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS);
cannam@62 418 }
cannam@62 419 inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) {
cannam@62 420 return builder.getList(ElementSize::POINTER, defaultValue);
cannam@62 421 }
cannam@62 422 inline static _::ListReader getFromPointer(
cannam@62 423 const _::PointerReader& reader, const word* defaultValue) {
cannam@62 424 return reader.getList(ElementSize::POINTER, defaultValue);
cannam@62 425 }
cannam@62 426
cannam@62 427 template <typename U, Kind k>
cannam@62 428 friend struct List;
cannam@62 429 template <typename U, Kind K>
cannam@62 430 friend struct _::PointerHelpers;
cannam@62 431 };
cannam@62 432
cannam@62 433 template <typename T>
cannam@62 434 struct List<T, Kind::BLOB> {
cannam@62 435 List() = delete;
cannam@62 436
cannam@62 437 class Reader {
cannam@62 438 public:
cannam@62 439 typedef List<T> Reads;
cannam@62 440
cannam@62 441 inline Reader(): reader(ElementSize::POINTER) {}
cannam@62 442 inline explicit Reader(_::ListReader reader): reader(reader) {}
cannam@62 443
cannam@62 444 inline uint size() const { return unbound(reader.size() / ELEMENTS); }
cannam@62 445 inline typename T::Reader operator[](uint index) const {
cannam@62 446 KJ_IREQUIRE(index < size());
cannam@62 447 return reader.getPointerElement(bounded(index) * ELEMENTS)
cannam@62 448 .template getBlob<T>(nullptr, ZERO * BYTES);
cannam@62 449 }
cannam@62 450
cannam@62 451 typedef _::IndexingIterator<const Reader, typename T::Reader> Iterator;
cannam@62 452 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 453 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 454
cannam@62 455 private:
cannam@62 456 _::ListReader reader;
cannam@62 457 template <typename U, Kind K>
cannam@62 458 friend struct _::PointerHelpers;
cannam@62 459 template <typename U, Kind K>
cannam@62 460 friend struct List;
cannam@62 461 friend class Orphanage;
cannam@62 462 template <typename U, Kind K>
cannam@62 463 friend struct ToDynamic_;
cannam@62 464 };
cannam@62 465
cannam@62 466 class Builder {
cannam@62 467 public:
cannam@62 468 typedef List<T> Builds;
cannam@62 469
cannam@62 470 inline Builder(): builder(ElementSize::POINTER) {}
cannam@62 471 inline Builder(decltype(nullptr)): Builder() {}
cannam@62 472 inline explicit Builder(_::ListBuilder builder): builder(builder) {}
cannam@62 473
cannam@62 474 inline operator Reader() const { return Reader(builder.asReader()); }
cannam@62 475 inline Reader asReader() const { return Reader(builder.asReader()); }
cannam@62 476
cannam@62 477 inline uint size() const { return unbound(builder.size() / ELEMENTS); }
cannam@62 478 inline typename T::Builder operator[](uint index) {
cannam@62 479 KJ_IREQUIRE(index < size());
cannam@62 480 return builder.getPointerElement(bounded(index) * ELEMENTS)
cannam@62 481 .template getBlob<T>(nullptr, ZERO * BYTES);
cannam@62 482 }
cannam@62 483 inline void set(uint index, typename T::Reader value) {
cannam@62 484 KJ_IREQUIRE(index < size());
cannam@62 485 builder.getPointerElement(bounded(index) * ELEMENTS).template setBlob<T>(value);
cannam@62 486 }
cannam@62 487 inline typename T::Builder init(uint index, uint size) {
cannam@62 488 KJ_IREQUIRE(index < this->size());
cannam@62 489 return builder.getPointerElement(bounded(index) * ELEMENTS)
cannam@62 490 .template initBlob<T>(bounded(size) * BYTES);
cannam@62 491 }
cannam@62 492 inline void adopt(uint index, Orphan<T>&& value) {
cannam@62 493 KJ_IREQUIRE(index < size());
cannam@62 494 builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value.builder));
cannam@62 495 }
cannam@62 496 inline Orphan<T> disown(uint index) {
cannam@62 497 KJ_IREQUIRE(index < size());
cannam@62 498 return Orphan<T>(builder.getPointerElement(bounded(index) * ELEMENTS).disown());
cannam@62 499 }
cannam@62 500
cannam@62 501 typedef _::IndexingIterator<Builder, typename T::Builder> Iterator;
cannam@62 502 inline Iterator begin() { return Iterator(this, 0); }
cannam@62 503 inline Iterator end() { return Iterator(this, size()); }
cannam@62 504
cannam@62 505 private:
cannam@62 506 _::ListBuilder builder;
cannam@62 507 template <typename U, Kind K>
cannam@62 508 friend struct _::PointerHelpers;
cannam@62 509 friend class Orphanage;
cannam@62 510 template <typename U, Kind K>
cannam@62 511 friend struct ToDynamic_;
cannam@62 512 };
cannam@62 513
cannam@62 514 class Pipeline {};
cannam@62 515
cannam@62 516 private:
cannam@62 517 inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) {
cannam@62 518 return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS);
cannam@62 519 }
cannam@62 520 inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) {
cannam@62 521 return builder.getList(ElementSize::POINTER, defaultValue);
cannam@62 522 }
cannam@62 523 inline static _::ListReader getFromPointer(
cannam@62 524 const _::PointerReader& reader, const word* defaultValue) {
cannam@62 525 return reader.getList(ElementSize::POINTER, defaultValue);
cannam@62 526 }
cannam@62 527
cannam@62 528 template <typename U, Kind k>
cannam@62 529 friend struct List;
cannam@62 530 template <typename U, Kind K>
cannam@62 531 friend struct _::PointerHelpers;
cannam@62 532 };
cannam@62 533
cannam@62 534 } // namespace capnp
cannam@62 535
cannam@62 536 #ifdef KJ_STD_COMPAT
cannam@62 537 namespace std {
cannam@62 538
cannam@62 539 template <typename Container, typename Element>
cannam@62 540 struct iterator_traits<capnp::_::IndexingIterator<Container, Element>>
cannam@62 541 : public std::iterator<std::random_access_iterator_tag, Element, int> {};
cannam@62 542
cannam@62 543 } // namespace std
cannam@62 544 #endif // KJ_STD_COMPAT
cannam@62 545
cannam@62 546 #endif // CAPNP_LIST_H_