list.h 20.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Kenton Varda's avatar
Kenton Varda committed
24 25
#ifndef CAPNP_LIST_H_
#define CAPNP_LIST_H_
26

27
#include "layout.h"
28
#include "orphan.h"
29
#include <initializer_list>
30

31
namespace capnp {
32
namespace _ {  // private
33

34 35 36 37 38 39 40 41
template <typename T>
class TemporaryPointer {
  // This class is a little hack which lets us define operator->() in cases where it needs to
  // return a pointer to a temporary value.  We instead construct a TemporaryPointer and return that
  // (by value).  The compiler then invokes operator->() on the TemporaryPointer, which itself is
  // able to return a real pointer to its member.

public:
Kenton Varda's avatar
Kenton Varda committed
42
  TemporaryPointer(T&& value): value(kj::mv(value)) {}
43 44 45 46 47 48 49
  TemporaryPointer(const T& value): value(value) {}

  inline T* operator->() { return &value; }
private:
  T value;
};

Kenton Varda's avatar
Kenton Varda committed
50
template <typename Container, typename Element>
51 52 53 54
class IndexingIterator {
public:
  IndexingIterator() = default;

Kenton Varda's avatar
Kenton Varda committed
55 56
  inline Element operator*() const { return (*container)[index]; }
  inline TemporaryPointer<Element> operator->() const {
Kenton Varda's avatar
Kenton Varda committed
57 58
    return TemporaryPointer<Element>((*container)[index]);
  }
Kenton Varda's avatar
Kenton Varda committed
59 60
  inline Element operator[]( int off) const { return (*container)[index]; }
  inline Element operator[](uint off) const { return (*container)[index]; }
61 62 63 64 65 66

  inline IndexingIterator& operator++() { ++index; return *this; }
  inline IndexingIterator operator++(int) { IndexingIterator other = *this; ++index; return other; }
  inline IndexingIterator& operator--() { --index; return *this; }
  inline IndexingIterator operator--(int) { IndexingIterator other = *this; --index; return other; }

Kenton Varda's avatar
Kenton Varda committed
67 68 69 70
  inline IndexingIterator operator+(uint amount) const { return IndexingIterator(container, index + amount); }
  inline IndexingIterator operator-(uint amount) const { return IndexingIterator(container, index - amount); }
  inline IndexingIterator operator+( int amount) const { return IndexingIterator(container, index + amount); }
  inline IndexingIterator operator-( int amount) const { return IndexingIterator(container, index - amount); }
71

Kenton Varda's avatar
Kenton Varda committed
72
  inline int operator-(const IndexingIterator& other) const { return index - other.index; }
73 74 75 76 77 78 79 80

  inline IndexingIterator& operator+=(uint amount) { index += amount; return *this; }
  inline IndexingIterator& operator-=(uint amount) { index -= amount; return *this; }
  inline IndexingIterator& operator+=( int amount) { index += amount; return *this; }
  inline IndexingIterator& operator-=( int amount) { index -= amount; return *this; }

  // STL says comparing iterators of different containers is not allowed, so we only compare
  // indices here.
Kenton Varda's avatar
Kenton Varda committed
81 82 83 84 85 86
  inline bool operator==(const IndexingIterator& other) const { return index == other.index; }
  inline bool operator!=(const IndexingIterator& other) const { return index != other.index; }
  inline bool operator<=(const IndexingIterator& other) const { return index <= other.index; }
  inline bool operator>=(const IndexingIterator& other) const { return index >= other.index; }
  inline bool operator< (const IndexingIterator& other) const { return index <  other.index; }
  inline bool operator> (const IndexingIterator& other) const { return index >  other.index; }
87 88

private:
89
  Container* container;
90 91 92
  uint index;

  friend Container;
93
  inline IndexingIterator(Container* container, uint index)
94
      : container(container), index(index) {}
95 96
};

97
}  // namespace _ (private)
98 99

template <typename T>
100
struct List<T, Kind::PRIMITIVE> {
101 102
  // List of primitives.

103 104
  List() = delete;

105 106
  class Reader {
  public:
107 108
    typedef List<T> Reads;

109
    Reader() = default;
110
    inline explicit Reader(_::ListReader reader): reader(reader) {}
111

112 113 114 115
    inline uint size() const { return reader.size() / ELEMENTS; }
    inline T operator[](uint index) const {
      return reader.template getDataElement<T>(index * ELEMENTS);
    }
116

117
    typedef _::IndexingIterator<const Reader, T> Iterator;
118 119
    inline Iterator begin() const { return Iterator(this, 0); }
    inline Iterator end() const { return Iterator(this, size()); }
120 121

  private:
122
    _::ListReader reader;
123
    template <typename U, Kind K>
124
    friend struct _::PointerHelpers;
125 126
    template <typename U, Kind K>
    friend struct List;
127 128 129
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
130 131 132 133
  };

  class Builder {
  public:
134 135
    typedef List<T> Builds;

136
    Builder() = default;
137
    inline explicit Builder(_::ListBuilder builder): builder(builder) {}
138

139 140 141
    inline operator Reader() { return Reader(builder.asReader()); }
    inline Reader asReader() { return Reader(builder.asReader()); }

142
    inline uint size() const { return builder.size() / ELEMENTS; }
143
    inline T operator[](uint index) {
Kenton Varda's avatar
Kenton Varda committed
144 145 146 147 148 149 150 151 152 153 154
      return builder.template getDataElement<T>(index * ELEMENTS);
    }
    inline void set(uint index, T value) {
      // Alas, it is not possible to make operator[] return a reference to which you can assign,
      // since the encoded representation does not necessarily match the compiler's representation
      // of the type.  We can't even return a clever class that implements operator T() and
      // operator=() because it will lead to surprising behavior when using type inference (e.g.
      // calling a template function with inferred argument types, or using "auto" or "decltype").

      builder.template setDataElement<T>(index * ELEMENTS, value);
    }
155

156
    typedef _::IndexingIterator<Builder, T> Iterator;
157 158
    inline Iterator begin() { return Iterator(this, 0); }
    inline Iterator end() { return Iterator(this, size()); }
159

Kenton Varda's avatar
Kenton Varda committed
160
  private:
161
    _::ListBuilder builder;
162 163 164
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
Kenton Varda's avatar
Kenton Varda committed
165
  };
166 167

private:
168 169
  inline static _::ListBuilder initAsElementOf(
      _::ListBuilder& builder, uint index, uint size) {
170
    return builder.initListElement(
171
        index * ELEMENTS, _::ElementSizeForType<T>::value, size * ELEMENTS);
172
  }
173 174
  inline static _::ListBuilder getAsElementOf(
      _::ListBuilder& builder, uint index) {
175
    return builder.getListElement(index * ELEMENTS, _::ElementSizeForType<T>::value);
176
  }
177 178
  inline static _::ListReader getAsElementOf(
      const _::ListReader& reader, uint index) {
179
    return reader.getListElement(index * ELEMENTS, _::ElementSizeForType<T>::value);
180
  }
181

182 183
  inline static _::ListBuilder initAsFieldOf(
      _::StructBuilder& builder, WirePointerCount index, uint size) {
184
    return builder.initListField(index, _::ElementSizeForType<T>::value, size * ELEMENTS);
185
  }
186 187
  inline static _::ListBuilder getAsFieldOf(
      _::StructBuilder& builder, WirePointerCount index, const word* defaultValue) {
188
    return builder.getListField(index, _::ElementSizeForType<T>::value, defaultValue);
189
  }
190 191
  inline static _::ListReader getAsFieldOf(
      const _::StructReader& reader, WirePointerCount index, const word* defaultValue) {
192
    return reader.getListField(index, _::ElementSizeForType<T>::value, defaultValue);
193 194
  }

195
  template <typename U, Kind k>
Kenton Varda's avatar
Kenton Varda committed
196
  friend struct List;
197
  template <typename U, Kind K>
198
  friend struct _::PointerHelpers;
Kenton Varda's avatar
Kenton Varda committed
199 200 201
};

template <typename T>
202 203 204 205
struct List<T, Kind::ENUM>: public List<T, Kind::PRIMITIVE> {};

template <typename T>
struct List<T, Kind::STRUCT> {
206 207
  // List of structs.

208 209
  List() = delete;

Kenton Varda's avatar
Kenton Varda committed
210 211
  class Reader {
  public:
212 213
    typedef List<T> Reads;

Kenton Varda's avatar
Kenton Varda committed
214
    Reader() = default;
215
    inline explicit Reader(_::ListReader reader): reader(reader) {}
Kenton Varda's avatar
Kenton Varda committed
216

217 218
    inline uint size() const { return reader.size() / ELEMENTS; }
    inline typename T::Reader operator[](uint index) const {
219
      return typename T::Reader(reader.getStructElement(index * ELEMENTS));
Kenton Varda's avatar
Kenton Varda committed
220
    }
221

222
    typedef _::IndexingIterator<const Reader, typename T::Reader> Iterator;
223 224
    inline Iterator begin() const { return Iterator(this, 0); }
    inline Iterator end() const { return Iterator(this, size()); }
225

Kenton Varda's avatar
Kenton Varda committed
226
  private:
227
    _::ListReader reader;
228
    template <typename U, Kind K>
229
    friend struct _::PointerHelpers;
230 231
    template <typename U, Kind K>
    friend struct List;
232 233 234
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
Kenton Varda's avatar
Kenton Varda committed
235
  };
236

Kenton Varda's avatar
Kenton Varda committed
237 238
  class Builder {
  public:
239 240
    typedef List<T> Builds;

Kenton Varda's avatar
Kenton Varda committed
241
    Builder() = default;
242
    inline explicit Builder(_::ListBuilder builder): builder(builder) {}
243

244 245 246
    inline operator Reader() { return Reader(builder.asReader()); }
    inline Reader asReader() { return Reader(builder.asReader()); }

247
    inline uint size() const { return builder.size() / ELEMENTS; }
248
    inline typename T::Builder operator[](uint index) {
Kenton Varda's avatar
Kenton Varda committed
249
      return typename T::Builder(builder.getStructElement(index * ELEMENTS));
Kenton Varda's avatar
Kenton Varda committed
250
    }
251

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
    inline void adoptWithCaveats(uint index, Orphan<T>&& orphan) {
      // Mostly behaves like you'd expect `adopt` to behave, but with two caveats originating from
      // the fact that structs in a struct list are allocated inline rather than by pointer:
      // * This actually performs a shallow copy, effectively adopting each of the orphan's
      //   children rather than adopting the orphan itself.  The orphan ends up being discarded,
      //   possibly wasting space in the message object.
      // * If the orphan is larger than the target struct -- say, because the orphan was built
      //   using a newer version of the schema that has additional fields -- it will be truncated,
      //   losing data.

      // We pass a zero-valued StructSize to asStruct() because we do not want the struct to be
      // expanded under any circumstances.  We're just going to throw it away anyway, and
      // transferContentFrom() already carefully compares the struct sizes before transferring.
      builder.getStructElement(index * ELEMENTS).transferContentFrom(
          orphan.builder.asStruct(_::StructSize(
              0 * WORDS, 0 * POINTERS, _::FieldSize::VOID)));
    }
269 270 271 272 273 274 275 276 277
    inline void setWithCaveats(uint index, const typename T::Reader& reader) {
      // Mostly behaves like you'd expect `set` to behave, but with a caveat originating from
      // the fact that structs in a struct list are allocated inline rather than by pointer:
      // If the source struct is larger than the target struct -- say, because the source was built
      // using a newer version of the schema that has additional fields -- it will be truncated,
      // losing data.

      builder.getStructElement(index * ELEMENTS).copyContentFrom(reader._reader);
    }
278

279 280 281 282
    // There are no init(), set(), adopt(), or disown() methods for lists of structs because the
    // elements of the list are inlined and are initialized when the list is initialized.  This
    // means that init() would be redundant, and set() would risk data loss if the input struct
    // were from a newer version of the protocol.
283

284
    typedef _::IndexingIterator<Builder, typename T::Builder> Iterator;
285 286
    inline Iterator begin() { return Iterator(this, 0); }
    inline Iterator end() { return Iterator(this, size()); }
287 288

  private:
289
    _::ListBuilder builder;
290 291 292
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
293
  };
294 295

private:
296 297
  inline static _::ListBuilder initAsElementOf(
      _::ListBuilder& builder, uint index, uint size) {
298
    return builder.initStructListElement(
299
        index * ELEMENTS, size * ELEMENTS, _::structSize<T>());
300
  }
301 302 303
  inline static _::ListBuilder getAsElementOf(
      _::ListBuilder& builder, uint index) {
    return builder.getStructListElement(index * ELEMENTS, _::structSize<T>());
304
  }
305 306 307
  inline static _::ListReader getAsElementOf(
      const _::ListReader& reader, uint index) {
    return reader.getListElement(index * ELEMENTS, _::FieldSize::INLINE_COMPOSITE);
308
  }
309

310 311 312
  inline static _::ListBuilder initAsFieldOf(
      _::StructBuilder& builder, WirePointerCount index, uint size) {
    return builder.initStructListField(index, size * ELEMENTS, _::structSize<T>());
313
  }
314 315 316
  inline static _::ListBuilder getAsFieldOf(
      _::StructBuilder& builder, WirePointerCount index, const word* defaultValue) {
    return builder.getStructListField(index, _::structSize<T>(), defaultValue);
317
  }
318 319 320
  inline static _::ListReader getAsFieldOf(
      const _::StructReader& reader, WirePointerCount index, const word* defaultValue) {
    return reader.getListField(index, _::FieldSize::INLINE_COMPOSITE, defaultValue);
321 322
  }

323
  template <typename U, Kind k>
Kenton Varda's avatar
Kenton Varda committed
324
  friend struct List;
325
  template <typename U, Kind K>
326
  friend struct _::PointerHelpers;
327 328 329
};

template <typename T>
330
struct List<List<T>, Kind::LIST> {
331 332
  // List of lists.

333 334
  List() = delete;

335 336
  class Reader {
  public:
337 338
    typedef List<List<T>> Reads;

339
    Reader() = default;
340
    inline explicit Reader(_::ListReader reader): reader(reader) {}
341

342 343
    inline uint size() const { return reader.size() / ELEMENTS; }
    inline typename List<T>::Reader operator[](uint index) const {
344
      return typename List<T>::Reader(List<T>::getAsElementOf(reader, index));
Kenton Varda's avatar
Kenton Varda committed
345
    }
346

347
    typedef _::IndexingIterator<const Reader, typename List<T>::Reader> Iterator;
348 349
    inline Iterator begin() const { return Iterator(this, 0); }
    inline Iterator end() const { return Iterator(this, size()); }
350 351

  private:
352
    _::ListReader reader;
353
    template <typename U, Kind K>
354
    friend struct _::PointerHelpers;
355 356
    template <typename U, Kind K>
    friend struct List;
357 358 359
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
360 361 362 363
  };

  class Builder {
  public:
364 365
    typedef List<List<T>> Builds;

366
    Builder() = default;
367
    inline explicit Builder(_::ListBuilder builder): builder(builder) {}
368

369 370 371
    inline operator Reader() { return Reader(builder.asReader()); }
    inline Reader asReader() { return Reader(builder.asReader()); }

372
    inline uint size() const { return builder.size() / ELEMENTS; }
373
    inline typename List<T>::Builder operator[](uint index) {
374
      return typename List<T>::Builder(List<T>::getAsElementOf(builder, index));
Kenton Varda's avatar
Kenton Varda committed
375 376
    }
    inline typename List<T>::Builder init(uint index, uint size) {
377
      return typename List<T>::Builder(List<T>::initAsElementOf(builder, index, size));
Kenton Varda's avatar
Kenton Varda committed
378
    }
379 380 381 382 383 384 385 386 387 388
    inline void set(uint index, typename List<T>::Reader value) {
      builder.setListElement(index * ELEMENTS, value.reader);
    }
    void set(uint index, std::initializer_list<ReaderFor<T>> value) {
      auto l = init(index, value.size());
      uint i = 0;
      for (auto& element: value) {
        l.set(i++, element);
      }
    }
389 390 391 392 393 394
    inline void adopt(uint index, Orphan<T>&& value) {
      builder.adopt(index * ELEMENTS, kj::mv(value));
    }
    inline Orphan<T> disown(uint index) {
      return Orphan<T>(builder.disown(index * ELEMENTS));
    }
395

396
    typedef _::IndexingIterator<Builder, typename List<T>::Builder> Iterator;
397 398
    inline Iterator begin() { return Iterator(this, 0); }
    inline Iterator end() { return Iterator(this, size()); }
399

Kenton Varda's avatar
Kenton Varda committed
400
  private:
401
    _::ListBuilder builder;
402 403 404
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
Kenton Varda's avatar
Kenton Varda committed
405
  };
406 407

private:
408 409
  inline static _::ListBuilder initAsElementOf(
      _::ListBuilder& builder, uint index, uint size) {
410
    return builder.initListElement(
411
        index * ELEMENTS, _::FieldSize::POINTER, size * ELEMENTS);
412
  }
413 414 415
  inline static _::ListBuilder getAsElementOf(
      _::ListBuilder& builder, uint index) {
    return builder.getListElement(index * ELEMENTS, _::FieldSize::POINTER);
416
  }
417 418 419
  inline static _::ListReader getAsElementOf(
      const _::ListReader& reader, uint index) {
    return reader.getListElement(index * ELEMENTS, _::FieldSize::POINTER);
420
  }
421

422 423 424
  inline static _::ListBuilder initAsFieldOf(
      _::StructBuilder& builder, WirePointerCount index, uint size) {
    return builder.initListField(index, _::FieldSize::POINTER, size * ELEMENTS);
425
  }
426 427 428
  inline static _::ListBuilder getAsFieldOf(
      _::StructBuilder& builder, WirePointerCount index, const word* defaultValue) {
    return builder.getListField(index, _::FieldSize::POINTER, defaultValue);
429
  }
430 431 432
  inline static _::ListReader getAsFieldOf(
      const _::StructReader& reader, WirePointerCount index, const word* defaultValue) {
    return reader.getListField(index, _::FieldSize::POINTER, defaultValue);
433 434
  }

435
  template <typename U, Kind k>
Kenton Varda's avatar
Kenton Varda committed
436
  friend struct List;
437
  template <typename U, Kind K>
438
  friend struct _::PointerHelpers;
Kenton Varda's avatar
Kenton Varda committed
439 440
};

441 442
template <typename T>
struct List<T, Kind::BLOB> {
443 444
  List() = delete;

Kenton Varda's avatar
Kenton Varda committed
445 446
  class Reader {
  public:
447 448
    typedef List<T> Reads;

Kenton Varda's avatar
Kenton Varda committed
449
    Reader() = default;
450
    inline explicit Reader(_::ListReader reader): reader(reader) {}
Kenton Varda's avatar
Kenton Varda committed
451

452 453
    inline uint size() const { return reader.size() / ELEMENTS; }
    inline typename T::Reader operator[](uint index) const {
454
      return reader.getBlobElement<T>(index * ELEMENTS);
Kenton Varda's avatar
Kenton Varda committed
455 456
    }

457
    typedef _::IndexingIterator<const Reader, typename T::Reader> Iterator;
458 459
    inline Iterator begin() const { return Iterator(this, 0); }
    inline Iterator end() const { return Iterator(this, size()); }
Kenton Varda's avatar
Kenton Varda committed
460 461

  private:
462
    _::ListReader reader;
463
    template <typename U, Kind K>
464
    friend struct _::PointerHelpers;
465 466
    template <typename U, Kind K>
    friend struct List;
467 468 469
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
Kenton Varda's avatar
Kenton Varda committed
470 471 472 473
  };

  class Builder {
  public:
474 475
    typedef List<T> Builds;

Kenton Varda's avatar
Kenton Varda committed
476
    Builder() = default;
477
    inline explicit Builder(_::ListBuilder builder): builder(builder) {}
Kenton Varda's avatar
Kenton Varda committed
478

479 480 481
    inline operator Reader() { return Reader(builder.asReader()); }
    inline Reader asReader() { return Reader(builder.asReader()); }

482
    inline uint size() const { return builder.size() / ELEMENTS; }
483
    inline typename T::Builder operator[](uint index) {
484
      return builder.getBlobElement<T>(index * ELEMENTS);
Kenton Varda's avatar
Kenton Varda committed
485
    }
486 487
    inline void set(uint index, typename T::Reader value) {
      builder.setBlobElement<T>(index * ELEMENTS, value);
488
    }
489 490
    inline typename T::Builder init(uint index, uint size) {
      return builder.initBlobElement<T>(index * ELEMENTS, size * BYTES);
Kenton Varda's avatar
Kenton Varda committed
491
    }
492 493 494 495 496 497
    inline void adopt(uint index, Orphan<T>&& value) {
      builder.adopt(index * ELEMENTS, kj::mv(value));
    }
    inline Orphan<T> disown(uint index) {
      return Orphan<T>(builder.disown(index * ELEMENTS));
    }
Kenton Varda's avatar
Kenton Varda committed
498

499
    typedef _::IndexingIterator<Builder, typename T::Builder> Iterator;
500 501
    inline Iterator begin() { return Iterator(this, 0); }
    inline Iterator end() { return Iterator(this, size()); }
Kenton Varda's avatar
Kenton Varda committed
502 503

  private:
504
    _::ListBuilder builder;
505 506 507
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
Kenton Varda's avatar
Kenton Varda committed
508
  };
509 510

private:
511 512
  inline static _::ListBuilder initAsElementOf(
      _::ListBuilder& builder, uint index, uint size) {
513
    return builder.initListElement(
514
        index * ELEMENTS, _::FieldSize::POINTER, size * ELEMENTS);
515
  }
516 517 518
  inline static _::ListBuilder getAsElementOf(
      _::ListBuilder& builder, uint index) {
    return builder.getListElement(index * ELEMENTS, _::FieldSize::POINTER);
519
  }
520 521 522
  inline static _::ListReader getAsElementOf(
      const _::ListReader& reader, uint index) {
    return reader.getListElement(index * ELEMENTS, _::FieldSize::POINTER);
523
  }
524

525 526 527
  inline static _::ListBuilder initAsFieldOf(
      _::StructBuilder& builder, WirePointerCount index, uint size) {
    return builder.initListField(index, _::FieldSize::POINTER, size * ELEMENTS);
528
  }
529 530 531
  inline static _::ListBuilder getAsFieldOf(
      _::StructBuilder& builder, WirePointerCount index, const word* defaultValue) {
    return builder.getListField(index, _::FieldSize::POINTER, defaultValue);
532
  }
533 534 535
  inline static _::ListReader getAsFieldOf(
      const _::StructReader& reader, WirePointerCount index, const word* defaultValue) {
    return reader.getListField(index, _::FieldSize::POINTER, defaultValue);
536 537
  }

538
  template <typename U, Kind k>
Kenton Varda's avatar
Kenton Varda committed
539
  friend struct List;
540
  template <typename U, Kind K>
541
  friend struct _::PointerHelpers;
Kenton Varda's avatar
Kenton Varda committed
542 543
};

544
}  // namespace capnp
545

Kenton Varda's avatar
Kenton Varda committed
546
#endif  // CAPNP_LIST_H_