Commit eab15190 authored by Kenton Varda's avatar Kenton Varda

Runtime support and tests for inline lists.

parent 13ab0872
...@@ -594,6 +594,184 @@ TEST(Encoding, InlineDefaults) { ...@@ -594,6 +594,184 @@ TEST(Encoding, InlineDefaults) {
EXPECT_EQ("qux", unions.getUnion3().getF16p().getP0()); EXPECT_EQ("qux", unions.getUnion3().getF16p().getP0());
EXPECT_EQ("quux", unions.getUnion3().getF16p().getP1()); 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.getStructList1()[0].getF());
EXPECT_FALSE(lists.getStructList1()[1].getF());
// EXPECT_TRUE(lists.getStructList1()[2].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.getStructList1p()[0].getF().getF());
EXPECT_EQ("quux", lists.getStructList1p()[0].getP0());
EXPECT_EQ("corge", lists.getStructList1p()[1].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());
}
} }
// ======================================================================================= // =======================================================================================
......
...@@ -102,6 +102,8 @@ static const AlignedData<2> SUBSTRUCT_DEFAULT = {{0,0,0,0,1,0,0,0, 0,0,0,0,0,0, ...@@ -102,6 +102,8 @@ static const AlignedData<2> SUBSTRUCT_DEFAULT = {{0,0,0,0,1,0,0,0, 0,0,0,0,0,0,
static const AlignedData<2> STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT = static const AlignedData<2> STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT =
{{0,0,0,0,1,0,0,0, 0,0,0,0,0,0,0,0}}; {{0,0,0,0,1,0,0,0, 0,0,0,0,0,0,0,0}};
static constexpr StructSize STRUCTLIST_ELEMENT_SIZE(1 * WORDS, 1 * REFERENCES, 64 * BITS);
static void setupStruct(StructBuilder builder) { static void setupStruct(StructBuilder builder) {
builder.setDataField<uint64_t>(0 * ELEMENTS, 0x1011121314151617ull); builder.setDataField<uint64_t>(0 * ELEMENTS, 0x1011121314151617ull);
builder.setDataField<uint32_t>(2 * ELEMENTS, 0x20212223u); builder.setDataField<uint32_t>(2 * ELEMENTS, 0x20212223u);
...@@ -118,7 +120,7 @@ static void setupStruct(StructBuilder builder) { ...@@ -118,7 +120,7 @@ static void setupStruct(StructBuilder builder) {
{ {
StructBuilder subStruct = builder.initStructField( StructBuilder subStruct = builder.initStructField(
0 * REFERENCES, StructSize(1 * WORDS, 0 * REFERENCES)); 0 * REFERENCES, StructSize(1 * WORDS, 0 * REFERENCES, 64 * BITS));
subStruct.setDataField<uint32_t>(0 * ELEMENTS, 123); subStruct.setDataField<uint32_t>(0 * ELEMENTS, 123);
} }
...@@ -132,12 +134,12 @@ static void setupStruct(StructBuilder builder) { ...@@ -132,12 +134,12 @@ static void setupStruct(StructBuilder builder) {
{ {
ListBuilder list = builder.initStructListField( ListBuilder list = builder.initStructListField(
2 * REFERENCES, 4 * ELEMENTS, StructSize(1 * WORDS, 1 * REFERENCES)); 2 * REFERENCES, 4 * ELEMENTS, STRUCTLIST_ELEMENT_SIZE);
EXPECT_EQ(4 * ELEMENTS, list.size()); EXPECT_EQ(4 * ELEMENTS, list.size());
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
StructBuilder element = list.getStructElement(i * ELEMENTS, 2 * WORDS / ELEMENTS, 1 * WORDS); StructBuilder element = list.getStructElement(i * ELEMENTS, STRUCTLIST_ELEMENT_SIZE);
element.setDataField<int32_t>(0 * ELEMENTS, 300 + i); element.setDataField<int32_t>(0 * ELEMENTS, 300 + i);
element.initStructField(0 * REFERENCES, StructSize(1 * WORDS, 0 * REFERENCES)) element.initStructField(0 * REFERENCES, StructSize(1 * WORDS, 0 * REFERENCES, 64 * BITS))
.setDataField<int32_t>(0 * ELEMENTS, 400 + i); .setDataField<int32_t>(0 * ELEMENTS, 400 + i);
} }
} }
...@@ -147,7 +149,7 @@ static void setupStruct(StructBuilder builder) { ...@@ -147,7 +149,7 @@ static void setupStruct(StructBuilder builder) {
EXPECT_EQ(5 * ELEMENTS, list.size()); EXPECT_EQ(5 * ELEMENTS, list.size());
for (uint i = 0; i < 5; i++) { for (uint i = 0; i < 5; i++) {
ListBuilder element = list.initListElement( ListBuilder element = list.initListElement(
i * REFERENCES, FieldSize::TWO_BYTES, (i + 1) * ELEMENTS); i * ELEMENTS, FieldSize::TWO_BYTES, (i + 1) * ELEMENTS);
EXPECT_EQ((i + 1) * ELEMENTS, element.size()); EXPECT_EQ((i + 1) * ELEMENTS, element.size());
for (uint j = 0; j <= i; j++) { for (uint j = 0; j <= i; j++) {
element.setDataElement<uint16_t>(j * ELEMENTS, 500 + j); element.setDataElement<uint16_t>(j * ELEMENTS, 500 + j);
...@@ -172,7 +174,7 @@ static void checkStruct(StructBuilder builder) { ...@@ -172,7 +174,7 @@ static void checkStruct(StructBuilder builder) {
{ {
StructBuilder subStruct = builder.getStructField( StructBuilder subStruct = builder.getStructField(
0 * REFERENCES, StructSize(1 * WORDS, 0 * REFERENCES), SUBSTRUCT_DEFAULT.words); 0 * REFERENCES, StructSize(1 * WORDS, 0 * REFERENCES, 64 * BITS), SUBSTRUCT_DEFAULT.words);
EXPECT_EQ(123u, subStruct.getDataField<uint32_t>(0 * ELEMENTS)); EXPECT_EQ(123u, subStruct.getDataField<uint32_t>(0 * ELEMENTS));
} }
...@@ -188,10 +190,10 @@ static void checkStruct(StructBuilder builder) { ...@@ -188,10 +190,10 @@ static void checkStruct(StructBuilder builder) {
ListBuilder list = builder.getListField(2 * REFERENCES, nullptr); ListBuilder list = builder.getListField(2 * REFERENCES, nullptr);
ASSERT_EQ(4 * ELEMENTS, list.size()); ASSERT_EQ(4 * ELEMENTS, list.size());
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
StructBuilder element = list.getStructElement(i * ELEMENTS, 2 * WORDS / ELEMENTS, 1 * WORDS); StructBuilder element = list.getStructElement(i * ELEMENTS, STRUCTLIST_ELEMENT_SIZE);
EXPECT_EQ(300 + i, element.getDataField<int32_t>(0 * ELEMENTS)); EXPECT_EQ(300 + i, element.getDataField<int32_t>(0 * ELEMENTS));
EXPECT_EQ(400 + i, EXPECT_EQ(400 + i,
element.getStructField(0 * REFERENCES, StructSize(1 * WORDS, 0 * REFERENCES), element.getStructField(0 * REFERENCES, StructSize(1 * WORDS, 0 * REFERENCES, 64 * BITS),
STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT.words) STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT.words)
.getDataField<int32_t>(0 * ELEMENTS)); .getDataField<int32_t>(0 * ELEMENTS));
} }
...@@ -201,7 +203,7 @@ static void checkStruct(StructBuilder builder) { ...@@ -201,7 +203,7 @@ static void checkStruct(StructBuilder builder) {
ListBuilder list = builder.getListField(3 * REFERENCES, nullptr); ListBuilder list = builder.getListField(3 * REFERENCES, nullptr);
ASSERT_EQ(5 * ELEMENTS, list.size()); ASSERT_EQ(5 * ELEMENTS, list.size());
for (uint i = 0; i < 5; i++) { for (uint i = 0; i < 5; i++) {
ListBuilder element = list.getListElement(i * REFERENCES); ListBuilder element = list.getListElement(i * ELEMENTS);
ASSERT_EQ((i + 1) * ELEMENTS, element.size()); ASSERT_EQ((i + 1) * ELEMENTS, element.size());
for (uint j = 0; j <= i; j++) { for (uint j = 0; j <= i; j++) {
EXPECT_EQ(500u + j, element.getDataElement<uint16_t>(j * ELEMENTS)); EXPECT_EQ(500u + j, element.getDataElement<uint16_t>(j * ELEMENTS));
...@@ -254,7 +256,7 @@ static void checkStruct(StructReader reader) { ...@@ -254,7 +256,7 @@ static void checkStruct(StructReader reader) {
ListReader list = reader.getListField(3 * REFERENCES, FieldSize::REFERENCE, nullptr); ListReader list = reader.getListField(3 * REFERENCES, FieldSize::REFERENCE, nullptr);
ASSERT_EQ(5 * ELEMENTS, list.size()); ASSERT_EQ(5 * ELEMENTS, list.size());
for (uint i = 0; i < 5; i++) { for (uint i = 0; i < 5; i++) {
ListReader element = list.getListElement(i * REFERENCES, FieldSize::TWO_BYTES); ListReader element = list.getListElement(i * ELEMENTS, FieldSize::TWO_BYTES);
ASSERT_EQ((i + 1) * ELEMENTS, element.size()); ASSERT_EQ((i + 1) * ELEMENTS, element.size());
for (uint j = 0; j <= i; j++) { for (uint j = 0; j <= i; j++) {
EXPECT_EQ(500u + j, element.getDataElement<uint16_t>(j * ELEMENTS)); EXPECT_EQ(500u + j, element.getDataElement<uint16_t>(j * ELEMENTS));
...@@ -270,7 +272,7 @@ TEST(WireFormat, StructRoundTrip_OneSegment) { ...@@ -270,7 +272,7 @@ TEST(WireFormat, StructRoundTrip_OneSegment) {
word* rootLocation = segment->allocate(1 * WORDS); word* rootLocation = segment->allocate(1 * WORDS);
StructBuilder builder = StructBuilder::initRoot( StructBuilder builder = StructBuilder::initRoot(
segment, rootLocation, StructSize(2 * WORDS, 4 * REFERENCES)); segment, rootLocation, StructSize(2 * WORDS, 4 * REFERENCES, 128 * BITS));
setupStruct(builder); setupStruct(builder);
// word count: // word count:
...@@ -306,7 +308,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) { ...@@ -306,7 +308,7 @@ TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
word* rootLocation = segment->allocate(1 * WORDS); word* rootLocation = segment->allocate(1 * WORDS);
StructBuilder builder = StructBuilder::initRoot( StructBuilder builder = StructBuilder::initRoot(
segment, rootLocation, StructSize(2 * WORDS, 4 * REFERENCES)); segment, rootLocation, StructSize(2 * WORDS, 4 * REFERENCES, 128 * BITS));
setupStruct(builder); setupStruct(builder);
// Verify that we made 15 segments. // Verify that we made 15 segments.
...@@ -343,7 +345,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) { ...@@ -343,7 +345,7 @@ TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
word* rootLocation = segment->allocate(1 * WORDS); word* rootLocation = segment->allocate(1 * WORDS);
StructBuilder builder = StructBuilder::initRoot( StructBuilder builder = StructBuilder::initRoot(
segment, rootLocation, StructSize(2 * WORDS, 4 * REFERENCES)); segment, rootLocation, StructSize(2 * WORDS, 4 * REFERENCES, 128 * BITS));
setupStruct(builder); setupStruct(builder);
// Verify that we made 6 segments. // Verify that we made 6 segments.
......
This diff is collapsed.
This diff is collapsed.
...@@ -236,8 +236,7 @@ struct List<T, false> { ...@@ -236,8 +236,7 @@ struct List<T, false> {
inline uint size() { return builder.size() / ELEMENTS; } inline uint size() { return builder.size() / ELEMENTS; }
inline typename T::Builder operator[](uint index) { inline typename T::Builder operator[](uint index) {
return typename T::Builder(builder.getStructElement(index * ELEMENTS, return typename T::Builder(builder.getStructElement(index * ELEMENTS, T::STRUCT_SIZE));
T::STRUCT_SIZE.total() / ELEMENTS, T::STRUCT_SIZE.data));
} }
typedef internal::IndexingIterator<Builder, typename T::Builder> iterator; typedef internal::IndexingIterator<Builder, typename T::Builder> iterator;
...@@ -282,11 +281,11 @@ struct List<List<T>, true> { ...@@ -282,11 +281,11 @@ struct List<List<T>, true> {
inline uint size() { return builder.size() / ELEMENTS; } inline uint size() { return builder.size() / ELEMENTS; }
inline typename List<T>::Builder operator[](uint index) { inline typename List<T>::Builder operator[](uint index) {
return typename List<T>::Builder(builder.getListElement(index * REFERENCES)); return typename List<T>::Builder(builder.getListElement(index * ELEMENTS));
} }
inline typename List<T>::Builder init(uint index, uint size) { inline typename List<T>::Builder init(uint index, uint size) {
return typename List<T>::Builder(builder.initListElement( return typename List<T>::Builder(builder.initListElement(
index * REFERENCES, internal::FieldSizeForType<T>::value, size * ELEMENTS)); index * ELEMENTS, internal::FieldSizeForType<T>::value, size * ELEMENTS));
} }
typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator; typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator;
...@@ -312,7 +311,7 @@ struct List<List<T>, false> { ...@@ -312,7 +311,7 @@ struct List<List<T>, false> {
inline uint size() { return reader.size() / ELEMENTS; } inline uint size() { return reader.size() / ELEMENTS; }
inline typename List<T>::Reader operator[](uint index) { inline typename List<T>::Reader operator[](uint index) {
return typename List<T>::Reader(reader.getListElement(index * REFERENCES, return typename List<T>::Reader(reader.getListElement(index * ELEMENTS,
internal::FieldSizeForType<T>::value)); internal::FieldSizeForType<T>::value));
} }
...@@ -331,11 +330,11 @@ struct List<List<T>, false> { ...@@ -331,11 +330,11 @@ struct List<List<T>, false> {
inline uint size() { return builder.size() / ELEMENTS; } inline uint size() { return builder.size() / ELEMENTS; }
inline typename List<T>::Builder operator[](uint index) { inline typename List<T>::Builder operator[](uint index) {
return typename List<T>::Builder(builder.getListElement(index * REFERENCES)); return typename List<T>::Builder(builder.getListElement(index * ELEMENTS));
} }
inline typename List<T>::Builder init(uint index, uint size) { inline typename List<T>::Builder init(uint index, uint size) {
return typename List<T>::Builder(builder.initStructListElement( return typename List<T>::Builder(builder.initStructListElement(
index * REFERENCES, size * ELEMENTS, T::DEFAULT.words)); index * ELEMENTS, size * ELEMENTS, T::DEFAULT.words));
} }
typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator; typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator;
...@@ -361,7 +360,7 @@ struct List<Data, false> { ...@@ -361,7 +360,7 @@ struct List<Data, false> {
inline uint size() { return reader.size() / ELEMENTS; } inline uint size() { return reader.size() / ELEMENTS; }
inline Data::Reader operator[](uint index) { inline Data::Reader operator[](uint index) {
return reader.getDataElement(index * REFERENCES); return reader.getDataElement(index * ELEMENTS);
} }
typedef internal::IndexingIterator<Reader, Data::Reader> iterator; typedef internal::IndexingIterator<Reader, Data::Reader> iterator;
...@@ -379,13 +378,13 @@ struct List<Data, false> { ...@@ -379,13 +378,13 @@ struct List<Data, false> {
inline uint size() { return builder.size() / ELEMENTS; } inline uint size() { return builder.size() / ELEMENTS; }
inline Data::Builder operator[](uint index) { inline Data::Builder operator[](uint index) {
return builder.getDataElement(index * REFERENCES); return builder.getDataElement(index * ELEMENTS);
} }
inline void set(uint index, Data::Reader value) { inline void set(uint index, Data::Reader value) {
builder.setDataElement(index * REFERENCES, value); builder.setDataElement(index * ELEMENTS, value);
} }
inline Data::Builder init(uint index, uint size) { inline Data::Builder init(uint index, uint size) {
return builder.initDataElement(index * REFERENCES, size * BYTES); return builder.initDataElement(index * ELEMENTS, size * BYTES);
} }
typedef internal::IndexingIterator<Builder, Data::Builder> iterator; typedef internal::IndexingIterator<Builder, Data::Builder> iterator;
...@@ -425,7 +424,7 @@ struct List<Text, false> { ...@@ -425,7 +424,7 @@ struct List<Text, false> {
inline uint size() { return reader.size() / ELEMENTS; } inline uint size() { return reader.size() / ELEMENTS; }
inline Text::Reader operator[](uint index) { inline Text::Reader operator[](uint index) {
return reader.getTextElement(index * REFERENCES); return reader.getTextElement(index * ELEMENTS);
} }
typedef internal::IndexingIterator<Reader, Text::Reader> iterator; typedef internal::IndexingIterator<Reader, Text::Reader> iterator;
...@@ -443,13 +442,13 @@ struct List<Text, false> { ...@@ -443,13 +442,13 @@ struct List<Text, false> {
inline uint size() { return builder.size() / ELEMENTS; } inline uint size() { return builder.size() / ELEMENTS; }
inline Text::Builder operator[](uint index) { inline Text::Builder operator[](uint index) {
return builder.getTextElement(index * REFERENCES); return builder.getTextElement(index * ELEMENTS);
} }
inline void set(uint index, Text::Reader value) { inline void set(uint index, Text::Reader value) {
builder.setTextElement(index * REFERENCES, value); builder.setTextElement(index * ELEMENTS, value);
} }
inline Text::Builder init(uint index, uint size) { inline Text::Builder init(uint index, uint size) {
return builder.initTextElement(index * REFERENCES, size * BYTES); return builder.initTextElement(index * ELEMENTS, size * BYTES);
} }
typedef internal::IndexingIterator<Builder, Text::Builder> iterator; typedef internal::IndexingIterator<Builder, Text::Builder> iterator;
......
...@@ -276,7 +276,7 @@ struct TestUsing { ...@@ -276,7 +276,7 @@ struct TestUsing {
innerNestedEnum @0 :NestedEnum = quux; innerNestedEnum @0 :NestedEnum = quux;
} }
struct TestInline0 fixed(0 bits) {} struct TestInline0 fixed(0 bits) { f @0: Void; }
struct TestInline1 fixed(1 bits) { f @0: Bool; } struct TestInline1 fixed(1 bits) { f @0: Bool; }
struct TestInline8 fixed(8 bits) { f0 @0: Bool; f1 @1: Bool; f2 @2: Bool; } struct TestInline8 fixed(8 bits) { f0 @0: Bool; f1 @1: Bool; f2 @2: Bool; }
struct TestInline16 fixed(16 bits) { f0 @0: UInt8; f1 @1: UInt8; } struct TestInline16 fixed(16 bits) { f0 @0: UInt8; f1 @1: UInt8; }
...@@ -384,9 +384,37 @@ struct TestInlineUnions { ...@@ -384,9 +384,37 @@ struct TestInlineUnions {
byte0 @39: UInt8; byte0 @39: UInt8;
} }
struct TestInlineLists {
voidList @ 0 : InlineList(Void, 2);
boolList @ 1 : InlineList(Bool, 3);
uInt8List @ 2 : InlineList(UInt8, 4);
uInt16List @ 3 : InlineList(UInt16, 5);
uInt32List @ 4 : InlineList(UInt32, 6);
uInt64List @ 5 : InlineList(UInt64, 7);
textList @ 6 : InlineList(Text, 8);
structList0 @ 7 : InlineList(TestInline0, 2);
structList1 @ 8 : InlineList(TestInline1, 3);
structList8 @ 9 : InlineList(TestInline8, 4);
structList16 @10 : InlineList(TestInline16, 2);
structList32 @11 : InlineList(TestInline32, 3);
structList64 @12 : InlineList(TestInline64, 4);
structList128 @13 : InlineList(TestInline128, 2);
structList192 @14 : InlineList(TestInline192, 3);
structList0p @15 : InlineList(TestInline0p, 4);
structList1p @16 : InlineList(TestInline1p, 2);
structList8p @17 : InlineList(TestInline8p, 3);
structList16p @18 : InlineList(TestInline16p, 4);
structList32p @19 : InlineList(TestInline32p, 2);
structList64p @20 : InlineList(TestInline64p, 3);
structList128p @21 : InlineList(TestInline128p, 4);
structList192p @22 : InlineList(TestInline192p, 2);
}
struct TestInlineDefaults { struct TestInlineDefaults {
normal @0 :TestInlineLayout = ( normal @0 :TestInlineLayout = (
f0 = (), f0 = (f = void),
f1 = (f = true), f1 = (f = true),
f8 = (f0 = true, f1 = false, f2 = true), f8 = (f0 = true, f1 = false, f2 = true),
f16 = (f0 = 123, f1 = 45), f16 = (f0 = 123, f1 = 45),
...@@ -411,4 +439,52 @@ struct TestInlineDefaults { ...@@ -411,4 +439,52 @@ struct TestInlineDefaults {
union1 = f128(f0 = 1234567890123, f1 = 4567890123456), union1 = f128(f0 = 1234567890123, f1 = 4567890123456),
union2 = f1p(p0 = "foo"), union2 = f1p(p0 = "foo"),
union3 = f16p(f = (f0 = 98, f1 = 76), p0 = "qux", p1 = "quux")); union3 = f16p(f = (f0 = 98, f1 = 76), p0 = "qux", p1 = "quux"));
lists @2 :TestInlineLists = (
voidList = [void, void],
boolList = [false, true, false],
uInt8List = [12, 34, 56, 78],
uInt16List = [1234, 5678, 9012, 3456, 7890],
uInt32List = [123456789, 234567890, 345678901, 456789012, 567890123, 678901234],
uInt64List = [1, 2, 3, 4, 5, 6, 7],
textList = ["foo", "bar", "baz", "qux", "quux", "corge", "grault", "garply"],
structList0 = [(f = void), ()],
structList1 = [(f = true), (f = false), (f = true)],
structList8 = [(f0 = true, f1 = false, f2 = false),
(f0 = false, f1 = true, f2 = false),
(f0 = true, f1 = true, f2 = false),
(f0 = false, f1 = false, f2 = true)],
structList16 = [(f0 = 12, f1 = 34), (f0 = 56, f1 = 78)],
structList32 = [(f0 = 90, f1 = 12345), (f0 = 67, f1 = 8901), (f0 = 23, f1 = 45678)],
structList64 = [(f0 = 90, f1 = 123456789), (f0 = 12, f1 = 345678901),
(f0 = 234, f1 = 567890123), (f0 = 45, f1 = 678901234)],
structList128 = [(f0 = 56789012345678, f1 = 90123456789012),
(f0 = 34567890123456, f1 = 78901234567890)],
structList192 = [(f0 = 1234567890123, f1 = 4567890123456, f2 = 7890123456789),
(f0 = 123456789012, f1 = 3456789012345, f2 = 6789012345678),
(f0 = 9012345678901, f1 = 2345678901234, f2 = 5678901234567)],
structList0p = [(f = (f = void), p0 = "foo"), (p0 = "bar"),
(f = (), p0 = "baz"), (p0 = "qux")],
structList1p = [(f = (f = true), p0 = "quux"), (p0 = "corge")],
structList8p = [(f = (f0 = true), p0 = "grault"), (p0 = "garply"), (p0 = "waldo")],
structList16p = [(f = (f0 = 123), p0 = "fred", p1 = "plugh"),
(p0 = "xyzzy", p1 = "thud"),
(p0 = "foobar", p1 = "barbaz"),
(p0 = "bazqux", p1 = "quxquux")],
structList32p = [(f = (f1 = 12345), p0 = "quuxcorge", p1 = "corgegrault"),
(p0 = "graultgarply", p1 = "garplywaldo")],
structList64p = [(f = (f1 = 123456789), p0 = "waldofred", p1 = "fredplugh"),
(p0 = "plughxyzzy", p1 = "xyzzythud"),
(p0 = "thudfoo", p1 = "foofoo")],
structList128p = [(f = (f1 = 123456789012345),
p0 = "foobaz", p1 = "fooqux", p2 = "foocorge"),
(p0 = "barbaz", p1 = "barqux", p2 = "barcorge"),
(p0 = "bazbaz", p1 = "bazqux", p2 = "bazcorge"),
(p0 = "quxbaz", p1 = "quxqux", p2 = "quxcorge")],
structList192p = [(f = (f2 = 123456789012345),
p0 = "corgebaz", p1 = "corgequx", p2 = "corgecorge"),
(p0 = "graultbaz", p1 = "graultqux", p2 = "graultcorge")]
);
} }
...@@ -326,6 +326,21 @@ public: ...@@ -326,6 +326,21 @@ public:
unit1PerUnit2 * other.unit1PerUnit2); unit1PerUnit2 * other.unit1PerUnit2);
} }
template <typename OtherNumber, typename Unit3>
inline constexpr UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit3, Unit2>
operator/(UnitRatio<OtherNumber, Unit1, Unit3> other) {
// (U1 / U2) / (U1 / U3) = U3 / U2
return UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit3, Unit2>(
unit1PerUnit2 / other.unit1PerUnit2);
}
template <typename OtherNumber, typename Unit3>
inline constexpr UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit1, Unit3>
operator/(UnitRatio<OtherNumber, Unit3, Unit2> other) {
// (U1 / U2) / (U3 / U2) = U1 / U3
return UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit1, Unit3>(
unit1PerUnit2 / other.unit1PerUnit2);
}
private: private:
Number unit1PerUnit2; Number unit1PerUnit2;
......
...@@ -295,7 +295,13 @@ compileType scope (TypeExpression n params) = do ...@@ -295,7 +295,13 @@ compileType scope (TypeExpression n params) = do
desc <- lookupDesc scope n desc <- lookupDesc scope n
case desc of case desc of
DescBuiltinList -> case params of DescBuiltinList -> case params of
[TypeParameterType param] -> fmap ListType (compileType scope param) [TypeParameterType param] -> do
inner <- compileType scope param
case inner of
InlineStructType _ -> makeError (declNamePos n)
"Don't declare list elements 'Inline'. The regular encoding for struct \
\lists already inlines the elements."
_ -> return (ListType inner)
_ -> makeError (declNamePos n) "'List' requires exactly one type parameter." _ -> makeError (declNamePos n) "'List' requires exactly one type parameter."
DescBuiltinInline -> case params of DescBuiltinInline -> case params of
[TypeParameterType param] -> do [TypeParameterType param] -> do
...@@ -311,7 +317,18 @@ compileType scope (TypeExpression n params) = do ...@@ -311,7 +317,18 @@ compileType scope (TypeExpression n params) = do
DescBuiltinInlineList -> case params of DescBuiltinInlineList -> case params of
[TypeParameterType param, TypeParameterInteger size] -> do [TypeParameterType param, TypeParameterInteger size] -> do
inner <- compileType scope param inner <- compileType scope param
return $ InlineListType inner size case inner of
InlineStructType _ -> makeError (declNamePos n)
"Don't declare list elements 'Inline'. The regular encoding for struct \
\lists already inlines the elements."
StructType s -> if structIsFixedWidth s
then return (InlineListType (InlineStructType s) size)
else makeError (declNamePos n) $
printf "'%s' cannot be inlined because it is not fixed-width."
(structName s)
InlineListType _ _ -> makeError (declNamePos n)
"InlineList of InlineList not currently supported."
_ -> return $ InlineListType inner size
_ -> makeError (declNamePos n) _ -> makeError (declNamePos n)
"'InlineList' requires exactly two type parameters: a type and a size." "'InlineList' requires exactly two type parameters: a type and a size."
_ -> case params of _ -> case params of
......
...@@ -105,17 +105,24 @@ isInlineStruct (InlineStructType _) = True ...@@ -105,17 +105,24 @@ isInlineStruct (InlineStructType _) = True
isInlineStruct _ = False isInlineStruct _ = False
isList (ListType _) = True isList (ListType _) = True
isList (InlineListType _ _) = True
isList _ = False isList _ = False
isNonStructList (ListType t) = not $ isStruct t isNonStructList (ListType t) = not $ isStruct t
isNonStructList (InlineListType t _) = not $ isStruct t
isNonStructList _ = False isNonStructList _ = False
isPrimitiveList (ListType t) = isPrimitive t isPrimitiveList (ListType t) = isPrimitive t
isPrimitiveList (InlineListType t _) = isPrimitive t
isPrimitiveList _ = False isPrimitiveList _ = False
isStructList (ListType t) = isStruct t isStructList (ListType t) = isStruct t
isStructList (InlineListType t _) = isStruct t
isStructList _ = False isStructList _ = False
isInlineList (InlineListType _ _) = True
isInlineList _ = False
blobTypeString (BuiltinType BuiltinText) = "Text" blobTypeString (BuiltinType BuiltinText) = "Text"
blobTypeString (BuiltinType BuiltinData) = "Data" blobTypeString (BuiltinType BuiltinData) = "Data"
blobTypeString _ = error "Not a blob." blobTypeString _ = error "Not a blob."
...@@ -139,6 +146,7 @@ cxxTypeString (StructType desc) = globalName $ DescStruct desc ...@@ -139,6 +146,7 @@ cxxTypeString (StructType desc) = globalName $ DescStruct desc
cxxTypeString (InlineStructType desc) = globalName $ DescStruct desc cxxTypeString (InlineStructType desc) = globalName $ DescStruct desc
cxxTypeString (InterfaceType desc) = globalName $ DescInterface desc cxxTypeString (InterfaceType desc) = globalName $ DescInterface desc
cxxTypeString (ListType t) = concat [" ::capnproto::List<", cxxTypeString t, ">"] cxxTypeString (ListType t) = concat [" ::capnproto::List<", cxxTypeString t, ">"]
cxxTypeString (InlineListType t _) = concat [" ::capnproto::List<", cxxTypeString t, ">"]
cxxFieldSizeString SizeVoid = "VOID"; cxxFieldSizeString SizeVoid = "VOID";
cxxFieldSizeString (SizeData Size1) = "BIT"; cxxFieldSizeString (SizeData Size1) = "BIT";
...@@ -203,6 +211,7 @@ defaultValueBytes t v@(ListDesc _) = Just $ encodeMessage t v ...@@ -203,6 +211,7 @@ defaultValueBytes t v@(ListDesc _) = Just $ encodeMessage t v
defaultValueBytes _ _ = Nothing defaultValueBytes _ _ = Nothing
elementType (ListType t) = t elementType (ListType t) = t
elementType (InlineListType t _) = t
elementType _ = error "Called elementType on non-list." elementType _ = error "Called elementType on non-list."
repeatedlyTake _ [] = [] repeatedlyTake _ [] = []
...@@ -244,6 +253,7 @@ fieldContext parent desc = mkStrContext context where ...@@ -244,6 +253,7 @@ fieldContext parent desc = mkStrContext context where
context "fieldIsNonStructList" = MuBool $ isNonStructList $ fieldType desc context "fieldIsNonStructList" = MuBool $ isNonStructList $ fieldType desc
context "fieldIsPrimitiveList" = MuBool $ isPrimitiveList $ fieldType desc context "fieldIsPrimitiveList" = MuBool $ isPrimitiveList $ fieldType desc
context "fieldIsStructList" = MuBool $ isStructList $ fieldType desc context "fieldIsStructList" = MuBool $ isStructList $ fieldType desc
context "fieldIsInlineList" = MuBool $ isInlineList $ fieldType desc
context "fieldDefaultBytes" = context "fieldDefaultBytes" =
case fieldDefaultValue desc >>= defaultValueBytes (fieldType desc) of case fieldDefaultValue desc >>= defaultValueBytes (fieldType desc) of
Just v -> muJust $ defaultBytesContext context (fieldType desc) v Just v -> muJust $ defaultBytesContext context (fieldType desc) v
...@@ -251,6 +261,23 @@ fieldContext parent desc = mkStrContext context where ...@@ -251,6 +261,23 @@ fieldContext parent desc = mkStrContext context where
context "fieldType" = MuVariable $ cxxTypeString $ fieldType desc context "fieldType" = MuVariable $ cxxTypeString $ fieldType desc
context "fieldBlobType" = MuVariable $ blobTypeString $ fieldType desc context "fieldBlobType" = MuVariable $ blobTypeString $ fieldType desc
context "fieldOffset" = MuVariable $ fieldOffsetInteger $ fieldOffset desc context "fieldOffset" = MuVariable $ fieldOffsetInteger $ fieldOffset desc
context "fieldInlineListSize" = case fieldType desc of
InlineListType _ n -> MuVariable n
_ -> muNull
context "fieldInlineDataOffset" = case fieldOffset desc of
InlineCompositeOffset off _ size _ ->
MuVariable (off * dataSizeInBits (dataSectionAlignment size))
_ -> muNull
context "fieldInlineDataSize" = case fieldOffset desc of
InlineCompositeOffset _ _ size _ ->
MuVariable $ dataSectionBits size
_ -> muNull
context "fieldInlinePointerOffset" = case fieldOffset desc of
InlineCompositeOffset _ off _ _ -> MuVariable off
_ -> muNull
context "fieldInlinePointerSize" = case fieldOffset desc of
InlineCompositeOffset _ _ _ size -> MuVariable size
_ -> muNull
context "fieldDefaultMask" = case fieldDefaultValue desc of context "fieldDefaultMask" = case fieldDefaultValue desc of
Nothing -> MuVariable "" Nothing -> MuVariable ""
Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v) Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v)
...@@ -303,6 +330,7 @@ structContext parent desc = mkStrContext context where ...@@ -303,6 +330,7 @@ structContext parent desc = mkStrContext context where
context "structFields" = MuList $ map (fieldContext context) $ structFields desc context "structFields" = MuList $ map (fieldContext context) $ structFields desc
context "structUnions" = MuList $ map (unionContext context) $ structUnions desc context "structUnions" = MuList $ map (unionContext context) $ structUnions desc
context "structDataSize" = MuVariable $ dataSectionWordSize $ structDataSize desc context "structDataSize" = MuVariable $ dataSectionWordSize $ structDataSize desc
context "structDataBits" = MuVariable $ dataSectionBits $ structDataSize desc
context "structReferenceCount" = MuVariable $ structPointerCount desc context "structReferenceCount" = MuVariable $ structPointerCount desc
context "structNestedEnums" = context "structNestedEnums" =
MuList $ map (enumContext context) [m | DescEnum m <- structMembers desc] MuList $ map (enumContext context) [m | DescEnum m <- structMembers desc]
......
...@@ -320,6 +320,7 @@ fieldSize (InterfaceType _) = SizeReference ...@@ -320,6 +320,7 @@ fieldSize (InterfaceType _) = SizeReference
fieldSize (ListType _) = SizeReference fieldSize (ListType _) = SizeReference
fieldSize (InlineListType element size) = let fieldSize (InlineListType element size) = let
minDataSectionForBits bits minDataSectionForBits bits
| bits <= 0 = DataSectionWords 0
| bits <= 1 = DataSection1 | bits <= 1 = DataSection1
| bits <= 8 = DataSection8 | bits <= 8 = DataSection8
| bits <= 16 = DataSection16 | bits <= 16 = DataSection16
...@@ -329,12 +330,12 @@ fieldSize (InlineListType element size) = let ...@@ -329,12 +330,12 @@ fieldSize (InlineListType element size) = let
SizeVoid -> DataSectionWords 0 SizeVoid -> DataSectionWords 0
SizeData s -> minDataSectionForBits $ dataSizeInBits s * size SizeData s -> minDataSectionForBits $ dataSizeInBits s * size
SizeReference -> DataSectionWords 0 SizeReference -> DataSectionWords 0
SizeInlineComposite ds _ -> minDataSectionForBits $ dataSectionBits ds SizeInlineComposite ds _ -> minDataSectionForBits $ dataSectionBits ds * size
pointerCount = case fieldSize element of pointerCount = case fieldSize element of
SizeVoid -> 0 SizeVoid -> 0
SizeData _ -> 0 SizeData _ -> 0
SizeReference -> size SizeReference -> size
SizeInlineComposite _ pc -> pc SizeInlineComposite _ pc -> pc * size
in SizeInlineComposite dataSection pointerCount in SizeInlineComposite dataSection pointerCount
-- Render the type descriptor's name as a string, appropriate for use in the given scope. -- Render the type descriptor's name as a string, appropriate for use in the given scope.
......
...@@ -29,6 +29,7 @@ import Data.Bits(shiftL, shiftR, Bits, setBit, xor) ...@@ -29,6 +29,7 @@ import Data.Bits(shiftL, shiftR, Bits, setBit, xor)
import Data.Function(on) import Data.Function(on)
import Semantics import Semantics
import Data.Binary.IEEE754(floatToWord, doubleToWord) import Data.Binary.IEEE754(floatToWord, doubleToWord)
import Text.Printf(printf)
import qualified Codec.Binary.UTF8.String as UTF8 import qualified Codec.Binary.UTF8.String as UTF8
byte :: (Integral a, Bits a) => a -> Int -> Word8 byte :: (Integral a, Bits a) => a -> Int -> Word8
...@@ -45,6 +46,7 @@ padToWord b = let ...@@ -45,6 +46,7 @@ padToWord b = let
data EncodedData = EncodedBit Bool data EncodedData = EncodedBit Bool
| EncodedBytes [Word8] | EncodedBytes [Word8]
deriving(Show)
xorData (EncodedBit a) (EncodedBit b) = EncodedBit (a /= b) xorData (EncodedBit a) (EncodedBit b) = EncodedBit (a /= b)
xorData (EncodedBytes a) (EncodedBytes b) = EncodedBytes (zipWith xor a b) xorData (EncodedBytes a) (EncodedBytes b) = EncodedBytes (zipWith xor a b)
...@@ -92,7 +94,7 @@ encodePointerValue _ _ = error "Unknown pointer type." ...@@ -92,7 +94,7 @@ encodePointerValue _ _ = error "Unknown pointer type."
packBytes :: Integer -- Total size of array to pack, in bits. packBytes :: Integer -- Total size of array to pack, in bits.
-> [(Integer, EncodedData)] -- (offset, data) pairs to pack. Must be in order. -> [(Integer, EncodedData)] -- (offset, data) pairs to pack. Must be in order.
-> [Word8] -> [Word8]
packBytes size = padToWord . loop 0 where packBytes size items = padToWord $ loop 0 items where
loop :: Integer -> [(Integer, EncodedData)] -> [Word8] loop :: Integer -> [(Integer, EncodedData)] -> [Word8]
loop bit [] | bit <= size = genericReplicate (div (size - bit + 7) 8) 0 loop bit [] | bit <= size = genericReplicate (div (size - bit + 7) 8) 0
loop bit [] | bit > size = error "Data values overran size." loop bit [] | bit > size = error "Data values overran size."
...@@ -103,7 +105,8 @@ packBytes size = padToWord . loop 0 where ...@@ -103,7 +105,8 @@ packBytes size = padToWord . loop 0 where
loop bit ((_, EncodedBit False):rest) = loop bit rest loop bit ((_, EncodedBit False):rest) = loop bit rest
loop bit ((offset, EncodedBytes encoded):rest) | offset == bit = loop bit ((offset, EncodedBytes encoded):rest) | offset == bit =
encoded ++ loop (bit + genericLength encoded * 8) rest encoded ++ loop (bit + genericLength encoded * 8) rest
loop _ _ = error "Data values overlapped." loop bit rest = error
(printf "Data values overlapped @%d: %s\n\n%s" bit (show rest) (show items))
bytesToWords i = if mod i 8 == 0 then div i 8 bytesToWords i = if mod i 8 == 0 then div i 8
else error "Byte count did not divide evenly into words." else error "Byte count did not divide evenly into words."
......
...@@ -69,7 +69,8 @@ struct {{typeFullName}} { ...@@ -69,7 +69,8 @@ struct {{typeFullName}} {
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE = static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
::capnproto::internal::StructSize({{structDataSize}} * ::capnproto::WORDS, ::capnproto::internal::StructSize({{structDataSize}} * ::capnproto::WORDS,
{{structReferenceCount}} * ::capnproto::REFERENCES); {{structReferenceCount}} * ::capnproto::REFERENCES,
{{structDataBits}} * ::capnproto::BITS);
{{/typeStruct}} {{/typeStruct}}
{{#typeUnion}} {{#typeUnion}}
...@@ -172,7 +173,12 @@ public: ...@@ -172,7 +173,12 @@ public:
inline {{fieldType}}::Builder get{{fieldTitleCase}}(); inline {{fieldType}}::Builder get{{fieldTitleCase}}();
{{/fieldIsStruct}} {{/fieldIsStruct}}
{{#fieldIsNonStructList}} {{#fieldIsNonStructList}}
{{#fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}();
{{/fieldIsInlineList}}
{{^fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size); inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size);
{{/fieldIsInlineList}}
inline {{fieldType}}::Builder get{{fieldTitleCase}}(); inline {{fieldType}}::Builder get{{fieldTitleCase}}();
template <typename _t> template <typename _t>
inline void set{{fieldTitleCase}}(const _t& other); inline void set{{fieldTitleCase}}(const _t& other);
...@@ -184,7 +190,12 @@ public: ...@@ -184,7 +190,12 @@ public:
{{/fieldIsPrimitiveList}} {{/fieldIsPrimitiveList}}
{{/fieldIsNonStructList}} {{/fieldIsNonStructList}}
{{#fieldIsStructList}} {{#fieldIsStructList}}
{{#fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}();
{{/fieldIsInlineList}}
{{^fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size); inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size);
{{/fieldIsInlineList}}
inline {{fieldType}}::Builder get{{fieldTitleCase}}(); inline {{fieldType}}::Builder get{{fieldTitleCase}}();
{{/fieldIsStructList}} {{/fieldIsStructList}}
{{/typeFields}} {{/typeFields}}
...@@ -356,6 +367,75 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -356,6 +367,75 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{/fieldIsStruct}} {{/fieldIsStruct}}
{{! ------------------------------------------------------------------------------------------- }} {{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsNonStructList}} {{#fieldIsNonStructList}}
{{#fieldIsInlineList}}
{{#fieldIsPrimitiveList}}
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.getInlineDataListField(
{{fieldInlineDataOffset}} * ::capnproto::BITS,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::{{fieldElementSize}}));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initInlineDataListField(
{{fieldInlineDataOffset}} * ::capnproto::BITS,
{{fieldInlineDataSize}} * ::capnproto::BITS,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::{{fieldElementSize}}));
}
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.getInlineDataListField(
{{fieldInlineDataOffset}} * ::capnproto::BITS,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
::capnproto::internal::FieldSize::{{fieldElementSize}}));
}
{{/fieldIsPrimitiveList}}
{{^fieldIsPrimitiveList}}
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.getInlinePointerListField(
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initInlinePointerListField(
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlinePointerSize}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS));
}
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.getInlinePointerListField(
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS));
}
{{/fieldIsPrimitiveList}}
{{/fieldIsInlineList}}
{{! --------------------------------- }}
{{^fieldIsInlineList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
...@@ -388,15 +468,17 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -388,15 +468,17 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}} {{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}})); {{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
} }
{{/fieldIsInlineList}}
{{! --------------------------------- }}
template <typename _t> template <typename _t>
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(const _t& other) { inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(const _t& other) {
{{#fieldUnion}} {{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>( _builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}}); {{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}} {{/fieldUnion}}
init{{fieldTitleCase}}(other.size()).copyFrom(other); init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
} }
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsPrimitiveList}} {{#fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}( inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}> other) { std::initializer_list<{{fieldElementType}}> other) {
...@@ -404,10 +486,9 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}( ...@@ -404,10 +486,9 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
_builder.setDataField<{{unionTitleCase}}::Which>( _builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}}); {{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}} {{/fieldUnion}}
init{{fieldTitleCase}}(other.size()).copyFrom(other); init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
} }
{{/fieldIsPrimitiveList}} {{/fieldIsPrimitiveList}}
{{! ------------------------------------------------------------------------------------------- }}
{{^fieldIsPrimitiveList}} {{^fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}( inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}::Reader> other) { std::initializer_list<{{fieldElementType}}::Reader> other) {
...@@ -415,12 +496,49 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}( ...@@ -415,12 +496,49 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
_builder.setDataField<{{unionTitleCase}}::Which>( _builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}}); {{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}} {{/fieldUnion}}
init{{fieldTitleCase}}(other.size()).copyFrom(other); init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
} }
{{/fieldIsPrimitiveList}} {{/fieldIsPrimitiveList}}
{{/fieldIsNonStructList}} {{/fieldIsNonStructList}}
{{! ------------------------------------------------------------------------------------------- }} {{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsStructList}} {{#fieldIsStructList}}
{{#fieldIsInlineList}}
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::BITS,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::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::BITS,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::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::BITS,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::STRUCT_SIZE));
}
{{/fieldIsInlineList}}
{{^fieldIsInlineList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
...@@ -452,6 +570,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -452,6 +570,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}} {{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}})); {{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
} }
{{/fieldIsInlineList}}
{{/fieldIsStructList}} {{/fieldIsStructList}}
{{/typeFields}} {{/typeFields}}
{{/typeStructOrUnion}} {{/typeStructOrUnion}}
......
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