Commit ebce1a49 authored by Kenton Varda's avatar Kenton Varda

Implemented InlineData, added a bunch of tests for list of lists and such, and fixed tons of bugs.

parent 71afa600
......@@ -40,6 +40,11 @@ struct Text {
class Builder;
};
template <size_t size>
struct InlineData: public Data {};
// Alias for Data used specifically for InlineData fields. This primarily exists so that
// List<InlineData<n>> can be specialized.
class Data::Reader {
// Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple
// pointer which does not own its target, can be passed by value, etc.
......
......@@ -32,6 +32,30 @@ namespace capnproto {
namespace internal {
namespace {
template <typename T, typename U>
void checkList(T reader, std::initializer_list<U> expected) {
ASSERT_EQ(expected.size(), reader.size());
for (uint i = 0; i < expected.size(); i++) {
EXPECT_EQ(expected.begin()[i], reader[i]);
}
}
template <typename T>
void checkList(T reader, std::initializer_list<float> expected) {
ASSERT_EQ(expected.size(), reader.size());
for (uint i = 0; i < expected.size(); i++) {
EXPECT_FLOAT_EQ(expected.begin()[i], reader[i]);
}
}
template <typename T>
void checkList(T reader, std::initializer_list<double> expected) {
ASSERT_EQ(expected.size(), reader.size());
for (uint i = 0; i < expected.size(); i++) {
EXPECT_DOUBLE_EQ(expected.begin()[i], reader[i]);
}
}
TEST(Encoding, AllTypes) {
MallocMessageBuilder builder;
......@@ -495,270 +519,21 @@ TEST(Encoding, InitInlineStruct) {
TEST(Encoding, InlineDefaults) {
MallocMessageBuilder builder;
TestInlineDefaults::Reader reader = builder.getRoot<TestInlineDefaults>().asReader();
{
auto normal = reader.getNormal();
EXPECT_TRUE(normal.getF8().getF0());
EXPECT_FALSE(normal.getF8().getF1());
EXPECT_TRUE(normal.getF8().getF2());
EXPECT_EQ(123u, normal.getF16().getF0());
EXPECT_EQ(45u, normal.getF16().getF1());
EXPECT_EQ(67u, normal.getF32().getF0());
EXPECT_EQ(8901u, normal.getF32().getF1());
EXPECT_EQ(234u, normal.getF64().getF0());
EXPECT_EQ(567890123u, normal.getF64().getF1());
EXPECT_EQ(1234567890123ull, normal.getF128().getF0());
EXPECT_EQ(4567890123456ull, normal.getF128().getF1());
EXPECT_EQ(7890123456789ull, normal.getF192().getF0());
EXPECT_EQ(2345678901234ull, normal.getF192().getF1());
EXPECT_EQ(5678901234567ull, normal.getF192().getF2());
EXPECT_TRUE(normal.getF8p().getF().getF0());
EXPECT_TRUE(normal.getF8p().getF().getF1());
EXPECT_FALSE(normal.getF8p().getF().getF2());
EXPECT_EQ(98u, normal.getF16p().getF().getF0());
EXPECT_EQ(76u, normal.getF16p().getF().getF1());
EXPECT_EQ(54u, normal.getF32p().getF().getF0());
EXPECT_EQ(32109u, normal.getF32p().getF().getF1());
EXPECT_EQ(87u, normal.getF64p().getF().getF0());
EXPECT_EQ(654321098u, normal.getF64p().getF().getF1());
EXPECT_EQ(7654321098765ull, normal.getF128p().getF().getF0());
EXPECT_EQ(4321098765432ull, normal.getF128p().getF().getF1());
EXPECT_EQ(1098765432109ull, normal.getF192p().getF().getF0());
EXPECT_EQ(8765432109876ull, normal.getF192p().getF().getF1());
EXPECT_EQ(5432109876543ull, normal.getF192p().getF().getF2());
EXPECT_EQ("foo", normal.getF0p().getP0());
EXPECT_EQ("baz", normal.getF8p().getP0());
EXPECT_EQ("qux", normal.getF16p().getP0());
EXPECT_EQ("quux", normal.getF16p().getP1());
EXPECT_EQ("corge", normal.getF32p().getP0());
EXPECT_EQ("grault", normal.getF32p().getP1());
EXPECT_EQ("garply", normal.getF64p().getP0());
EXPECT_EQ("waldo", normal.getF64p().getP1());
EXPECT_EQ("fred", normal.getF128p().getP0());
EXPECT_EQ("plugh", normal.getF128p().getP1());
EXPECT_EQ("xyzzy", normal.getF128p().getP2());
EXPECT_EQ("thud", normal.getF192p().getP0());
EXPECT_EQ("foobar", normal.getF192p().getP1());
EXPECT_EQ("barbaz", normal.getF192p().getP2());
}
TestInlineDefaults::Builder root = builder.getRoot<TestInlineDefaults>();
{
auto unions = reader.getUnions();
ASSERT_EQ(TestInlineUnions::Union0::F32, unions.getUnion0().which());
EXPECT_EQ(67u, unions.getUnion0().getF32().getF0());
EXPECT_EQ(8901u, unions.getUnion0().getF32().getF1());
ASSERT_EQ(TestInlineUnions::Union1::F128, unions.getUnion1().which());
EXPECT_EQ(1234567890123ull, unions.getUnion1().getF128().getF0());
EXPECT_EQ(4567890123456ull, unions.getUnion1().getF128().getF1());
ASSERT_EQ(TestInlineUnions::Union3::F16P, unions.getUnion3().which());
EXPECT_EQ(98u, unions.getUnion3().getF16p().getF().getF0());
EXPECT_EQ(76u, unions.getUnion3().getF16p().getF().getF1());
EXPECT_EQ("qux", unions.getUnion3().getF16p().getP0());
EXPECT_EQ("quux", unions.getUnion3().getF16p().getP1());
}
checkTestMessage(root.asReader());
checkTestMessage(root);
checkTestMessage(root.asReader());
}
{
auto lists = reader.getLists();
ASSERT_EQ(2u, lists.getVoidList().size());
ASSERT_EQ(3u, lists.getBoolList().size());
ASSERT_EQ(4u, lists.getUInt8List().size());
ASSERT_EQ(5u, lists.getUInt16List().size());
ASSERT_EQ(6u, lists.getUInt32List().size());
ASSERT_EQ(7u, lists.getUInt64List().size());
ASSERT_EQ(8u, lists.getTextList().size());
ASSERT_EQ(2u, lists.getStructList0().size());
ASSERT_EQ(3u, lists.getStructList1().size());
ASSERT_EQ(4u, lists.getStructList8().size());
ASSERT_EQ(2u, lists.getStructList16().size());
ASSERT_EQ(3u, lists.getStructList32().size());
ASSERT_EQ(4u, lists.getStructList64().size());
ASSERT_EQ(2u, lists.getStructList128().size());
ASSERT_EQ(3u, lists.getStructList192().size());
ASSERT_EQ(4u, lists.getStructList0p().size());
ASSERT_EQ(2u, lists.getStructList1p().size());
ASSERT_EQ(3u, lists.getStructList8p().size());
ASSERT_EQ(4u, lists.getStructList16p().size());
ASSERT_EQ(2u, lists.getStructList32p().size());
ASSERT_EQ(3u, lists.getStructList64p().size());
ASSERT_EQ(4u, lists.getStructList128p().size());
ASSERT_EQ(2u, lists.getStructList192p().size());
EXPECT_EQ(Void::VOID, lists.getVoidList()[0]);
EXPECT_EQ(Void::VOID, lists.getVoidList()[1]);
EXPECT_FALSE(lists.getBoolList()[0]);
EXPECT_TRUE(lists.getBoolList()[1]);
EXPECT_FALSE(lists.getBoolList()[2]);
EXPECT_EQ(12u, lists.getUInt8List()[0]);
EXPECT_EQ(34u, lists.getUInt8List()[1]);
EXPECT_EQ(56u, lists.getUInt8List()[2]);
EXPECT_EQ(78u, lists.getUInt8List()[3]);
EXPECT_EQ(1234u, lists.getUInt16List()[0]);
EXPECT_EQ(5678u, lists.getUInt16List()[1]);
EXPECT_EQ(9012u, lists.getUInt16List()[2]);
EXPECT_EQ(3456u, lists.getUInt16List()[3]);
EXPECT_EQ(7890u, lists.getUInt16List()[4]);
EXPECT_EQ(123456789u, lists.getUInt32List()[0]);
EXPECT_EQ(234567890u, lists.getUInt32List()[1]);
EXPECT_EQ(345678901u, lists.getUInt32List()[2]);
EXPECT_EQ(456789012u, lists.getUInt32List()[3]);
EXPECT_EQ(567890123u, lists.getUInt32List()[4]);
EXPECT_EQ(678901234u, lists.getUInt32List()[5]);
for (uint i = 0; i < 7; i++) {
EXPECT_EQ(i + 1, lists.getUInt64List()[i]);
}
EXPECT_EQ("foo", lists.getTextList()[0]);
EXPECT_EQ("bar", lists.getTextList()[1]);
EXPECT_EQ("baz", lists.getTextList()[2]);
EXPECT_EQ("qux", lists.getTextList()[3]);
EXPECT_EQ("quux", lists.getTextList()[4]);
EXPECT_EQ("corge", lists.getTextList()[5]);
EXPECT_EQ("grault", lists.getTextList()[6]);
EXPECT_EQ("garply", lists.getTextList()[7]);
EXPECT_EQ(Void::VOID, lists.getStructList0()[0].getF());
EXPECT_EQ(Void::VOID, lists.getStructList0()[1].getF());
EXPECT_TRUE (lists.getStructList8()[0].getF0());
EXPECT_FALSE(lists.getStructList8()[0].getF1());
EXPECT_FALSE(lists.getStructList8()[0].getF2());
EXPECT_FALSE(lists.getStructList8()[1].getF0());
EXPECT_TRUE (lists.getStructList8()[1].getF1());
EXPECT_FALSE(lists.getStructList8()[1].getF2());
EXPECT_TRUE (lists.getStructList8()[2].getF0());
EXPECT_TRUE (lists.getStructList8()[2].getF1());
EXPECT_FALSE(lists.getStructList8()[2].getF2());
EXPECT_FALSE(lists.getStructList8()[3].getF0());
EXPECT_FALSE(lists.getStructList8()[3].getF1());
EXPECT_TRUE (lists.getStructList8()[3].getF2());
EXPECT_EQ(12u, lists.getStructList16()[0].getF0());
EXPECT_EQ(34u, lists.getStructList16()[0].getF1());
EXPECT_EQ(56u, lists.getStructList16()[1].getF0());
EXPECT_EQ(78u, lists.getStructList16()[1].getF1());
EXPECT_EQ(90u, lists.getStructList32()[0].getF0());
EXPECT_EQ(12345u, lists.getStructList32()[0].getF1());
EXPECT_EQ(67u, lists.getStructList32()[1].getF0());
EXPECT_EQ(8901u, lists.getStructList32()[1].getF1());
EXPECT_EQ(23u, lists.getStructList32()[2].getF0());
EXPECT_EQ(45678u, lists.getStructList32()[2].getF1());
EXPECT_EQ(90u, lists.getStructList64()[0].getF0());
EXPECT_EQ(123456789u, lists.getStructList64()[0].getF1());
EXPECT_EQ(12u, lists.getStructList64()[1].getF0());
EXPECT_EQ(345678901u, lists.getStructList64()[1].getF1());
EXPECT_EQ(234u, lists.getStructList64()[2].getF0());
EXPECT_EQ(567890123u, lists.getStructList64()[2].getF1());
EXPECT_EQ(45u, lists.getStructList64()[3].getF0());
EXPECT_EQ(678901234u, lists.getStructList64()[3].getF1());
EXPECT_EQ(56789012345678ull, lists.getStructList128()[0].getF0());
EXPECT_EQ(90123456789012ull, lists.getStructList128()[0].getF1());
EXPECT_EQ(34567890123456ull, lists.getStructList128()[1].getF0());
EXPECT_EQ(78901234567890ull, lists.getStructList128()[1].getF1());
EXPECT_EQ(1234567890123ull, lists.getStructList192()[0].getF0());
EXPECT_EQ(4567890123456ull, lists.getStructList192()[0].getF1());
EXPECT_EQ(7890123456789ull, lists.getStructList192()[0].getF2());
EXPECT_EQ( 123456789012ull, lists.getStructList192()[1].getF0());
EXPECT_EQ(3456789012345ull, lists.getStructList192()[1].getF1());
EXPECT_EQ(6789012345678ull, lists.getStructList192()[1].getF2());
EXPECT_EQ(9012345678901ull, lists.getStructList192()[2].getF0());
EXPECT_EQ(2345678901234ull, lists.getStructList192()[2].getF1());
EXPECT_EQ(5678901234567ull, lists.getStructList192()[2].getF2());
EXPECT_EQ("foo", lists.getStructList0p()[0].getP0());
EXPECT_EQ("bar", lists.getStructList0p()[1].getP0());
EXPECT_EQ("baz", lists.getStructList0p()[2].getP0());
EXPECT_EQ("qux", lists.getStructList0p()[3].getP0());
EXPECT_TRUE(lists.getStructList8p()[0].getF().getF0());
EXPECT_EQ("grault", lists.getStructList8p()[0].getP0());
EXPECT_EQ("garply", lists.getStructList8p()[1].getP0());
EXPECT_EQ("waldo", lists.getStructList8p()[2].getP0());
EXPECT_EQ(123u, lists.getStructList16p()[0].getF().getF0());
EXPECT_EQ("fred", lists.getStructList16p()[0].getP0());
EXPECT_EQ("plugh", lists.getStructList16p()[0].getP1());
EXPECT_EQ("xyzzy", lists.getStructList16p()[1].getP0());
EXPECT_EQ("thud", lists.getStructList16p()[1].getP1());
EXPECT_EQ("foobar", lists.getStructList16p()[2].getP0());
EXPECT_EQ("barbaz", lists.getStructList16p()[2].getP1());
EXPECT_EQ("bazqux", lists.getStructList16p()[3].getP0());
EXPECT_EQ("quxquux", lists.getStructList16p()[3].getP1());
EXPECT_EQ(12345u, lists.getStructList32p()[0].getF().getF1());
EXPECT_EQ("quuxcorge", lists.getStructList32p()[0].getP0());
EXPECT_EQ("corgegrault", lists.getStructList32p()[0].getP1());
EXPECT_EQ("graultgarply", lists.getStructList32p()[1].getP0());
EXPECT_EQ("garplywaldo", lists.getStructList32p()[1].getP1());
EXPECT_EQ(123456789u, lists.getStructList64p()[0].getF().getF1());
EXPECT_EQ("waldofred", lists.getStructList64p()[0].getP0());
EXPECT_EQ("fredplugh", lists.getStructList64p()[0].getP1());
EXPECT_EQ("plughxyzzy", lists.getStructList64p()[1].getP0());
EXPECT_EQ("xyzzythud", lists.getStructList64p()[1].getP1());
EXPECT_EQ("thudfoo", lists.getStructList64p()[2].getP0());
EXPECT_EQ("foofoo", lists.getStructList64p()[2].getP1());
EXPECT_EQ(123456789012345ull, lists.getStructList128p()[0].getF().getF1());
EXPECT_EQ("foobaz", lists.getStructList128p()[0].getP0());
EXPECT_EQ("fooqux", lists.getStructList128p()[0].getP1());
EXPECT_EQ("foocorge", lists.getStructList128p()[0].getP2());
EXPECT_EQ("barbaz", lists.getStructList128p()[1].getP0());
EXPECT_EQ("barqux", lists.getStructList128p()[1].getP1());
EXPECT_EQ("barcorge", lists.getStructList128p()[1].getP2());
EXPECT_EQ("bazbaz", lists.getStructList128p()[2].getP0());
EXPECT_EQ("bazqux", lists.getStructList128p()[2].getP1());
EXPECT_EQ("bazcorge", lists.getStructList128p()[2].getP2());
EXPECT_EQ("quxbaz", lists.getStructList128p()[3].getP0());
EXPECT_EQ("quxqux", lists.getStructList128p()[3].getP1());
EXPECT_EQ("quxcorge", lists.getStructList128p()[3].getP2());
EXPECT_EQ(123456789012345ull, lists.getStructList192p()[0].getF().getF2());
EXPECT_EQ("corgebaz", lists.getStructList192p()[0].getP0());
EXPECT_EQ("corgequx", lists.getStructList192p()[0].getP1());
EXPECT_EQ("corgecorge", lists.getStructList192p()[0].getP2());
EXPECT_EQ("graultbaz", lists.getStructList192p()[1].getP0());
EXPECT_EQ("graultqux", lists.getStructList192p()[1].getP1());
EXPECT_EQ("graultcorge", lists.getStructList192p()[1].getP2());
}
TEST(Encoding, BuildInlineDefaults) {
MallocMessageBuilder builder;
TestInlineDefaults::Builder root = builder.getRoot<TestInlineDefaults>();
{
auto sl = reader.getStructLists();
ASSERT_EQ(2u, sl.getList0().size());
ASSERT_EQ(2u, sl.getList1().size());
ASSERT_EQ(2u, sl.getList8().size());
ASSERT_EQ(2u, sl.getList16().size());
ASSERT_EQ(2u, sl.getList32().size());
ASSERT_EQ(2u, sl.getList64().size());
ASSERT_EQ(2u, sl.getListP().size());
EXPECT_EQ(Void::VOID, sl.getList0()[0].getF());
EXPECT_EQ(Void::VOID, sl.getList0()[1].getF());
EXPECT_TRUE(sl.getList1()[0].getF());
EXPECT_FALSE(sl.getList1()[1].getF());
EXPECT_EQ(123u, sl.getList8()[0].getF());
EXPECT_EQ(45u, sl.getList8()[1].getF());
EXPECT_EQ(12345u, sl.getList16()[0].getF());
EXPECT_EQ(6789u, sl.getList16()[1].getF());
EXPECT_EQ(123456789u, sl.getList32()[0].getF());
EXPECT_EQ(234567890u, sl.getList32()[1].getF());
EXPECT_EQ(1234567890123456u, sl.getList64()[0].getF());
EXPECT_EQ(2345678901234567u, sl.getList64()[1].getF());
EXPECT_EQ("foo", sl.getListP()[0].getF());
EXPECT_EQ("bar", sl.getListP()[1].getF());
}
initTestMessage(root);
checkTestMessage(root.asReader());
checkTestMessage(root);
checkTestMessage(root.asReader());
}
TEST(Encoding, SmallStructLists) {
......
......@@ -26,6 +26,8 @@
#include "util.h"
#include "logging.h"
#include <unistd.h>
#include <execinfo.h>
#include <stdlib.h>
namespace capnproto {
......@@ -59,10 +61,15 @@ Exception::Exception(Nature nature, Durability durability, const char* file, int
description(move(description)) {
bool hasDescription = this->description != nullptr;
void* trace[16];
int traceCount = backtrace(trace, 16);
ArrayPtr<void*> traceArray = arrayPtr(trace, traceCount);
// Must be careful to NUL-terminate this.
whatStr = str(file, ":", line, ": ", nature,
durability == Durability::TEMPORARY ? " (temporary)" : "",
hasDescription ? ": " : "", this->description, '\0');
hasDescription ? ": " : "", this->description,
"\nstack: ", strArray(traceArray, " "), '\0');
}
Exception::Exception(const Exception& other) noexcept
......
......@@ -364,6 +364,14 @@ public:
const void* defaultValue, ByteCount defaultSize) const;
// Same as *Text*, but for data blobs.
CAPNPROTO_ALWAYS_INLINE(Data::Builder getInlineDataField(
ByteCount offset, ByteCount size) const);
CAPNPROTO_ALWAYS_INLINE(void setInlineDataField(
ByteCount offset, ByteCount size, Data::Reader value) const);
CAPNPROTO_ALWAYS_INLINE(Data::Builder initInlineDataField(
ByteCount offset, ByteCount size) const);
// For InlineData.
StructReader asReader() const;
// Gets a StructReader pointing at the same memory.
......@@ -445,6 +453,10 @@ public:
const void* defaultValue, ByteCount defaultSize) const;
// Gets the data field, or the given default value if not initialized.
CAPNPROTO_ALWAYS_INLINE(Data::Reader getInlineDataField(
ByteCount offset, ByteCount size) const);
// Gets the inline data field.
WireReferenceCount getReferenceCount() { return referenceCount; }
private:
......@@ -509,6 +521,10 @@ public:
// Get the existing list element at the given index. Returns an empty list if the element is
// not initialized.
CAPNPROTO_ALWAYS_INLINE(ListBuilder slice(ElementCount start, ElementCount length) const);
// Get a list pointing at a slice of this list. WARNING: The second parameter is a length, not
// an end index, because this is what is most convenient at the only call site.
Text::Builder initTextElement(ElementCount index, ByteCount size) const;
// Initialize the text element to the given size in bytes (not including NUL terminator) and
// return a Text::Builder which can be used to fill in the content.
......@@ -522,6 +538,7 @@ public:
Data::Builder initDataElement(ElementCount index, ByteCount size) const;
void setDataElement(ElementCount index, Data::Reader value) const;
Data::Builder getDataElement(ElementCount index) const;
// Like *Text*() but for Data.
ListReader asReader(FieldSize elementSize) const;
// Get a ListReader pointing at the same memory. Use this version only for non-struct lists.
......@@ -573,6 +590,10 @@ public:
ListReader getListElement(ElementCount index, FieldSize expectedElementSize) const;
// Get the list element at the given index.
CAPNPROTO_ALWAYS_INLINE(ListReader slice(ElementCount start, ElementCount length) const);
// Get a list pointing at a slice of this list. WARNING: The second parameter is a length, not
// an end index, because this is what is most convenient at the only call site.
Text::Reader getTextElement(ElementCount index) const;
// Get the text element. If it is not initialized, returns an empty Text::Reader.
......@@ -741,6 +762,22 @@ inline ListBuilder StructBuilder::getInlineStructListField(
elementCount);
}
inline Data::Builder StructBuilder::getInlineDataField(
ByteCount offset, ByteCount size) const {
return Data::Builder(
reinterpret_cast<char*>(reinterpret_cast<byte*>(data) + offset), size / BYTES);
}
inline void StructBuilder::setInlineDataField(
ByteCount offset, ByteCount size, Data::Reader value) const {
getInlineDataField(offset, size).copyFrom(value);
}
inline Data::Builder StructBuilder::initInlineDataField(
ByteCount offset, ByteCount size) const {
byte* ptr = reinterpret_cast<byte*>(data) + offset;
memset(ptr, 0, size / BYTES);
return Data::Builder(reinterpret_cast<char*>(ptr), size / BYTES);
}
// -------------------------------------------------------------------
template <typename T>
......@@ -776,17 +813,20 @@ T StructReader::getDataField(ElementCount offset, typename MaskType<T>::Type mas
inline StructReader StructReader::getInlineStructField(
ByteCount dataOffset, ByteCount inlineDataSize,
WireReferenceCount refIndex, WireReferenceCount inlineRefCount) const {
// TODO(soon): Too complicated to be inlined?
return StructReader(
segment, reinterpret_cast<const byte*>(data) + dataOffset,
// WireReference is incomplete here so we have to cast around... Bah.
reinterpret_cast<const WireReference*>(
reinterpret_cast<const word*>(references) + refIndex * WORDS_PER_REFERENCE),
dataSize, inlineRefCount,
inlineDataSize * (dataOffset + inlineDataSize <= dataSize),
inlineRefCount * (refIndex + inlineRefCount <= referenceCount),
nestingLimit);
}
inline ListReader StructReader::getInlineDataListField(
ByteCount offset, ElementCount elementCount, FieldSize elementSize) const {
// TODO(soon): Bounds check! Needs to fall back to some common zero'd region.
return ListReader(
segment, reinterpret_cast<const byte*>(data) + offset, nullptr,
elementCount, bytesPerElement(elementSize), 0 * REFERENCES / ELEMENTS,
......@@ -795,6 +835,7 @@ inline ListReader StructReader::getInlineDataListField(
inline ListReader StructReader::getInlinePointerListField(
WireReferenceCount offset, ElementCount elementCount) const {
// TODO(soon): Bounds check! Needs to fall back to some common zero'd region.
return ListReader(
segment, nullptr,
reinterpret_cast<const WireReference*>(
......@@ -806,6 +847,7 @@ inline ListReader StructReader::getInlinePointerListField(
inline ListReader StructReader::getInlineStructListField(
ByteCount dataOffset, WireReferenceCount ptrOffset, ElementCount elementCount,
StructSize elementSize) const {
// TODO(soon): Bounds check! Needs to fall back to some common zero'd region.
return ListReader(
segment, reinterpret_cast<const byte*>(data) + dataOffset,
reinterpret_cast<const WireReference*>(
......@@ -814,6 +856,12 @@ inline ListReader StructReader::getInlineStructListField(
elementSize.dataBytes, elementSize.pointers, nestingLimit);
}
inline Data::Reader StructReader::getInlineDataField(ByteCount offset, ByteCount size) const {
// TODO(soon): Bounds check! Needs to fall back to some common zero'd region.
return Data::Reader(reinterpret_cast<const char*>(reinterpret_cast<const byte*>(data) + offset),
size / BYTES);
}
// -------------------------------------------------------------------
inline ElementCount ListBuilder::size() { return elementCount; }
......@@ -856,6 +904,14 @@ inline void ListBuilder::setDataElement<bool>(ElementCount index, bool value) co
template <>
inline void ListBuilder::setDataElement<Void>(ElementCount index, Void value) const {}
inline ListBuilder ListBuilder::slice(ElementCount start, ElementCount length) const {
return ListBuilder(segment,
reinterpret_cast<byte*>(data) + start * stepBytes,
reinterpret_cast<WireReference*>(
reinterpret_cast<word*>(pointers) + start * stepPointers * WORDS_PER_REFERENCE),
stepBytes, stepPointers, length);
}
// -------------------------------------------------------------------
inline ElementCount ListReader::size() { return elementCount; }
......@@ -879,6 +935,14 @@ inline Void ListReader::getDataElement<Void>(ElementCount index) const {
return Void::VOID;
}
inline ListReader ListReader::slice(ElementCount start, ElementCount length) const {
return ListReader(segment,
reinterpret_cast<const byte*>(data) + start * stepBytes,
reinterpret_cast<const WireReference*>(
reinterpret_cast<const word*>(pointers) + start * stepPointers * WORDS_PER_REFERENCE),
length, stepBytes, stepPointers, structDataSize, structReferenceCount, nestingLimit);
}
} // namespace internal
} // namespace capnproto
......
......@@ -48,6 +48,10 @@ public:
template <typename T, bool isPrimitive = internal::IsPrimitive<T>::value>
struct List;
template <typename T, size_t size>
struct InlineList: public List<T> {};
// Alias for List. Primarily exists so that we can specialize List<InlineList<...>>.
namespace internal {
template <size_t size> struct FieldSizeForByteSize;
......@@ -146,6 +150,8 @@ private:
template <typename T>
struct List<T, true> {
// List of primitives.
class Reader {
public:
Reader() = default;
......@@ -207,10 +213,29 @@ struct List<T, true> {
private:
internal::ListBuilder builder;
};
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initListElement(
index * ELEMENTS, internal::FieldSizeForType<T>::value, size * ELEMENTS);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSizeForType<T>::value);
}
template <typename U, bool b>
friend class List;
};
template <typename T>
struct List<T, false> {
// List of structs.
class Reader {
public:
Reader() = default;
......@@ -251,10 +276,29 @@ struct List<T, false> {
private:
internal::ListBuilder builder;
};
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initStructListElement(
index * ELEMENTS, size * ELEMENTS, T::STRUCT_SIZE);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSize::INLINE_COMPOSITE);
}
template <typename U, bool b>
friend class List;
};
template <typename T>
struct List<List<T>, true> {
struct List<List<T>, false> {
// List of lists.
class Reader {
public:
Reader() = default;
......@@ -262,8 +306,7 @@ struct List<List<T>, true> {
inline uint size() { return reader.size() / ELEMENTS; }
inline typename List<T>::Reader operator[](uint index) {
return typename List<T>::Reader(reader.getListElement(index * REFERENCES,
internal::FieldSizeForType<T>::value));
return typename List<T>::Reader(List<T>::getAsElementOf(reader, index));
}
typedef internal::IndexingIterator<Reader, typename List<T>::Reader> iterator;
......@@ -281,11 +324,10 @@ struct List<List<T>, true> {
inline uint size() { return builder.size() / ELEMENTS; }
inline typename List<T>::Builder operator[](uint index) {
return typename List<T>::Builder(builder.getListElement(index * ELEMENTS));
return typename List<T>::Builder(List<T>::getAsElementOf(builder, index));
}
inline typename List<T>::Builder init(uint index, uint size) {
return typename List<T>::Builder(builder.initListElement(
index * ELEMENTS, internal::FieldSizeForType<T>::value, size * ELEMENTS));
return typename List<T>::Builder(List<T>::initAsElementOf(builder, index, size));
}
typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator;
......@@ -300,19 +342,38 @@ struct List<List<T>, true> {
private:
internal::ListBuilder builder;
};
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initListElement(
index * ELEMENTS, internal::FieldSize::REFERENCE, size * ELEMENTS);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSize::REFERENCE);
}
template <typename U, bool b>
friend class List;
};
template <typename T>
struct List<List<T>, false> {
template <typename T, size_t subSize>
struct List<InlineList<T, subSize>, false> {
// List of inline lists.
class Reader {
public:
Reader() = default;
inline explicit Reader(internal::ListReader reader): reader(reader) {}
inline uint size() { return reader.size() / ELEMENTS; }
inline uint size() { return reader.size() / ELEMENTS / subSize; }
inline typename List<T>::Reader operator[](uint index) {
return typename List<T>::Reader(reader.getListElement(index * ELEMENTS,
internal::FieldSizeForType<T>::value));
return typename List<T>::Reader(reader.slice(
index * subSize * ELEMENTS, subSize * ELEMENTS));
}
typedef internal::IndexingIterator<Reader, typename List<T>::Reader> iterator;
......@@ -328,13 +389,10 @@ struct List<List<T>, false> {
Builder() = default;
inline explicit Builder(internal::ListBuilder builder): builder(builder) {}
inline uint size() { return builder.size() / ELEMENTS; }
inline uint size() { return builder.size() / ELEMENTS / subSize; }
inline typename List<T>::Builder operator[](uint index) {
return typename List<T>::Builder(builder.getListElement(index * ELEMENTS));
}
inline typename List<T>::Builder init(uint index, uint size) {
return typename List<T>::Builder(builder.initStructListElement(
index * ELEMENTS, size * ELEMENTS, T::DEFAULT.words));
return typename List<T>::Builder(builder.slice(
index * subSize * ELEMENTS, subSize * ELEMENTS));
}
typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator;
......@@ -349,6 +407,22 @@ struct List<List<T>, false> {
private:
internal::ListBuilder builder;
};
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return List<T>::initAsElementOf(builder, index, size * subSize);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSizeForType<T>::value);
}
template <typename U, bool b>
friend class List;
};
template <>
......@@ -413,6 +487,104 @@ struct List<Data, false> {
private:
internal::ListBuilder builder;
};
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initListElement(
index * ELEMENTS, internal::FieldSize::REFERENCE, size * ELEMENTS);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSize::REFERENCE);
}
template <typename U, bool b>
friend class List;
};
template <size_t subSize>
struct List<InlineData<subSize>, false> {
// List of inline lists.
class Reader {
public:
Reader() = default;
inline explicit Reader(Data::Reader reader): reader(reader) {}
inline uint size() { return reader.size() / subSize; }
inline typename Data::Reader operator[](uint index) {
return typename Data::Reader(reader.slice(
index * subSize, index * subSize + subSize));
}
typedef internal::IndexingIterator<Reader, typename Data::Reader> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
private:
Data::Reader reader;
};
class Builder {
public:
Builder() = default;
inline explicit Builder(Data::Builder builder): builder(builder) {}
inline uint size() { return builder.size() / subSize; }
inline typename Data::Builder operator[](uint index) {
return typename Data::Builder(builder.slice(
index * subSize, index * subSize + subSize));
}
inline void set(uint index, Data::Reader value) {
(*this)[index].copyFrom(value);
}
typedef internal::IndexingIterator<Builder, typename Data::Builder> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
template <typename Other>
void copyFrom(const Other& other) {
auto i = other.begin();
auto end = other.end();
uint pos = 0;
for (; i != end && pos < size(); ++i) {
set(pos, *i);
}
CAPNPROTO_INLINE_DPRECOND(pos == size() && i == end,
"List::copyFrom() argument had different size.");
}
void copyFrom(std::initializer_list<Data::Reader> other) {
CAPNPROTO_INLINE_DPRECOND(other.size() == size(),
"List::copyFrom() argument had different size.");
for (uint i = 0; i < other.size(); i++) {
set(i, other.begin()[i]);
}
}
private:
Data::Builder builder;
};
private:
inline static Data::Builder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initDataElement(index * ELEMENTS, size * subSize * BYTES);
}
inline static Data::Builder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getDataElement(index * ELEMENTS);
}
inline static Data::Reader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getDataElement(index * ELEMENTS);
}
template <typename U, bool b>
friend class List;
};
template <>
......@@ -477,6 +649,23 @@ struct List<Text, false> {
private:
internal::ListBuilder builder;
};
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initListElement(
index * ELEMENTS, internal::FieldSize::REFERENCE, size * ELEMENTS);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSize::REFERENCE);
}
template <typename U, bool b>
friend class List;
};
} // namespace capnproto
......
......@@ -45,13 +45,27 @@ public:
void onRecoverableException(Exception&& exception) override {
text += "recoverable exception: ";
text += exception.what();
// Only take the first line of "what" because the second line is a stack trace.
const char* what = exception.what();
const char* end = strchr(what, '\n');
if (end == nullptr) {
text += exception.what();
} else {
text.append(what, end);
}
text += '\n';
}
void onFatalException(Exception&& exception) override {
text += "fatal exception: ";
text += exception.what();
// Only take the first line of "what" because the second line is a stack trace.
const char* what = exception.what();
const char* end = strchr(what, '\n');
if (end == nullptr) {
text += exception.what();
} else {
text.append(what, end);
}
text += '\n';
throw MockException();
}
......
......@@ -324,16 +324,847 @@ void genericCheckTestMessageAllZero(Reader reader) {
EXPECT_EQ(0u, reader.getStructList().size());
}
template <typename Builder>
void genericInitInlineDefaults(Builder builder) {
{
auto normal = builder.initNormal();
normal.getF8().setF0(true);
normal.getF8().setF1(false);
normal.getF8().setF2(true);
normal.getF16().setF0(123u);
normal.getF16().setF1(45u);
normal.getF32().setF0(67u);
normal.getF32().setF1(8901u);
normal.getF64().setF0(234u);
normal.getF64().setF1(567890123u);
normal.getF128().setF0(1234567890123ull);
normal.getF128().setF1(4567890123456ull);
normal.getF192().setF0(7890123456789ull);
normal.getF192().setF1(2345678901234ull);
normal.getF192().setF2(5678901234567ull);
normal.getF8p().getF().setF0(true);
normal.getF8p().getF().setF1(true);
normal.getF8p().getF().setF2(false);
normal.getF16p().getF().setF0(98u);
normal.getF16p().getF().setF1(76u);
normal.getF32p().getF().setF0(54u);
normal.getF32p().getF().setF1(32109u);
normal.getF64p().getF().setF0(87u);
normal.getF64p().getF().setF1(654321098u);
normal.getF128p().getF().setF0(7654321098765ull);
normal.getF128p().getF().setF1(4321098765432ull);
normal.getF192p().getF().setF0(1098765432109ull);
normal.getF192p().getF().setF1(8765432109876ull);
normal.getF192p().getF().setF2(5432109876543ull);
normal.getF0p().setP0("foo");
normal.getF8p().setP0("baz");
normal.getF16p().setP0("qux");
normal.getF16p().setP1("quux");
normal.getF32p().setP0("corge");
normal.getF32p().setP1("grault");
normal.getF64p().setP0("garply");
normal.getF64p().setP1("waldo");
normal.getF128p().setP0("fred");
normal.getF128p().setP1("plugh");
normal.getF128p().setP2("xyzzy");
normal.getF192p().setP0("thud");
normal.getF192p().setP1("foobar");
normal.getF192p().setP2("barbaz");
}
{
auto unions = builder.initUnions();
unions.getUnion0().initF32().setF0(67u);
unions.getUnion0().getF32().setF1(8901u);
unions.getUnion1().initF128().setF0(1234567890123ull);
unions.getUnion1().getF128().setF1(4567890123456ull);
unions.getUnion3().initF16p().getF().setF0(98u);
unions.getUnion3().getF16p().getF().setF1(76u);
unions.getUnion3().getF16p().setP0("qux");
unions.getUnion3().getF16p().setP1("quux");
}
{
auto lists = builder.initLists();
ASSERT_EQ(2u, lists.getVoidList().size());
ASSERT_EQ(3u, lists.getBoolList().size());
ASSERT_EQ(4u, lists.getUInt8List().size());
ASSERT_EQ(5u, lists.getUInt16List().size());
ASSERT_EQ(6u, lists.getUInt32List().size());
ASSERT_EQ(7u, lists.getUInt64List().size());
ASSERT_EQ(8u, lists.getTextList().size());
ASSERT_EQ(2u, lists.getStructList0().size());
ASSERT_EQ(3u, lists.getStructList1().size());
ASSERT_EQ(4u, lists.getStructList8().size());
ASSERT_EQ(2u, lists.getStructList16().size());
ASSERT_EQ(3u, lists.getStructList32().size());
ASSERT_EQ(4u, lists.getStructList64().size());
ASSERT_EQ(2u, lists.getStructList128().size());
ASSERT_EQ(3u, lists.getStructList192().size());
ASSERT_EQ(4u, lists.getStructList0p().size());
ASSERT_EQ(2u, lists.getStructList1p().size());
ASSERT_EQ(3u, lists.getStructList8p().size());
ASSERT_EQ(4u, lists.getStructList16p().size());
ASSERT_EQ(2u, lists.getStructList32p().size());
ASSERT_EQ(3u, lists.getStructList64p().size());
ASSERT_EQ(4u, lists.getStructList128p().size());
ASSERT_EQ(2u, lists.getStructList192p().size());
lists.getVoidList().set(0, Void::VOID);
lists.getVoidList().set(1, Void::VOID);
lists.getBoolList().set(0, false);
lists.getBoolList().set(1, true);
lists.getBoolList().set(2, false);
lists.getUInt8List().set(0, 12u);
lists.getUInt8List().set(1, 34u);
lists.getUInt8List().set(2, 56u);
lists.getUInt8List().set(3, 78u);
lists.getUInt16List().set(0, 1234u);
lists.getUInt16List().set(1, 5678u);
lists.getUInt16List().set(2, 9012u);
lists.getUInt16List().set(3, 3456u);
lists.getUInt16List().set(4, 7890u);
lists.getUInt32List().set(0, 123456789u);
lists.getUInt32List().set(1, 234567890u);
lists.getUInt32List().set(2, 345678901u);
lists.getUInt32List().set(3, 456789012u);
lists.getUInt32List().set(4, 567890123u);
lists.getUInt32List().set(5, 678901234u);
for (uint i = 0; i < 7; i++) {
lists.getUInt64List().set(i, i + 1);
}
lists.getTextList().set(0, "foo");
lists.getTextList().set(1, "bar");
lists.getTextList().set(2, "baz");
lists.getTextList().set(3, "qux");
lists.getTextList().set(4, "quux");
lists.getTextList().set(5, "corge");
lists.getTextList().set(6, "grault");
lists.getTextList().set(7, "garply");
lists.getStructList0()[0].setF(Void::VOID);
lists.getStructList0()[1].setF(Void::VOID);
lists.getStructList8()[0].setF0(true);
lists.getStructList8()[0].setF1(false);
lists.getStructList8()[0].setF2(false);
lists.getStructList8()[1].setF0(false);
lists.getStructList8()[1].setF1(true);
lists.getStructList8()[1].setF2(false);
lists.getStructList8()[2].setF0(true);
lists.getStructList8()[2].setF1(true);
lists.getStructList8()[2].setF2(false);
lists.getStructList8()[3].setF0(false);
lists.getStructList8()[3].setF1(false);
lists.getStructList8()[3].setF2(true);
lists.getStructList16()[0].setF0(12u);
lists.getStructList16()[0].setF1(34u);
lists.getStructList16()[1].setF0(56u);
lists.getStructList16()[1].setF1(78u);
lists.getStructList32()[0].setF0(90u);
lists.getStructList32()[0].setF1(12345u);
lists.getStructList32()[1].setF0(67u);
lists.getStructList32()[1].setF1(8901u);
lists.getStructList32()[2].setF0(23u);
lists.getStructList32()[2].setF1(45678u);
lists.getStructList64()[0].setF0(90u);
lists.getStructList64()[0].setF1(123456789u);
lists.getStructList64()[1].setF0(12u);
lists.getStructList64()[1].setF1(345678901u);
lists.getStructList64()[2].setF0(234u);
lists.getStructList64()[2].setF1(567890123u);
lists.getStructList64()[3].setF0(45u);
lists.getStructList64()[3].setF1(678901234u);
lists.getStructList128()[0].setF0(56789012345678ull);
lists.getStructList128()[0].setF1(90123456789012ull);
lists.getStructList128()[1].setF0(34567890123456ull);
lists.getStructList128()[1].setF1(78901234567890ull);
lists.getStructList192()[0].setF0(1234567890123ull);
lists.getStructList192()[0].setF1(4567890123456ull);
lists.getStructList192()[0].setF2(7890123456789ull);
lists.getStructList192()[1].setF0( 123456789012ull);
lists.getStructList192()[1].setF1(3456789012345ull);
lists.getStructList192()[1].setF2(6789012345678ull);
lists.getStructList192()[2].setF0(9012345678901ull);
lists.getStructList192()[2].setF1(2345678901234ull);
lists.getStructList192()[2].setF2(5678901234567ull);
lists.getStructList0p()[0].setP0("foo");
lists.getStructList0p()[1].setP0("bar");
lists.getStructList0p()[2].setP0("baz");
lists.getStructList0p()[3].setP0("qux");
lists.getStructList8p()[0].getF().setF0(true);
lists.getStructList8p()[0].setP0("grault");
lists.getStructList8p()[1].setP0("garply");
lists.getStructList8p()[2].setP0("waldo");
lists.getStructList16p()[0].getF().setF0(123u);
lists.getStructList16p()[0].setP0("fred");
lists.getStructList16p()[0].setP1("plugh");
lists.getStructList16p()[1].setP0("xyzzy");
lists.getStructList16p()[1].setP1("thud");
lists.getStructList16p()[2].setP0("foobar");
lists.getStructList16p()[2].setP1("barbaz");
lists.getStructList16p()[3].setP0("bazqux");
lists.getStructList16p()[3].setP1("quxquux");
lists.getStructList32p()[0].getF().setF1(12345u);
lists.getStructList32p()[0].setP0("quuxcorge");
lists.getStructList32p()[0].setP1("corgegrault");
lists.getStructList32p()[1].setP0("graultgarply");
lists.getStructList32p()[1].setP1("garplywaldo");
lists.getStructList64p()[0].getF().setF1(123456789u);
lists.getStructList64p()[0].setP0("waldofred");
lists.getStructList64p()[0].setP1("fredplugh");
lists.getStructList64p()[1].setP0("plughxyzzy");
lists.getStructList64p()[1].setP1("xyzzythud");
lists.getStructList64p()[2].setP0("thudfoo");
lists.getStructList64p()[2].setP1("foofoo");
lists.getStructList128p()[0].getF().setF1(123456789012345ull);
lists.getStructList128p()[0].setP0("foobaz");
lists.getStructList128p()[0].setP1("fooqux");
lists.getStructList128p()[0].setP2("foocorge");
lists.getStructList128p()[1].setP0("barbaz");
lists.getStructList128p()[1].setP1("barqux");
lists.getStructList128p()[1].setP2("barcorge");
lists.getStructList128p()[2].setP0("bazbaz");
lists.getStructList128p()[2].setP1("bazqux");
lists.getStructList128p()[2].setP2("bazcorge");
lists.getStructList128p()[3].setP0("quxbaz");
lists.getStructList128p()[3].setP1("quxqux");
lists.getStructList128p()[3].setP2("quxcorge");
lists.getStructList192p()[0].getF().setF2(123456789012345ull);
lists.getStructList192p()[0].setP0("corgebaz");
lists.getStructList192p()[0].setP1("corgequx");
lists.getStructList192p()[0].setP2("corgecorge");
lists.getStructList192p()[1].setP0("graultbaz");
lists.getStructList192p()[1].setP1("graultqux");
lists.getStructList192p()[1].setP2("graultcorge");
lists.setData("12345");
}
{
auto sl = builder.initStructLists();
sl.initList0(2);
sl.initList1(2);
sl.initList8(2);
sl.initList16(2);
sl.initList32(2);
sl.initList64(2);
sl.initListP(2);
sl.getList0()[0].setF(Void::VOID);
sl.getList0()[1].setF(Void::VOID);
sl.getList1()[0].setF(true);
sl.getList1()[1].setF(false);
sl.getList8()[0].setF(123u);
sl.getList8()[1].setF(45u);
sl.getList16()[0].setF(12345u);
sl.getList16()[1].setF(6789u);
sl.getList32()[0].setF(123456789u);
sl.getList32()[1].setF(234567890u);
sl.getList64()[0].setF(1234567890123456u);
sl.getList64()[1].setF(2345678901234567u);
sl.getListP()[0].setF("foo");
sl.getListP()[1].setF("bar");
}
{
auto ll = builder.initListLists();
{
auto l = ll.initInt32ListList(3);
l.init(0, 3).copyFrom({1, 2, 3});
l.init(1, 2).copyFrom({4, 5});
l.init(2, 1).copyFrom({12341234});
}
{
auto l = ll.initTextListList(3);
l.init(0, 2).copyFrom({"foo", "bar"});
l.init(1, 1).copyFrom({"baz"});
l.init(2, 2).copyFrom({"qux", "corge"});
}
{
auto l = ll.initStructListList(2);
auto e = l.init(0, 2);
e[0].setInt32Field(123);
e[1].setInt32Field(456);
e = l.init(1, 1);
e[0].setInt32Field(789);
}
{
auto l = ll.initInt32InlineListList(2);
l[0].copyFrom({1, 2, 3, 4, 5, 6, 123456789});
l[1].copyFrom({987654321, 6, 5, 4, 3, 2, 1});
}
{
auto l = ll.initTextInlineListList(3);
l[0].copyFrom({"grault1", "grault2", "grault3", "grault4", "grault5"});
l[1].copyFrom({"garply1", "garply2", "garply3", "garply4", "garply5"});
l[2].copyFrom({"waldo1", "waldo2", "waldo3", "waldo4", "waldo5"});
}
{
auto l = ll.initStructInlineListList(3);
ASSERT_EQ(3u, l[0].size());
ASSERT_EQ(3u, l[1].size());
ASSERT_EQ(3u, l[2].size());
l[0][0].getF().setF1(123);
l[0][1].getF().setF1(456);
l[0][2].getF().setF1(789);
l[1][0].getF().setF1(321);
l[1][1].getF().setF1(654);
l[1][2].getF().setF1(987);
l[2][0].getF().setF1(111);
l[2][1].getF().setF1(222);
l[2][2].getF().setF1(333);
l[0][0].setP0("fred1");
l[0][1].setP0("fred2");
l[0][2].setP0("fred3");
l[1][0].setP0("plugh1");
l[1][1].setP0("plugh2");
l[1][2].setP0("plugh3");
l[2][0].setP0("thud1");
l[2][1].setP0("thud2");
l[2][2].setP0("thud3");
}
ll.setInlineDataList({"123456789", "234567890", "345678901", "456789012", "567890123"});
{
auto l = ll.initInt32InlineListListList(3);
l.init(0, 3);
l.init(1, 2);
l.init(2, 1);
ASSERT_EQ(2u, l[0][0].size());
ASSERT_EQ(2u, l[0][1].size());
ASSERT_EQ(2u, l[0][2].size());
ASSERT_EQ(2u, l[1][0].size());
ASSERT_EQ(2u, l[1][1].size());
ASSERT_EQ(2u, l[2][0].size());
l[0][0].copyFrom({1, 2});
l[0][1].copyFrom({3, 4});
l[0][2].copyFrom({5, 6});
l[1][0].copyFrom({7, 8});
l[1][1].copyFrom({9, 10});
l[2][0].copyFrom({1234567, 7654321});
}
{
auto l = ll.initTextInlineListListList(2);
l.init(0, 2);
l.init(1, 1);
ASSERT_EQ(5u, l[0][0].size());
ASSERT_EQ(5u, l[0][1].size());
ASSERT_EQ(5u, l[1][0].size());
l[0][0].copyFrom({"1", "2", "3", "4", "5"});
l[0][1].copyFrom({"foo", "bar", "baz", "qux", "corge"});
l[1][0].copyFrom({"z", "y", "x", "w", "v"});
}
{
auto l = ll.initStructInlineListListList(2);
l.init(0, 2);
l.init(1, 1);
ASSERT_EQ(3u, l[0][0].size());
ASSERT_EQ(3u, l[0][1].size());
ASSERT_EQ(3u, l[1][0].size());
l[0][0][0].getF().setF1(123);
l[0][0][1].getF().setF1(456);
l[0][0][2].getF().setF1(789);
l[0][1][0].getF().setF1(321);
l[0][1][1].getF().setF1(654);
l[0][1][2].getF().setF1(987);
l[1][0][0].getF().setF1(111);
l[1][0][1].getF().setF1(222);
l[1][0][2].getF().setF1(333);
l[0][0][0].setP0("fred1");
l[0][0][1].setP0("fred2");
l[0][0][2].setP0("fred3");
l[0][1][0].setP0("plugh1");
l[0][1][1].setP0("plugh2");
l[0][1][2].setP0("plugh3");
l[1][0][0].setP0("thud1");
l[1][0][1].setP0("thud2");
l[1][0][2].setP0("thud3");
}
{
auto l = ll.initInlineDataListList(2);
l.init(0, 3).copyFrom({"foo", "bar", "baz"});
l.init(1, 2).copyFrom({"123", "234"});
}
}
}
template <typename Reader>
void genericCheckInlineDefaults(Reader reader) {
{
auto normal = reader.getNormal();
EXPECT_TRUE(normal.getF8().getF0());
EXPECT_FALSE(normal.getF8().getF1());
EXPECT_TRUE(normal.getF8().getF2());
EXPECT_EQ(123u, normal.getF16().getF0());
EXPECT_EQ(45u, normal.getF16().getF1());
EXPECT_EQ(67u, normal.getF32().getF0());
EXPECT_EQ(8901u, normal.getF32().getF1());
EXPECT_EQ(234u, normal.getF64().getF0());
EXPECT_EQ(567890123u, normal.getF64().getF1());
EXPECT_EQ(1234567890123ull, normal.getF128().getF0());
EXPECT_EQ(4567890123456ull, normal.getF128().getF1());
EXPECT_EQ(7890123456789ull, normal.getF192().getF0());
EXPECT_EQ(2345678901234ull, normal.getF192().getF1());
EXPECT_EQ(5678901234567ull, normal.getF192().getF2());
EXPECT_TRUE(normal.getF8p().getF().getF0());
EXPECT_TRUE(normal.getF8p().getF().getF1());
EXPECT_FALSE(normal.getF8p().getF().getF2());
EXPECT_EQ(98u, normal.getF16p().getF().getF0());
EXPECT_EQ(76u, normal.getF16p().getF().getF1());
EXPECT_EQ(54u, normal.getF32p().getF().getF0());
EXPECT_EQ(32109u, normal.getF32p().getF().getF1());
EXPECT_EQ(87u, normal.getF64p().getF().getF0());
EXPECT_EQ(654321098u, normal.getF64p().getF().getF1());
EXPECT_EQ(7654321098765ull, normal.getF128p().getF().getF0());
EXPECT_EQ(4321098765432ull, normal.getF128p().getF().getF1());
EXPECT_EQ(1098765432109ull, normal.getF192p().getF().getF0());
EXPECT_EQ(8765432109876ull, normal.getF192p().getF().getF1());
EXPECT_EQ(5432109876543ull, normal.getF192p().getF().getF2());
EXPECT_EQ("foo", normal.getF0p().getP0());
EXPECT_EQ("baz", normal.getF8p().getP0());
EXPECT_EQ("qux", normal.getF16p().getP0());
EXPECT_EQ("quux", normal.getF16p().getP1());
EXPECT_EQ("corge", normal.getF32p().getP0());
EXPECT_EQ("grault", normal.getF32p().getP1());
EXPECT_EQ("garply", normal.getF64p().getP0());
EXPECT_EQ("waldo", normal.getF64p().getP1());
EXPECT_EQ("fred", normal.getF128p().getP0());
EXPECT_EQ("plugh", normal.getF128p().getP1());
EXPECT_EQ("xyzzy", normal.getF128p().getP2());
EXPECT_EQ("thud", normal.getF192p().getP0());
EXPECT_EQ("foobar", normal.getF192p().getP1());
EXPECT_EQ("barbaz", normal.getF192p().getP2());
}
{
auto unions = reader.getUnions();
ASSERT_EQ(TestInlineUnions::Union0::F32, unions.getUnion0().which());
EXPECT_EQ(67u, unions.getUnion0().getF32().getF0());
EXPECT_EQ(8901u, unions.getUnion0().getF32().getF1());
ASSERT_EQ(TestInlineUnions::Union1::F128, unions.getUnion1().which());
EXPECT_EQ(1234567890123ull, unions.getUnion1().getF128().getF0());
EXPECT_EQ(4567890123456ull, unions.getUnion1().getF128().getF1());
ASSERT_EQ(TestInlineUnions::Union3::F16P, unions.getUnion3().which());
EXPECT_EQ(98u, unions.getUnion3().getF16p().getF().getF0());
EXPECT_EQ(76u, unions.getUnion3().getF16p().getF().getF1());
EXPECT_EQ("qux", unions.getUnion3().getF16p().getP0());
EXPECT_EQ("quux", unions.getUnion3().getF16p().getP1());
}
{
auto lists = reader.getLists();
ASSERT_EQ(2u, lists.getVoidList().size());
ASSERT_EQ(3u, lists.getBoolList().size());
ASSERT_EQ(4u, lists.getUInt8List().size());
ASSERT_EQ(5u, lists.getUInt16List().size());
ASSERT_EQ(6u, lists.getUInt32List().size());
ASSERT_EQ(7u, lists.getUInt64List().size());
ASSERT_EQ(8u, lists.getTextList().size());
ASSERT_EQ(2u, lists.getStructList0().size());
ASSERT_EQ(3u, lists.getStructList1().size());
ASSERT_EQ(4u, lists.getStructList8().size());
ASSERT_EQ(2u, lists.getStructList16().size());
ASSERT_EQ(3u, lists.getStructList32().size());
ASSERT_EQ(4u, lists.getStructList64().size());
ASSERT_EQ(2u, lists.getStructList128().size());
ASSERT_EQ(3u, lists.getStructList192().size());
ASSERT_EQ(4u, lists.getStructList0p().size());
ASSERT_EQ(2u, lists.getStructList1p().size());
ASSERT_EQ(3u, lists.getStructList8p().size());
ASSERT_EQ(4u, lists.getStructList16p().size());
ASSERT_EQ(2u, lists.getStructList32p().size());
ASSERT_EQ(3u, lists.getStructList64p().size());
ASSERT_EQ(4u, lists.getStructList128p().size());
ASSERT_EQ(2u, lists.getStructList192p().size());
EXPECT_EQ(Void::VOID, lists.getVoidList()[0]);
EXPECT_EQ(Void::VOID, lists.getVoidList()[1]);
EXPECT_FALSE(lists.getBoolList()[0]);
EXPECT_TRUE(lists.getBoolList()[1]);
EXPECT_FALSE(lists.getBoolList()[2]);
EXPECT_EQ(12u, lists.getUInt8List()[0]);
EXPECT_EQ(34u, lists.getUInt8List()[1]);
EXPECT_EQ(56u, lists.getUInt8List()[2]);
EXPECT_EQ(78u, lists.getUInt8List()[3]);
EXPECT_EQ(1234u, lists.getUInt16List()[0]);
EXPECT_EQ(5678u, lists.getUInt16List()[1]);
EXPECT_EQ(9012u, lists.getUInt16List()[2]);
EXPECT_EQ(3456u, lists.getUInt16List()[3]);
EXPECT_EQ(7890u, lists.getUInt16List()[4]);
EXPECT_EQ(123456789u, lists.getUInt32List()[0]);
EXPECT_EQ(234567890u, lists.getUInt32List()[1]);
EXPECT_EQ(345678901u, lists.getUInt32List()[2]);
EXPECT_EQ(456789012u, lists.getUInt32List()[3]);
EXPECT_EQ(567890123u, lists.getUInt32List()[4]);
EXPECT_EQ(678901234u, lists.getUInt32List()[5]);
for (uint i = 0; i < 7; i++) {
EXPECT_EQ(i + 1, lists.getUInt64List()[i]);
}
EXPECT_EQ("foo", lists.getTextList()[0]);
EXPECT_EQ("bar", lists.getTextList()[1]);
EXPECT_EQ("baz", lists.getTextList()[2]);
EXPECT_EQ("qux", lists.getTextList()[3]);
EXPECT_EQ("quux", lists.getTextList()[4]);
EXPECT_EQ("corge", lists.getTextList()[5]);
EXPECT_EQ("grault", lists.getTextList()[6]);
EXPECT_EQ("garply", lists.getTextList()[7]);
EXPECT_EQ(Void::VOID, lists.getStructList0()[0].getF());
EXPECT_EQ(Void::VOID, lists.getStructList0()[1].getF());
EXPECT_TRUE (lists.getStructList8()[0].getF0());
EXPECT_FALSE(lists.getStructList8()[0].getF1());
EXPECT_FALSE(lists.getStructList8()[0].getF2());
EXPECT_FALSE(lists.getStructList8()[1].getF0());
EXPECT_TRUE (lists.getStructList8()[1].getF1());
EXPECT_FALSE(lists.getStructList8()[1].getF2());
EXPECT_TRUE (lists.getStructList8()[2].getF0());
EXPECT_TRUE (lists.getStructList8()[2].getF1());
EXPECT_FALSE(lists.getStructList8()[2].getF2());
EXPECT_FALSE(lists.getStructList8()[3].getF0());
EXPECT_FALSE(lists.getStructList8()[3].getF1());
EXPECT_TRUE (lists.getStructList8()[3].getF2());
EXPECT_EQ(12u, lists.getStructList16()[0].getF0());
EXPECT_EQ(34u, lists.getStructList16()[0].getF1());
EXPECT_EQ(56u, lists.getStructList16()[1].getF0());
EXPECT_EQ(78u, lists.getStructList16()[1].getF1());
EXPECT_EQ(90u, lists.getStructList32()[0].getF0());
EXPECT_EQ(12345u, lists.getStructList32()[0].getF1());
EXPECT_EQ(67u, lists.getStructList32()[1].getF0());
EXPECT_EQ(8901u, lists.getStructList32()[1].getF1());
EXPECT_EQ(23u, lists.getStructList32()[2].getF0());
EXPECT_EQ(45678u, lists.getStructList32()[2].getF1());
EXPECT_EQ(90u, lists.getStructList64()[0].getF0());
EXPECT_EQ(123456789u, lists.getStructList64()[0].getF1());
EXPECT_EQ(12u, lists.getStructList64()[1].getF0());
EXPECT_EQ(345678901u, lists.getStructList64()[1].getF1());
EXPECT_EQ(234u, lists.getStructList64()[2].getF0());
EXPECT_EQ(567890123u, lists.getStructList64()[2].getF1());
EXPECT_EQ(45u, lists.getStructList64()[3].getF0());
EXPECT_EQ(678901234u, lists.getStructList64()[3].getF1());
EXPECT_EQ(56789012345678ull, lists.getStructList128()[0].getF0());
EXPECT_EQ(90123456789012ull, lists.getStructList128()[0].getF1());
EXPECT_EQ(34567890123456ull, lists.getStructList128()[1].getF0());
EXPECT_EQ(78901234567890ull, lists.getStructList128()[1].getF1());
EXPECT_EQ(1234567890123ull, lists.getStructList192()[0].getF0());
EXPECT_EQ(4567890123456ull, lists.getStructList192()[0].getF1());
EXPECT_EQ(7890123456789ull, lists.getStructList192()[0].getF2());
EXPECT_EQ( 123456789012ull, lists.getStructList192()[1].getF0());
EXPECT_EQ(3456789012345ull, lists.getStructList192()[1].getF1());
EXPECT_EQ(6789012345678ull, lists.getStructList192()[1].getF2());
EXPECT_EQ(9012345678901ull, lists.getStructList192()[2].getF0());
EXPECT_EQ(2345678901234ull, lists.getStructList192()[2].getF1());
EXPECT_EQ(5678901234567ull, lists.getStructList192()[2].getF2());
EXPECT_EQ("foo", lists.getStructList0p()[0].getP0());
EXPECT_EQ("bar", lists.getStructList0p()[1].getP0());
EXPECT_EQ("baz", lists.getStructList0p()[2].getP0());
EXPECT_EQ("qux", lists.getStructList0p()[3].getP0());
EXPECT_TRUE(lists.getStructList8p()[0].getF().getF0());
EXPECT_EQ("grault", lists.getStructList8p()[0].getP0());
EXPECT_EQ("garply", lists.getStructList8p()[1].getP0());
EXPECT_EQ("waldo", lists.getStructList8p()[2].getP0());
EXPECT_EQ(123u, lists.getStructList16p()[0].getF().getF0());
EXPECT_EQ("fred", lists.getStructList16p()[0].getP0());
EXPECT_EQ("plugh", lists.getStructList16p()[0].getP1());
EXPECT_EQ("xyzzy", lists.getStructList16p()[1].getP0());
EXPECT_EQ("thud", lists.getStructList16p()[1].getP1());
EXPECT_EQ("foobar", lists.getStructList16p()[2].getP0());
EXPECT_EQ("barbaz", lists.getStructList16p()[2].getP1());
EXPECT_EQ("bazqux", lists.getStructList16p()[3].getP0());
EXPECT_EQ("quxquux", lists.getStructList16p()[3].getP1());
EXPECT_EQ(12345u, lists.getStructList32p()[0].getF().getF1());
EXPECT_EQ("quuxcorge", lists.getStructList32p()[0].getP0());
EXPECT_EQ("corgegrault", lists.getStructList32p()[0].getP1());
EXPECT_EQ("graultgarply", lists.getStructList32p()[1].getP0());
EXPECT_EQ("garplywaldo", lists.getStructList32p()[1].getP1());
EXPECT_EQ(123456789u, lists.getStructList64p()[0].getF().getF1());
EXPECT_EQ("waldofred", lists.getStructList64p()[0].getP0());
EXPECT_EQ("fredplugh", lists.getStructList64p()[0].getP1());
EXPECT_EQ("plughxyzzy", lists.getStructList64p()[1].getP0());
EXPECT_EQ("xyzzythud", lists.getStructList64p()[1].getP1());
EXPECT_EQ("thudfoo", lists.getStructList64p()[2].getP0());
EXPECT_EQ("foofoo", lists.getStructList64p()[2].getP1());
EXPECT_EQ(123456789012345ull, lists.getStructList128p()[0].getF().getF1());
EXPECT_EQ("foobaz", lists.getStructList128p()[0].getP0());
EXPECT_EQ("fooqux", lists.getStructList128p()[0].getP1());
EXPECT_EQ("foocorge", lists.getStructList128p()[0].getP2());
EXPECT_EQ("barbaz", lists.getStructList128p()[1].getP0());
EXPECT_EQ("barqux", lists.getStructList128p()[1].getP1());
EXPECT_EQ("barcorge", lists.getStructList128p()[1].getP2());
EXPECT_EQ("bazbaz", lists.getStructList128p()[2].getP0());
EXPECT_EQ("bazqux", lists.getStructList128p()[2].getP1());
EXPECT_EQ("bazcorge", lists.getStructList128p()[2].getP2());
EXPECT_EQ("quxbaz", lists.getStructList128p()[3].getP0());
EXPECT_EQ("quxqux", lists.getStructList128p()[3].getP1());
EXPECT_EQ("quxcorge", lists.getStructList128p()[3].getP2());
EXPECT_EQ(123456789012345ull, lists.getStructList192p()[0].getF().getF2());
EXPECT_EQ("corgebaz", lists.getStructList192p()[0].getP0());
EXPECT_EQ("corgequx", lists.getStructList192p()[0].getP1());
EXPECT_EQ("corgecorge", lists.getStructList192p()[0].getP2());
EXPECT_EQ("graultbaz", lists.getStructList192p()[1].getP0());
EXPECT_EQ("graultqux", lists.getStructList192p()[1].getP1());
EXPECT_EQ("graultcorge", lists.getStructList192p()[1].getP2());
EXPECT_EQ("12345", lists.getData());
}
{
auto sl = reader.getStructLists();
ASSERT_EQ(2u, sl.getList0().size());
ASSERT_EQ(2u, sl.getList1().size());
ASSERT_EQ(2u, sl.getList8().size());
ASSERT_EQ(2u, sl.getList16().size());
ASSERT_EQ(2u, sl.getList32().size());
ASSERT_EQ(2u, sl.getList64().size());
ASSERT_EQ(2u, sl.getListP().size());
EXPECT_EQ(Void::VOID, sl.getList0()[0].getF());
EXPECT_EQ(Void::VOID, sl.getList0()[1].getF());
EXPECT_TRUE(sl.getList1()[0].getF());
EXPECT_FALSE(sl.getList1()[1].getF());
EXPECT_EQ(123u, sl.getList8()[0].getF());
EXPECT_EQ(45u, sl.getList8()[1].getF());
EXPECT_EQ(12345u, sl.getList16()[0].getF());
EXPECT_EQ(6789u, sl.getList16()[1].getF());
EXPECT_EQ(123456789u, sl.getList32()[0].getF());
EXPECT_EQ(234567890u, sl.getList32()[1].getF());
EXPECT_EQ(1234567890123456u, sl.getList64()[0].getF());
EXPECT_EQ(2345678901234567u, sl.getList64()[1].getF());
EXPECT_EQ("foo", sl.getListP()[0].getF());
EXPECT_EQ("bar", sl.getListP()[1].getF());
}
{
auto ll = reader.getListLists();
{
auto l = ll.getInt32ListList();
ASSERT_EQ(3u, l.size());
checkList(l[0], {1, 2, 3});
checkList(l[1], {4, 5});
checkList(l[2], {12341234});
}
{
auto l = ll.getTextListList();
ASSERT_EQ(3u, l.size());
checkList(l[0], {"foo", "bar"});
checkList(l[1], {"baz"});
checkList(l[2], {"qux", "corge"});
}
{
auto l = ll.getStructListList();
ASSERT_EQ(2u, l.size());
auto e = l[0];
ASSERT_EQ(2u, e.size());
EXPECT_EQ(123, e[0].getInt32Field());
EXPECT_EQ(456, e[1].getInt32Field());
e = l[1];
ASSERT_EQ(1u, e.size());
EXPECT_EQ(789, e[0].getInt32Field());
}
{
auto l = ll.getInt32InlineListList();
ASSERT_EQ(2u, l.size());
checkList(l[0], {1, 2, 3, 4, 5, 6, 123456789});
checkList(l[1], {987654321, 6, 5, 4, 3, 2, 1});
}
{
auto l = ll.getTextInlineListList();
ASSERT_EQ(3u, l.size());
checkList(l[0], {"grault1", "grault2", "grault3", "grault4", "grault5"});
checkList(l[1], {"garply1", "garply2", "garply3", "garply4", "garply5"});
checkList(l[2], {"waldo1", "waldo2", "waldo3", "waldo4", "waldo5"});
}
{
auto l = ll.getStructInlineListList();
ASSERT_EQ(3u, l.size());
ASSERT_EQ(3u, l[0].size());
ASSERT_EQ(3u, l[1].size());
ASSERT_EQ(3u, l[2].size());
EXPECT_EQ(123, l[0][0].getF().getF1());
EXPECT_EQ(456, l[0][1].getF().getF1());
EXPECT_EQ(789, l[0][2].getF().getF1());
EXPECT_EQ(321, l[1][0].getF().getF1());
EXPECT_EQ(654, l[1][1].getF().getF1());
EXPECT_EQ(987, l[1][2].getF().getF1());
EXPECT_EQ(111, l[2][0].getF().getF1());
EXPECT_EQ(222, l[2][1].getF().getF1());
EXPECT_EQ(333, l[2][2].getF().getF1());
EXPECT_EQ("fred1", l[0][0].getP0());
EXPECT_EQ("fred2", l[0][1].getP0());
EXPECT_EQ("fred3", l[0][2].getP0());
EXPECT_EQ("plugh1", l[1][0].getP0());
EXPECT_EQ("plugh2", l[1][1].getP0());
EXPECT_EQ("plugh3", l[1][2].getP0());
EXPECT_EQ("thud1", l[2][0].getP0());
EXPECT_EQ("thud2", l[2][1].getP0());
EXPECT_EQ("thud3", l[2][2].getP0());
}
checkList(ll.getInlineDataList(),
{"123456789", "234567890", "345678901", "456789012", "567890123"});
{
auto l = ll.getInt32InlineListListList();
ASSERT_EQ(3u, l.size());
ASSERT_EQ(3u, l[0].size());
ASSERT_EQ(2u, l[1].size());
ASSERT_EQ(1u, l[2].size());
ASSERT_EQ(2u, l[0][0].size());
ASSERT_EQ(2u, l[0][1].size());
ASSERT_EQ(2u, l[0][2].size());
ASSERT_EQ(2u, l[1][0].size());
ASSERT_EQ(2u, l[1][1].size());
ASSERT_EQ(2u, l[2][0].size());
checkList(l[0][0], {1, 2});
checkList(l[0][1], {3, 4});
checkList(l[0][2], {5, 6});
checkList(l[1][0], {7, 8});
checkList(l[1][1], {9, 10});
checkList(l[2][0], {1234567, 7654321});
}
{
auto l = ll.getTextInlineListListList();
ASSERT_EQ(2u, l.size());
ASSERT_EQ(2u, l[0].size());
ASSERT_EQ(1u, l[1].size());
ASSERT_EQ(5u, l[0][0].size());
ASSERT_EQ(5u, l[0][1].size());
ASSERT_EQ(5u, l[1][0].size());
checkList(l[0][0], {"1", "2", "3", "4", "5"});
checkList(l[0][1], {"foo", "bar", "baz", "qux", "corge"});
checkList(l[1][0], {"z", "y", "x", "w", "v"});
}
{
auto l = ll.getStructInlineListListList();
ASSERT_EQ(2u, l.size());
ASSERT_EQ(2u, l[0].size());
ASSERT_EQ(1u, l[1].size());
ASSERT_EQ(3u, l[0][0].size());
ASSERT_EQ(3u, l[0][1].size());
ASSERT_EQ(3u, l[1][0].size());
EXPECT_EQ(123, l[0][0][0].getF().getF1());
EXPECT_EQ(456, l[0][0][1].getF().getF1());
EXPECT_EQ(789, l[0][0][2].getF().getF1());
EXPECT_EQ(321, l[0][1][0].getF().getF1());
EXPECT_EQ(654, l[0][1][1].getF().getF1());
EXPECT_EQ(987, l[0][1][2].getF().getF1());
EXPECT_EQ(111, l[1][0][0].getF().getF1());
EXPECT_EQ(222, l[1][0][1].getF().getF1());
EXPECT_EQ(333, l[1][0][2].getF().getF1());
EXPECT_EQ("fred1", l[0][0][0].getP0());
EXPECT_EQ("fred2", l[0][0][1].getP0());
EXPECT_EQ("fred3", l[0][0][2].getP0());
EXPECT_EQ("plugh1", l[0][1][0].getP0());
EXPECT_EQ("plugh2", l[0][1][1].getP0());
EXPECT_EQ("plugh3", l[0][1][2].getP0());
EXPECT_EQ("thud1", l[1][0][0].getP0());
EXPECT_EQ("thud2", l[1][0][1].getP0());
EXPECT_EQ("thud3", l[1][0][2].getP0());
}
{
auto l = ll.getInlineDataListList();
ASSERT_EQ(2u, l.size());
checkList(l[0], {"foo", "bar", "baz"});
checkList(l[1], {"123", "234"});
}
}
}
} // namespace
void initTestMessage(TestAllTypes::Builder builder) { genericInitTestMessage(builder); }
void initTestMessage(TestDefaults::Builder builder) { genericInitTestMessage(builder); }
void initTestMessage(TestInlineDefaults::Builder builder) { genericInitInlineDefaults(builder); }
void checkTestMessage(TestAllTypes::Builder builder) { genericCheckTestMessage(builder); }
void checkTestMessage(TestDefaults::Builder builder) { genericCheckTestMessage(builder); }
void checkTestMessage(TestInlineDefaults::Builder builder) { genericCheckInlineDefaults(builder); }
void checkTestMessage(TestAllTypes::Reader reader) { genericCheckTestMessage(reader); }
void checkTestMessage(TestDefaults::Reader reader) { genericCheckTestMessage(reader); }
void checkTestMessage(TestInlineDefaults::Reader reader) { genericCheckInlineDefaults(reader); }
void checkTestMessageAllZero(TestAllTypes::Builder builder) {
genericCheckTestMessageAllZero(builder);
......
......@@ -48,30 +48,35 @@ inline std::ostream& operator<<(std::ostream& os, Void) {
namespace internal {
// Explicitly import each of these to make sure they're really located in capnproto::test and not,
// say, the global namespace.
using ::capnproto::test::TestAllTypes;
using ::capnproto::test::TestDefaults;
using ::capnproto::test::TestEnum;
using ::capnproto::test::TestUnion;
using ::capnproto::test::TestUnionDefaults;
using ::capnproto::test::TestNestedTypes;
using ::capnproto::test::TestUsing;
using ::capnproto::test::TestInlineLayout;
using ::capnproto::test::TestInlineUnions;
using ::capnproto::test::TestInlineDefaults;
namespace test = capnproto_test::capnproto::test;
void initTestMessage(test::TestAllTypes::Builder builder);
void initTestMessage(test::TestDefaults::Builder builder);
// We don't use "using namespace" to pull these in because then things would still compile
// correctly if they were generated in the global namespace.
using ::capnproto_test::capnproto::test::TestAllTypes;
using ::capnproto_test::capnproto::test::TestDefaults;
using ::capnproto_test::capnproto::test::TestEnum;
using ::capnproto_test::capnproto::test::TestUnion;
using ::capnproto_test::capnproto::test::TestUnionDefaults;
using ::capnproto_test::capnproto::test::TestNestedTypes;
using ::capnproto_test::capnproto::test::TestUsing;
using ::capnproto_test::capnproto::test::TestInlineLayout;
using ::capnproto_test::capnproto::test::TestInlineUnions;
using ::capnproto_test::capnproto::test::TestInlineDefaults;
void checkTestMessage(test::TestAllTypes::Builder builder);
void checkTestMessage(test::TestDefaults::Builder builder);
void initTestMessage(TestAllTypes::Builder builder);
void initTestMessage(TestDefaults::Builder builder);
void initTestMessage(TestInlineDefaults::Builder builder);
void checkTestMessage(test::TestAllTypes::Reader reader);
void checkTestMessage(test::TestDefaults::Reader reader);
void checkTestMessage(TestAllTypes::Builder builder);
void checkTestMessage(TestDefaults::Builder builder);
void checkTestMessage(TestInlineDefaults::Builder builder);
void checkTestMessageAllZero(test::TestAllTypes::Builder builder);
void checkTestMessageAllZero(test::TestAllTypes::Reader reader);
void checkTestMessage(TestAllTypes::Reader reader);
void checkTestMessage(TestDefaults::Reader reader);
void checkTestMessage(TestInlineDefaults::Reader reader);
void checkTestMessageAllZero(TestAllTypes::Builder builder);
void checkTestMessageAllZero(TestAllTypes::Reader reader);
} // namespace internal
} // namespace capnproto
......
......@@ -23,7 +23,9 @@
using Cxx = import "c++.capnp";
$Cxx.namespace("capnproto::test");
# Use a namespace likely to cause trouble if the generated code doesn't use fully-qualified
# names for stuff in the capnproto namespace.
$Cxx.namespace("capnproto_test::capnproto::test");
enum TestEnum {
foo @0;
......@@ -406,6 +408,8 @@ struct TestInlineLists {
structList64p @20 : InlineList(TestInline64p, 3);
structList128p @21 : InlineList(TestInline128p, 4);
structList192p @22 : InlineList(TestInline192p, 2);
data @23 :InlineData(5);
}
struct TestStructLists {
......@@ -428,6 +432,22 @@ struct TestStructLists {
listP @6 :List(StructP);
}
struct TestListLists {
int32ListList @0 :List(List(Int32));
textListList @1 :List(List(Text));
structListList @2 :List(List(TestAllTypes));
int32InlineListList @3 :List(InlineList(Int32, 7));
textInlineListList @4 :List(InlineList(Text, 5));
structInlineListList @5 :List(InlineList(TestInline32p, 3));
inlineDataList @6 :List(InlineData(9));
int32InlineListListList @7 :List(List(InlineList(Int32, 2)));
textInlineListListList @8 :List(List(InlineList(Text, 5)));
structInlineListListList @9 :List(List(InlineList(TestInline32p, 3)));
inlineDataListList @10 :List(List(InlineData(3)));
}
struct TestInlineDefaults {
normal @0 :TestInlineLayout = (
f0 = (f = void),
......@@ -497,7 +517,9 @@ struct TestInlineDefaults {
(p0 = "quxbaz", p1 = "quxqux", p2 = "quxcorge")],
structList192p = [(f = (f2 = 123456789012345),
p0 = "corgebaz", p1 = "corgequx", p2 = "corgecorge"),
(p0 = "graultbaz", p1 = "graultqux", p2 = "graultcorge")]);
(p0 = "graultbaz", p1 = "graultqux", p2 = "graultcorge")],
data = "12345");
structLists @3 :TestStructLists = (
list0 = [(f = void), (f = void)],
......@@ -507,4 +529,30 @@ struct TestInlineDefaults {
list32 = [(f = 123456789), (f = 234567890)],
list64 = [(f = 1234567890123456), (f = 2345678901234567)],
listP = [(f = "foo"), (f = "bar")]);
listLists @4 :TestListLists = (
int32ListList = [[1, 2, 3], [4, 5], [12341234]],
textListList = [["foo", "bar"], ["baz"], ["qux", "corge"]],
structListList = [[(int32Field = 123), (int32Field = 456)], [(int32Field = 789)]],
int32InlineListList = [[1, 2, 3, 4, 5, 6, 123456789], [987654321, 6, 5, 4, 3, 2, 1]],
textInlineListList = [["grault1", "grault2", "grault3", "grault4", "grault5"],
["garply1", "garply2", "garply3", "garply4", "garply5"],
["waldo1", "waldo2", "waldo3", "waldo4", "waldo5"]],
structInlineListList =
[[(f=(f1=123), p0="fred1"), (f=(f1=456), p0="fred2"), (f=(f1=789), p0="fred3")],
[(f=(f1=321), p0="plugh1"), (f=(f1=654), p0="plugh2"), (f=(f1=987), p0="plugh3")],
[(f=(f1=111), p0="thud1"), (f=(f1=222), p0="thud2"), (f=(f1=333), p0="thud3")]],
inlineDataList = ["123456789", "234567890", "345678901", "456789012", "567890123"],
int32InlineListListList = [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10]], [[1234567,7654321]]],
textInlineListListList = [[["1", "2", "3", "4", "5"],
["foo", "bar", "baz", "qux", "corge"]],
[["z", "y", "x", "w", "v"]]],
structInlineListListList =
[[[(f=(f1=123), p0="fred1"), (f=(f1=456), p0="fred2"), (f=(f1=789), p0="fred3")],
[(f=(f1=321), p0="plugh1"), (f=(f1=654), p0="plugh2"), (f=(f1=987), p0="plugh3")]],
[[(f=(f1=111), p0="thud1"), (f=(f1=222), p0="thud2"), (f=(f1=333), p0="thud3")]]],
inlineDataListList = [["foo", "bar", "baz"], ["123", "234"]]);
}
......@@ -47,6 +47,7 @@ STRINGIFY_INT(long, "%ld");
STRINGIFY_INT(unsigned long, "%lu");
STRINGIFY_INT(long long, "%lld");
STRINGIFY_INT(unsigned long long, "%llu");
STRINGIFY_INT(const void*, "%p");
#undef STRINGIFY_INT
......
......@@ -125,7 +125,7 @@ template <typename Element>
Element* fill(Element* ptr) { return ptr; }
template <typename Element, typename First, typename... Rest>
Element* fill(Element* __restrict__ target, First& first, Rest&&... rest) {
Element* fill(Element* __restrict__ target, const First& first, Rest&&... rest) {
auto i = first.begin();
auto end = first.end();
while (i != end) {
......@@ -134,16 +134,6 @@ Element* fill(Element* __restrict__ target, First& first, Rest&&... rest) {
return fill(target, std::forward<Rest>(rest)...);
}
template <typename Element, typename First, typename... Rest>
Element* fill(Element* __restrict__ target, First&& first, Rest&&... rest) {
auto i = first.begin();
auto end = first.end();
while (i != end) {
*target++ = std::move(*i++);
}
return fill(target, std::forward<Rest>(rest)...);
}
template <typename Element, typename... Params>
Array<Element> concat(Params&&... params) {
// Concatenate a bunch of containers into a single Array. The containers can be anything that
......@@ -196,6 +186,10 @@ struct Stringifier {
CappedArray<char, sizeof(unsigned long long) * 4> operator*(unsigned long long i) const;
CappedArray<char, 24> operator*(float f) const;
CappedArray<char, 32> operator*(double f) const;
CappedArray<char, sizeof(const void*) * 4> operator*(const void* s) const;
template <typename T>
Array<char> operator*(ArrayPtr<T> arr) const;
};
static constexpr Stringifier STR;
......@@ -210,6 +204,34 @@ Array<char> str(Params&&... params) {
return concat<char>(STR * std::forward<Params>(params)...);
}
template <typename T>
Array<char> strArray(ArrayPtr<T> arr, const char* delim) {
size_t delimLen = strlen(delim);
decltype(STR * arr[0]) pieces[arr.size()];
size_t size = 0;
for (size_t i = 0; i < arr.size(); i++) {
if (i > 0) size += delimLen;
pieces[i] = STR * arr[i];
size += pieces[i].size();
}
Array<char> result = newArray<char>(size);
char* pos = result.begin();
for (size_t i = 0; i < arr.size(); i++) {
if (i > 0) {
memcpy(pos, delim, delimLen);
pos += delimLen;
}
pos = fill(pos, pieces[i]);
}
return result;
}
template <typename T>
inline Array<char> Stringifier::operator*(ArrayPtr<T> arr) const {
return strArray(arr, ", ");
}
} // namespace capnproto
#endif // CAPNPROTO_UTIL_H_
......@@ -164,6 +164,7 @@ builtinTypeMap = Map.fromList
[("List", DescBuiltinList),
("Inline", DescBuiltinInline),
("InlineList", DescBuiltinInlineList),
("InlineData", DescBuiltinInlineData),
("id", DescBuiltinId)])
------------------------------------------------------------------------------------------
......@@ -255,6 +256,12 @@ compileValue pos (InlineListType t s) (ListFieldValue l) = do
makeError pos $ printf "Fixed-size list must have exactly %d elements." s
return $ ListDesc elements
compileValue pos (InlineDataType s) (StringFieldValue x) = let
bytes = map (fromIntegral . fromEnum) x
in if List.genericLength bytes == s
then succeed $ DataDesc bytes
else makeError pos $ printf "Fixed-size data must have exactly %d bytes." s
compileValue pos (BuiltinType BuiltinVoid) _ = makeError pos "Void fields cannot have values."
compileValue pos (BuiltinType BuiltinBool) _ = makeExpectError pos "boolean"
compileValue pos (BuiltinType BuiltinInt8) _ = makeExpectError pos "integer"
......@@ -275,6 +282,7 @@ compileValue pos (StructType _) _ = makeExpectError pos "parenthesized list of f
compileValue pos (InterfaceType _) _ = makeError pos "Interfaces can't have default values."
compileValue pos (ListType _) _ = makeExpectError pos "list"
compileValue pos (InlineListType _ _) _ = makeExpectError pos "list"
compileValue pos (InlineDataType _) _ = makeExpectError pos "string"
descAsType _ (DescEnum desc) = succeed (EnumType desc)
descAsType _ (DescStruct desc) = succeed (StructType desc)
......@@ -286,7 +294,9 @@ descAsType name DescBuiltinList = makeError (declNamePos name) message where
descAsType name DescBuiltinInline = makeError (declNamePos name) message where
message = printf "'Inline' requires exactly one type parameter." (declNameString name)
descAsType name DescBuiltinInlineList = makeError (declNamePos name) message where
message = printf "'InlineList' requires exactly one type parameter." (declNameString name)
message = printf "'InlineList' requires exactly two type parameters." (declNameString name)
descAsType name DescBuiltinInlineData = makeError (declNamePos name) message where
message = printf "'InlineData' requires exactly one type parameter." (declNameString name)
descAsType name _ = makeError (declNamePos name) message where
message = printf "'%s' is not a type." (declNameString name)
......@@ -328,9 +338,15 @@ compileType scope (TypeExpression n params) = do
(structName s)
InlineListType _ _ -> makeError (declNamePos n)
"InlineList of InlineList not currently supported."
InlineDataType _ -> makeError (declNamePos n)
"InlineList of InlineData not currently supported."
_ -> return $ InlineListType inner size
_ -> makeError (declNamePos n)
"'InlineList' requires exactly two type parameters: a type and a size."
DescBuiltinInlineData -> case params of
[TypeParameterInteger size] -> return $ InlineDataType size
_ -> makeError (declNamePos n)
"'InlineData' requires exactly one type parameter: the byte size of the data."
_ -> case params of
[] -> descAsType n desc
_ -> makeError (declNamePos n) $
......@@ -881,6 +897,10 @@ compileDecl scope
recover () (case typeDesc of
InlineStructType _ ->
makeError defaultPos "Inline fields cannot have default values."
InlineListType _ _ ->
makeError defaultPos "Inline fields cannot have default values."
InlineDataType _ ->
makeError defaultPos "Inline fields cannot have default values."
_ -> return ())
return result
Nothing -> return Nothing
......
......@@ -92,11 +92,16 @@ isPrimitive (InlineStructType _) = False
isPrimitive (InterfaceType _) = False
isPrimitive (ListType _) = False
isPrimitive (InlineListType _ _) = False
isPrimitive (InlineDataType _) = False
isBlob (BuiltinType BuiltinText) = True
isBlob (BuiltinType BuiltinData) = True
isBlob (InlineDataType _) = True
isBlob _ = False
isInlineBlob (InlineDataType _) = True
isInlineBlob _ = False
isStruct (StructType _) = True
isStruct (InlineStructType _) = True
isStruct _ = False
......@@ -116,6 +121,18 @@ isPrimitiveList (ListType t) = isPrimitive t
isPrimitiveList (InlineListType t _) = isPrimitive t
isPrimitiveList _ = False
isPointerElement (InlineDataType _) = False
isPointerElement t = not (isPrimitive t || isStruct t || isInlineList t)
isPointerList (ListType t) = isPointerElement t
isPointerList (InlineListType t _) = isPointerElement t
isPointerList _ = False
isInlineBlobList (ListType t) = isInlineBlob t
isInlineBlobList _ = False
isStructList (ListType t@(InlineListType _ _)) = isStructList t
isStructList (InlineListType t@(InlineListType _ _) _) = isStructList t
isStructList (ListType t) = isStruct t
isStructList (InlineListType t _) = isStruct t
isStructList _ = False
......@@ -125,8 +142,20 @@ isInlineList _ = False
blobTypeString (BuiltinType BuiltinText) = "Text"
blobTypeString (BuiltinType BuiltinData) = "Data"
blobTypeString (InlineDataType _) = "Data"
blobTypeString (ListType t) = blobTypeString t
blobTypeString (InlineListType t _) = blobTypeString t
blobTypeString _ = error "Not a blob."
inlineMultiplier (InlineListType t s) = s * inlineMultiplier t
inlineMultiplier (InlineDataType s) = s
inlineMultiplier _ = 1
listInlineMultiplierString (ListType t) = case inlineMultiplier t of
1 -> ""
s -> " * " ++ show s
listInlineMultiplierString _ = error "Not a list."
cxxTypeString (BuiltinType BuiltinVoid) = " ::capnproto::Void"
cxxTypeString (BuiltinType BuiltinBool) = "bool"
cxxTypeString (BuiltinType BuiltinInt8) = " ::int8_t"
......@@ -146,7 +175,10 @@ cxxTypeString (StructType desc) = globalName $ DescStruct desc
cxxTypeString (InlineStructType desc) = globalName $ DescStruct desc
cxxTypeString (InterfaceType desc) = globalName $ DescInterface desc
cxxTypeString (ListType t) = concat [" ::capnproto::List<", cxxTypeString t, ">"]
cxxTypeString (InlineListType t _) = concat [" ::capnproto::List<", cxxTypeString t, ">"]
cxxTypeString (InlineListType t s) =
concat [" ::capnproto::InlineList<", cxxTypeString t, ", ", show s, ">"]
cxxTypeString (InlineDataType s) =
concat [" ::capnproto::InlineData<", show s, ">"]
cxxFieldSizeString SizeVoid = "VOID";
cxxFieldSizeString (SizeData Size1) = "BIT";
......@@ -214,6 +246,10 @@ elementType (ListType t) = t
elementType (InlineListType t _) = t
elementType _ = error "Called elementType on non-list."
inlineElementType (ListType t@(InlineListType _ _)) = inlineElementType t
inlineElementType (InlineListType t@(InlineListType _ _) _) = inlineElementType t
inlineElementType t = elementType t
repeatedlyTake _ [] = []
repeatedlyTake n l = take n l : repeatedlyTake n (drop n l)
......@@ -247,11 +283,14 @@ fieldContext parent desc = mkStrContext context where
context "fieldUpperCase" = MuVariable $ toUpperCaseWithUnderscores $ fieldName desc
context "fieldIsPrimitive" = MuBool $ isPrimitive $ fieldType desc
context "fieldIsBlob" = MuBool $ isBlob $ fieldType desc
context "fieldIsInlineBlob" = MuBool $ isInlineBlob $ fieldType desc
context "fieldIsStruct" = MuBool $ isStruct $ fieldType desc
context "fieldIsInlineStruct" = MuBool $ isInlineStruct $ fieldType desc
context "fieldIsList" = MuBool $ isList $ fieldType desc
context "fieldIsNonStructList" = MuBool $ isNonStructList $ fieldType desc
context "fieldIsPrimitiveList" = MuBool $ isPrimitiveList $ fieldType desc
context "fieldIsPointerList" = MuBool $ isPointerList $ fieldType desc
context "fieldIsInlineBlobList" = MuBool $ isInlineBlobList $ fieldType desc
context "fieldIsStructList" = MuBool $ isStructList $ fieldType desc
context "fieldIsInlineList" = MuBool $ isInlineList $ fieldType desc
context "fieldDefaultBytes" =
......@@ -263,6 +302,7 @@ fieldContext parent desc = mkStrContext context where
context "fieldOffset" = MuVariable $ fieldOffsetInteger $ fieldOffset desc
context "fieldInlineListSize" = case fieldType desc of
InlineListType _ n -> MuVariable n
InlineDataType n -> MuVariable n
_ -> muNull
context "fieldInlineDataOffset" = case fieldOffset desc of
InlineCompositeOffset off _ size _ ->
......@@ -278,13 +318,16 @@ fieldContext parent desc = mkStrContext context where
context "fieldInlinePointerSize" = case fieldOffset desc of
InlineCompositeOffset _ _ _ size -> MuVariable size
_ -> muNull
context "fieldInlineMultiplier" = MuVariable $ listInlineMultiplierString $ fieldType desc
context "fieldDefaultMask" = case fieldDefaultValue desc of
Nothing -> MuVariable ""
Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v)
context "fieldElementSize" =
MuVariable $ cxxFieldSizeString $ fieldSize $ elementType $ fieldType desc
MuVariable $ cxxFieldSizeString $ fieldSize $ inlineElementType $ fieldType desc
context "fieldElementType" =
MuVariable $ cxxTypeString $ elementType $ fieldType desc
context "fieldInlineElementType" =
MuVariable $ cxxTypeString $ inlineElementType $ fieldType desc
context "fieldUnion" = case fieldUnion desc of
Just (u, _) -> muJust $ unionContext context u
Nothing -> muNull
......
......@@ -57,6 +57,7 @@ data Desc = DescFile FileDesc
| DescBuiltinList
| DescBuiltinInline
| DescBuiltinInlineList
| DescBuiltinInlineData
| DescBuiltinId
descName (DescFile _) = "(top-level)"
......@@ -75,6 +76,7 @@ descName (DescBuiltinType d) = builtinTypeName d
descName DescBuiltinList = "List"
descName DescBuiltinInline = "Inline"
descName DescBuiltinInlineList = "InlineList"
descName DescBuiltinInlineData = "InlineData"
descName DescBuiltinId = "id"
descId (DescFile d) = fileId d
......@@ -93,6 +95,7 @@ descId (DescBuiltinType _) = Nothing
descId DescBuiltinList = Nothing
descId DescBuiltinInline = Nothing
descId DescBuiltinInlineList = Nothing
descId DescBuiltinInlineData = Nothing
descId DescBuiltinId = Just "0U0T3e_SnatEfk6UcH2tcjTt1E0"
-- Gets the ID if explicitly defined, or generates it by appending ".name" to the parent's ID.
......@@ -119,6 +122,7 @@ descParent (DescBuiltinType _) = error "Builtin type has no parent."
descParent DescBuiltinList = error "Builtin type has no parent."
descParent DescBuiltinInline = error "Builtin type has no parent."
descParent DescBuiltinInlineList = error "Builtin type has no parent."
descParent DescBuiltinInlineData = error "Builtin type has no parent."
descParent DescBuiltinId = error "Builtin annotation has no parent."
descFile (DescFile d) = d
......@@ -140,6 +144,7 @@ descAnnotations (DescBuiltinType _) = Map.empty
descAnnotations DescBuiltinList = Map.empty
descAnnotations DescBuiltinInline = Map.empty
descAnnotations DescBuiltinInlineList = Map.empty
descAnnotations DescBuiltinInlineData = Map.empty
descAnnotations DescBuiltinId = Map.empty
descRuntimeImports (DescFile _) = error "Not to be called on files."
......@@ -158,6 +163,7 @@ descRuntimeImports (DescBuiltinType _) = []
descRuntimeImports DescBuiltinList = []
descRuntimeImports DescBuiltinInline = []
descRuntimeImports DescBuiltinInlineList = []
descRuntimeImports DescBuiltinInlineData = []
descRuntimeImports DescBuiltinId = []
type MemberMap = Map.Map String (Maybe Desc)
......@@ -228,6 +234,7 @@ data TypeDesc = BuiltinType BuiltinType
| InterfaceType InterfaceDesc
| ListType TypeDesc
| InlineListType TypeDesc Integer
| InlineDataType Integer
typeRuntimeImports (BuiltinType _) = []
typeRuntimeImports (EnumType d) = [descFile (DescEnum d)]
......@@ -236,6 +243,7 @@ typeRuntimeImports (InlineStructType d) = [descFile (DescStruct d)]
typeRuntimeImports (InterfaceType d) = [descFile (DescInterface d)]
typeRuntimeImports (ListType d) = typeRuntimeImports d
typeRuntimeImports (InlineListType d _) = typeRuntimeImports d
typeRuntimeImports (InlineDataType _) = []
data DataSectionSize = DataSection1 | DataSection8 | DataSection16 | DataSection32
| DataSectionWords Integer
......@@ -337,6 +345,12 @@ fieldSize (InlineListType element size) = let
SizeReference -> size
SizeInlineComposite _ pc -> pc * size
in SizeInlineComposite dataSection pointerCount
fieldSize (InlineDataType size)
| size <= 0 = SizeInlineComposite (DataSectionWords 0) 0
| size <= 1 = SizeInlineComposite DataSection8 0
| size <= 2 = SizeInlineComposite DataSection16 0
| size <= 4 = SizeInlineComposite DataSection32 0
| otherwise = SizeInlineComposite (DataSectionWords (div (size + 7) 8)) 0
-- Render the type descriptor's name as a string, appropriate for use in the given scope.
typeName :: Desc -> TypeDesc -> String
......@@ -347,6 +361,7 @@ typeName scope (InlineStructType desc) = descQualifiedName scope (DescStruct des
typeName scope (InterfaceType desc) = descQualifiedName scope (DescInterface desc)
typeName scope (ListType t) = "List(" ++ typeName scope t ++ ")"
typeName scope (InlineListType t s) = printf "InlineList(%s, %d)" (typeName scope t) s
typeName scope (InlineDataType s) = printf "InlineData(%d)" s
-- Computes the qualified name for the given descriptor within the given scope.
-- At present the scope is only used to determine whether the target is in the same file. If
......@@ -605,6 +620,7 @@ descToCode _ (DescBuiltinType _) = error "Can't print code for builtin type."
descToCode _ DescBuiltinList = error "Can't print code for builtin type."
descToCode _ DescBuiltinInline = error "Can't print code for builtin type."
descToCode _ DescBuiltinInlineList = error "Can't print code for builtin type."
descToCode _ DescBuiltinInlineData = error "Can't print code for builtin type."
descToCode _ DescBuiltinId = error "Can't print code for builtin annotation."
maybeBlockCode :: String -> [Desc] -> String
......
......@@ -88,6 +88,8 @@ encodePointerValue (InlineStructType _) _ =
encodePointerValue (ListType elementType) (ListDesc items) = encodeList elementType items
encodePointerValue (InlineListType _ _) _ =
error "Tried to encode inline list as a pointer."
encodePointerValue (InlineDataType _) _ =
error "Tried to encode inline data as a pointer."
encodePointerValue _ _ = error "Unknown pointer type."
-- Given a sorted list of (bitOffset, data), pack into a byte array.
......@@ -191,6 +193,7 @@ structDataSectionValues assignments = let
(pos, v2) <- case (t, v) of
(InlineStructType _, StructValueDesc v2) -> structDataSectionValues v2
(InlineListType t2 _, ListDesc v2) -> inlineListDataSectionValues t2 v2
(InlineDataType _, DataDesc v2) -> [(0, EncodedBytes v2)]
_ -> error "Non-inline-composite had inline-composite offset."
return (pos + bitOffset, v2)
......@@ -211,6 +214,7 @@ structPointerSectionValues assignments = let
(pos, v2) <- case (t, v) of
(InlineStructType _, StructValueDesc v2) -> structPointerSectionValues v2
(InlineListType t2 _, ListDesc v2) -> inlineListPointerSectionValues t2 v2
(InlineDataType _, DataDesc _) -> []
_ -> error "Non-inline-composite had inline-composite offset."
return (pos + off, v2)
......@@ -261,29 +265,21 @@ encodeList (StructType desc) elements = let
(genericLength elements),
concat [tag, elemBytes, childBytes])
-- A list of inline structs is encoded into separate data and pointer sections, and the
-- pointer to it is actually a struct pointer.
encodeList (InlineStructType desc) elements = let
dataBytes = inlineStructListDataSection desc elements
(refBytes, childBytes) = inlineStructListPointerSection desc elements
in case (structDataSize desc, structPointerCount desc) of
(ds, 0) -> -- If only data, encode as a primitive list.
(encodeListReference (SizeData $ dataSectionAlignment ds)
(div (genericLength elements * dataSectionBits ds)
(dataSizeInBits (dataSectionAlignment ds))),
dataBytes)
(DataSectionWords 0, pc) -> -- If only pointers, encode as a pointer list.
(encodeListReference SizeReference (genericLength elements * pc),
refBytes ++ childBytes)
(ds, pc) -> -- Otherwise, encode as a struct.
(encodeInlineStructListReference ds pc (genericLength elements),
concat [dataBytes, refBytes, childBytes])
encodeList (InlineStructType _) _ = error "Not supported: List of inline structs."
-- Encode a list of inline lists by just concatenating all the elements. The number of inner
-- lists can be determined at runtime by dividing the total size by the fixed inline list size.
-- Note that this means if you have something like List(InlineList(UInt8, 3)) and the list has
-- two elements, the total size will be 6 bytes -- we don't round the individual sub-lists up
-- to power-of-two boundaries.
encodeList (InlineListType (InlineStructType t) _) elements =
encodeList (StructType t) (concat [l | ListDesc l <- elements])
encodeList (InlineListType t _) elements = encodeList t (concat [l | ListDesc l <- elements])
-- Encode a list of inline data. Similar deal to above.
encodeList (InlineDataType _) elements =
encodePointerValue (BuiltinType BuiltinData) (DataDesc $ concat [l | DataDesc l <- elements])
-- Encode primitive types.
encodeList elementType elements = let
eSize = fieldSize elementType
......@@ -306,6 +302,7 @@ inlineListDataSectionValues elementType elements = case fieldSize elementType of
(SizeInlineComposite _ _) -> case elementType of
InlineStructType desc -> inlineStructListDataSectionValues desc elements
InlineListType t _ -> inlineListDataSectionValues t (concat [l | ListDesc l <- elements])
InlineDataType _ -> [(0, EncodedBytes $ concat [l | DataDesc l <- elements])]
_ -> error "Unknown inline composite type."
SizeReference -> []
SizeData size -> let
......@@ -317,6 +314,7 @@ inlineListPointerSectionValues elementType elements = case fieldSize elementType
(SizeInlineComposite _ _) -> case elementType of
InlineStructType desc -> inlineStructListPointerSectionValues desc elements
InlineListType t _ -> inlineListPointerSectionValues t (concat [l | ListDesc l <- elements])
InlineDataType _ -> []
_ -> error "Unknown inline composite type."
SizeReference -> zip [0..] $ map (encodePointerValue elementType) elements
SizeData _ -> []
......@@ -348,9 +346,7 @@ inlineStructListPointerSectionValues elementDesc elements = do
encodeMessage (StructType desc) (StructValueDesc assignments) = let
(dataBytes, refBytes, childBytes) = encodeStruct desc assignments 0
in concat [encodeStructReference desc (0::Integer), dataBytes, refBytes, childBytes]
encodeMessage (InlineStructType desc) val = encodeMessage (StructType desc) val
encodeMessage (ListType elementType) (ListDesc elements) = let
(ptr, listBytes) = encodeList elementType elements
in ptr (0::Integer) ++ listBytes
encodeMessage (InlineListType elementType _) val = encodeMessage (ListType elementType) val
encodeMessage _ _ = error "Not a message."
......@@ -166,13 +166,13 @@ public:
{{#fieldIsBlob}}
inline {{fieldType}}::Builder get{{fieldTitleCase}}();
inline void set{{fieldTitleCase}}({{fieldType}}::Reader value);
inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size);
inline {{fieldType}}::Builder init{{fieldTitleCase}}({{^fieldIsInlineBlob}}unsigned int size{{/fieldIsInlineBlob}});
{{/fieldIsBlob}}
{{#fieldIsStruct}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}();
inline {{fieldType}}::Builder get{{fieldTitleCase}}();
{{/fieldIsStruct}}
{{#fieldIsNonStructList}}
{{#fieldIsList}}
{{#fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}();
{{/fieldIsInlineList}}
......@@ -188,16 +188,7 @@ public:
{{^fieldIsPrimitiveList}}
inline void set{{fieldTitleCase}}(std::initializer_list<{{fieldElementType}}::Reader> other);
{{/fieldIsPrimitiveList}}
{{/fieldIsNonStructList}}
{{#fieldIsStructList}}
{{#fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}();
{{/fieldIsInlineList}}
{{^fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size);
{{/fieldIsInlineList}}
inline {{fieldType}}::Builder get{{fieldTitleCase}}();
{{/fieldIsStructList}}
{{/fieldIsList}}
{{/typeFields}}
private:
::capnproto::internal::StructBuilder _builder;
......@@ -264,6 +255,47 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}({{fieldType}} value
{{/fieldIsPrimitive}}
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsBlob}}
{{#fieldIsInlineBlob}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return _reader.getInline{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return _builder.getInline{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}({{fieldType}}::Reader value) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
_builder.setInline{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES,
value);
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return _builder.initInline{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
{{/fieldIsInlineBlob}}
{{^fieldIsInlineBlob}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
......@@ -303,6 +335,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
return _builder.init{{fieldBlobType}}Field(
{{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::BYTES);
}
{{/fieldIsInlineBlob}}
{{/fieldIsBlob}}
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsStruct}}
......@@ -366,7 +399,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{/fieldIsInlineStruct}}
{{/fieldIsStruct}}
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsNonStructList}}
{{#fieldIsList}}
{{#fieldIsInlineList}}
{{#fieldIsPrimitiveList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
......@@ -402,7 +435,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
::capnproto::internal::FieldSize::{{fieldElementSize}}));
}
{{/fieldIsPrimitiveList}}
{{^fieldIsPrimitiveList}}
{{#fieldIsPointerList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
......@@ -432,10 +465,48 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS));
}
{{/fieldIsPrimitiveList}}
{{/fieldIsPointerList}}
{{#fieldIsStructList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Reader(_reader.getInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.getInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
}
{{/fieldIsStructList}}
{{/fieldIsInlineList}}
{{! --------------------------------- }}
{{^fieldIsInlineList}}
{{^fieldIsStructList}}
{{^fieldIsInlineBlobList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
......@@ -456,7 +527,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
return {{fieldType}}::Builder(_builder.initListField(
{{fieldOffset}} * ::capnproto::REFERENCES,
::capnproto::internal::FieldSize::{{fieldElementSize}},
size * ::capnproto::ELEMENTS));
size{{fieldInlineMultiplier}} * ::capnproto::ELEMENTS));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
......@@ -468,77 +539,37 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
}
{{/fieldIsInlineList}}
{{! --------------------------------- }}
template <typename _t>
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(const _t& other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{#fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}> other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{/fieldIsPrimitiveList}}
{{^fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}::Reader> other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{/fieldIsPrimitiveList}}
{{/fieldIsNonStructList}}
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsStructList}}
{{#fieldIsInlineList}}
{{/fieldIsInlineBlobList}}
{{/fieldIsStructList}}
{{#fieldIsInlineBlobList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Reader(_reader.getInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::STRUCT_SIZE));
return {{fieldType}}::Reader(_reader.get{{fieldBlobType}}Field(
{{fieldOffset}} * ::capnproto::REFERENCES, nullptr, 0 * ::capnproto::BYTES));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(unsigned int size) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::STRUCT_SIZE));
return {{fieldType}}::Builder(_builder.init{{fieldBlobType}}Field(
{{fieldOffset}} * ::capnproto::REFERENCES,
size{{fieldInlineMultiplier}} * ::capnproto::BYTES));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.getInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::STRUCT_SIZE));
return {{fieldType}}::Builder(_builder.get{{fieldBlobType}}Field(
{{fieldOffset}} * ::capnproto::REFERENCES, nullptr, 0 * ::capnproto::BYTES));
}
{{/fieldIsInlineList}}
{{^fieldIsInlineList}}
{{/fieldIsInlineBlobList}}
{{#fieldIsStructList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
......@@ -557,8 +588,9 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initStructListField(
{{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::ELEMENTS,
{{fieldElementType}}::STRUCT_SIZE));
{{fieldOffset}} * ::capnproto::REFERENCES,
size{{fieldInlineMultiplier}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
......@@ -570,8 +602,40 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
}
{{/fieldIsInlineList}}
{{/fieldIsStructList}}
{{/fieldIsInlineList}}
{{! --------------------------------- }}
template <typename _t>
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(const _t& other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{#fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}> other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{/fieldIsPrimitiveList}}
{{^fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}::Reader> other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{/fieldIsPrimitiveList}}
{{/fieldIsList}}
{{! ------------------------------------------------------------------------------------------- }}
{{/typeFields}}
{{/typeStructOrUnion}}
{{/fileTypes}}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment