Commit 8b7e9096 authored by Kenton Varda's avatar Kenton Varda

Lists working.

parent 271c4728
......@@ -39,27 +39,107 @@ TEST(Encoding, Simple) {
EXPECT_EQ(1234, builder.getA());
EXPECT_EQ(-1, builder.getB());
EXPECT_EQ(200, builder.getC());
ASSERT_EQ(0, builder.getNums().size());
ASSERT_EQ(0u, builder.getNums().size());
builder.setA(321);
builder.setB(45);
builder.setC(67);
builder.initD().setX(55.25);
List<int32_t>::Builder listBuilder = builder.initNums(5);
ASSERT_EQ(5, listBuilder.size());
listBuilder[0] = 12;
listBuilder[1] = 34;
listBuilder[2] = 56;
listBuilder[3] = 78;
listBuilder[4] = 90;
{
List<int32_t>::Builder listBuilder = builder.initNums(5);
ASSERT_EQ(5u, listBuilder.size());
listBuilder.set(0, 12);
listBuilder.set(1, 34);
listBuilder.set(2, 56);
listBuilder.set(3, 78);
listBuilder.set(4, 90);
EXPECT_EQ(12, listBuilder[0]);
EXPECT_EQ(34, listBuilder[1]);
EXPECT_EQ(56, listBuilder[2]);
EXPECT_EQ(78, listBuilder[3]);
EXPECT_EQ(90, listBuilder[4]);
{
int sum = 0;
for (int32_t i: listBuilder) {
sum += i;
}
EXPECT_EQ(12 + 34 + 56 + 78 + 90, sum);
}
}
{
List<Bar>::Builder structListBuilder = builder.initBars(3);
ASSERT_EQ(3u, structListBuilder.size());
structListBuilder[0].setX(123);
structListBuilder[1].setX(456);
structListBuilder[2].setX(789);
EXPECT_EQ(123, structListBuilder[0].getX());
EXPECT_EQ(456, structListBuilder[1].getX());
EXPECT_EQ(789, structListBuilder[2].getX());
{
double sum = 0;
for (auto bar: structListBuilder) {
sum += bar.getX();
}
EXPECT_EQ(123 + 456 + 789, sum);
}
}
{
int sum = 0;
for (int32_t i: listBuilder) {
sum += i;
List<Bar>::Builder structListBuilder = builder.getBars();
ASSERT_EQ(3u, structListBuilder.size());
EXPECT_EQ(123, structListBuilder[0].getX());
EXPECT_EQ(456, structListBuilder[1].getX());
EXPECT_EQ(789, structListBuilder[2].getX());
{
double sum = 0;
for (auto bar: structListBuilder) {
sum += bar.getX();
}
EXPECT_EQ(123 + 456 + 789, sum);
}
EXPECT_EQ(12 + 34 + 56 + 78 + 90, sum);
}
{
List<List<int32_t>>::Builder listListBuilder = builder.initPrimListList(2);
ASSERT_EQ(2u, listListBuilder.size());
List<int32_t>::Builder sublist = listListBuilder.init(0, 2);
ASSERT_EQ(2u, sublist.size());
sublist.set(0, 1234);
sublist.set(1, 5678);
sublist = listListBuilder.init(1, 4);
ASSERT_EQ(4u, sublist.size());
sublist.set(0, 21);
sublist.set(1, 43);
sublist.set(2, 65);
sublist.set(3, 87);
}
{
List<List<Bar>>::Builder listListBuilder = builder.initStructListList(2);
ASSERT_EQ(2u, listListBuilder.size());
List<Bar>::Builder sublist = listListBuilder.init(0, 2);
ASSERT_EQ(2u, sublist.size());
sublist[0].setX(1234);
sublist[1].setX(5678);
sublist = listListBuilder.init(1, 4);
ASSERT_EQ(4u, sublist.size());
sublist[0].setX(21);
sublist[1].setX(43);
sublist[2].setX(65);
sublist[3].setX(87);
}
EXPECT_EQ(321, builder.getA());
......@@ -75,20 +155,73 @@ TEST(Encoding, Simple) {
EXPECT_EQ(67, reader.getC());
EXPECT_EQ(55.25, reader.getD().getX());
List<int32_t>::Reader listReader = reader.getNums();
ASSERT_EQ(5, listReader.size());
EXPECT_EQ(12, listReader[0]);
EXPECT_EQ(34, listReader[1]);
EXPECT_EQ(56, listReader[2]);
EXPECT_EQ(78, listReader[3]);
EXPECT_EQ(90, listReader[4]);
{
List<int32_t>::Reader listReader = reader.getNums();
ASSERT_EQ(5u, listReader.size());
EXPECT_EQ(12, listReader[0]);
EXPECT_EQ(34, listReader[1]);
EXPECT_EQ(56, listReader[2]);
EXPECT_EQ(78, listReader[3]);
EXPECT_EQ(90, listReader[4]);
{
int sum = 0;
for (int32_t i: listReader) {
sum += i;
}
EXPECT_EQ(12 + 34 + 56 + 78 + 90, sum);
}
}
{
int sum = 0;
for (int32_t i: listReader) {
sum += i;
List<Bar>::Reader structListReader = reader.getBars();
ASSERT_EQ(3u, structListReader.size());
EXPECT_EQ(123, structListReader[0].getX());
EXPECT_EQ(456, structListReader[1].getX());
EXPECT_EQ(789, structListReader[2].getX());
{
double sum = 0;
for (auto bar: structListReader) {
sum += bar.getX();
}
EXPECT_EQ(123 + 456 + 789, sum);
}
EXPECT_EQ(12 + 34 + 56 + 78 + 90, sum);
}
{
List<List<int32_t>>::Reader listListReader = reader.getPrimListList();
ASSERT_EQ(2u, listListReader.size());
List<int32_t>::Reader sublist = listListReader[0];
ASSERT_EQ(2u, sublist.size());
EXPECT_EQ(1234, sublist[0]);
EXPECT_EQ(5678, sublist[1]);
sublist = listListReader[1];
ASSERT_EQ(4u, sublist.size());
EXPECT_EQ(21, sublist[0]);
EXPECT_EQ(43, sublist[1]);
EXPECT_EQ(65, sublist[2]);
EXPECT_EQ(87, sublist[3]);
}
{
List<List<Bar>>::Reader listListReader = reader.getStructListList();
ASSERT_EQ(2u, listListReader.size());
List<Bar>::Reader sublist = listListReader[0];
ASSERT_EQ(2u, sublist.size());
EXPECT_EQ(1234, sublist[0].getX());
EXPECT_EQ(5678, sublist[1].getX());
sublist = listListReader[1];
ASSERT_EQ(4u, sublist.size());
EXPECT_EQ(21, sublist[0].getX());
EXPECT_EQ(43, sublist[1].getX());
EXPECT_EQ(65, sublist[2].getX());
EXPECT_EQ(87, sublist[3].getX());
}
}
......
......@@ -25,9 +25,17 @@
#define CAPNPROTO_LIST_H_
#include "wire-format.h"
#include "descriptor.h" // only for FieldSize; TODO: Eliminate this
namespace capnproto {
namespace internal {
template <typename T> struct IsPrimitive;
} // namespace internal
template <typename T, bool isPrimitive = internal::IsPrimitive<T>::value>
struct List;
namespace internal {
template <typename T> struct IsPrimitive { static constexpr bool value = false; };
......@@ -44,6 +52,27 @@ template <> struct IsPrimitive<uint32_t> { static constexpr bool value = true; }
template <> struct IsPrimitive<uint64_t> { static constexpr bool value = true; };
template <> struct IsPrimitive<float> { static constexpr bool value = true; };
template <> struct IsPrimitive<double> { static constexpr bool value = true; };
template <typename T, bool b> struct IsPrimitive<List<T, b>> {
static constexpr bool value = IsPrimitive<T>::value;
};
template <typename T> struct FieldSizeForType { static constexpr FieldSize value = FieldSize::INLINE_COMPOSITE; };
template <> struct FieldSizeForType<void> { static constexpr FieldSize value = FieldSize::VOID; };
template <> struct FieldSizeForType<bool> { static constexpr FieldSize value = FieldSize::BIT; };
template <> struct FieldSizeForType<int8_t> { static constexpr FieldSize value = FieldSize::BYTE; };
template <> struct FieldSizeForType<int16_t> { static constexpr FieldSize value = FieldSize::TWO_BYTES; };
template <> struct FieldSizeForType<int32_t> { static constexpr FieldSize value = FieldSize::FOUR_BYTES; };
template <> struct FieldSizeForType<int64_t> { static constexpr FieldSize value = FieldSize::EIGHT_BYTES; };
template <> struct FieldSizeForType<uint8_t> { static constexpr FieldSize value = FieldSize::BYTE; };
template <> struct FieldSizeForType<uint16_t> { static constexpr FieldSize value = FieldSize::TWO_BYTES; };
template <> struct FieldSizeForType<uint32_t> { static constexpr FieldSize value = FieldSize::FOUR_BYTES; };
template <> struct FieldSizeForType<uint64_t> { static constexpr FieldSize value = FieldSize::EIGHT_BYTES; };
template <> struct FieldSizeForType<float> { static constexpr FieldSize value = FieldSize::FOUR_BYTES; };
template <> struct FieldSizeForType<double> { static constexpr FieldSize value = FieldSize::EIGHT_BYTES; };
template <typename T, bool b> struct FieldSizeForType<List<T, b>> {
static constexpr FieldSize value = FieldSize::REFERENCE;
};
template<typename T> constexpr T&& move(T& t) noexcept { return static_cast<T&&>(t); }
// Like std::move. Unfortunately, #including <utility> brings in tons of unnecessary stuff.
......@@ -64,15 +93,17 @@ private:
T value;
};
template <typename Container, typename Element, typename Reference>
template <typename Container, typename Element>
class IndexingIterator {
public:
IndexingIterator() = default;
inline Reference operator*() { return (*container)[index]; }
inline Reference operator->() { return TemporaryPointer<Element>((*container)[index]); }
inline Reference operator[]( int off) { return (*container)[index]; }
inline Reference operator[](uint off) { return (*container)[index]; }
inline Element operator*() { return (*container)[index]; }
inline TemporaryPointer<Element> operator->() {
return TemporaryPointer<Element>((*container)[index]);
}
inline Element operator[]( int off) { return (*container)[index]; }
inline Element operator[](uint off) { return (*container)[index]; }
inline IndexingIterator& operator++() { ++index; return *this; }
inline IndexingIterator operator++(int) { IndexingIterator other = *this; ++index; return other; }
......@@ -105,14 +136,11 @@ private:
uint index;
friend Container;
IndexingIterator(Container* builder, uint index): container(container), index(index) {}
inline IndexingIterator(Container* container, uint index): container(container), index(index) {}
};
} // namespace internal
template <typename T, bool isPrimitive = internal::IsPrimitive<T>::value>
struct List;
template <typename T>
struct List<T, true> {
class Reader {
......@@ -120,11 +148,10 @@ struct List<T, true> {
Reader() = default;
inline explicit Reader(internal::ListReader reader): reader(reader) {}
typedef internal::IndexingIterator<Reader, T, T> iterator;
inline T operator[](uint index) { return reader.template getDataElement<T>(index * ELEMENTS); }
inline uint size() { return reader.size() / ELEMENTS; }
inline T operator[](uint index) { return reader.template getDataElement<T>(index * ELEMENTS); }
typedef internal::IndexingIterator<Reader, T> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
......@@ -137,36 +164,62 @@ struct List<T, true> {
Builder() = default;
inline explicit Builder(internal::ListBuilder builder): builder(builder) {}
class reference {
public:
reference() = default;
inline uint size() { return builder.size() / ELEMENTS; }
inline T operator[](uint index) {
return builder.template getDataElement<T>(index * ELEMENTS);
}
inline void set(uint index, T value) {
// Alas, it is not possible to make operator[] return a reference to which you can assign,
// since the encoded representation does not necessarily match the compiler's representation
// of the type. We can't even return a clever class that implements operator T() and
// operator=() because it will lead to surprising behavior when using type inference (e.g.
// calling a template function with inferred argument types, or using "auto" or "decltype").
builder.template setDataElement<T>(index * ELEMENTS, value);
}
inline operator T() { return (*builder)[index]; }
inline reference& operator=(T value) {
builder->builder.template setDataElement<T>(index * ELEMENTS, value);
return *this;
}
typedef internal::IndexingIterator<Builder, T> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
T* operator&() {
static_assert(sizeof(T) < 0,
"You can't take the address of a list member because they are not stored in memory "
"in a directly-usable format.");
return nullptr;
}
private:
internal::ListBuilder builder;
};
};
template <typename T>
struct List<T, false> {
class Reader {
public:
Reader() = default;
inline explicit Reader(internal::ListReader reader): reader(reader) {}
inline uint size() { return reader.size() / ELEMENTS; }
inline typename T::Reader operator[](uint index) {
return typename T::Reader(reader.getStructElement(index * ELEMENTS, T::DEFAULT.words));
}
private:
Builder* builder;
uint index;
typedef internal::IndexingIterator<Reader, typename T::Reader> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
friend class Builder;
reference(Builder* builder, uint index): builder(builder), index(index) {}
};
private:
internal::ListReader reader;
};
typedef internal::IndexingIterator<Builder, T, reference> iterator;
class Builder {
public:
Builder() = default;
inline explicit Builder(internal::ListBuilder builder): builder(builder) {}
inline reference operator[](uint index) { return reference(this, index); }
inline uint size() { return builder.size() / ELEMENTS; }
inline typename T::Builder operator[](uint index) {
return typename T::Builder(builder.getStructElement(index * ELEMENTS,
(T::DATA_SIZE + T::REFERENCE_COUNT * WORDS_PER_REFERENCE) / ELEMENTS,
T::DATA_SIZE));
}
typedef internal::IndexingIterator<Builder, typename T::Builder> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
......@@ -176,19 +229,19 @@ struct List<T, true> {
};
template <typename T>
struct List<T, false> {
struct List<List<T>, true> {
class Reader {
public:
Reader() = default;
inline explicit Reader(internal::ListReader reader): reader(reader) {}
typedef internal::IndexingIterator<Reader, typename T::Reader, typename T::Reader> iterator;
inline typename T::Reader operator[](uint index) {
return typename T::Reader(reader.getStructElement(index * ELEMENTS, T::DEFAULT.words));
}
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));
}
typedef internal::IndexingIterator<Reader, typename List<T>::Reader> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
......@@ -201,38 +254,60 @@ struct List<T, false> {
Builder() = default;
inline explicit Builder(internal::ListBuilder builder): builder(builder) {}
class reference {
public:
reference() = default;
inline uint size() { return builder.size() / ELEMENTS; }
inline typename List<T>::Builder operator[](uint index) {
return typename List<T>::Builder(builder.getListElement(index * REFERENCES));
}
inline typename List<T>::Builder init(uint index, uint size) {
return typename List<T>::Builder(builder.initListElement(
index * REFERENCES, internal::FieldSizeForType<T>::value, size * ELEMENTS));
}
inline operator typename T::Builder() { return (*builder)[index]; }
typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
// TODO: operator= to accept ownership transfer.
private:
internal::ListBuilder builder;
};
};
template <typename T>
struct List<List<T>, false> {
class Reader {
public:
Reader() = default;
inline explicit Reader(internal::ListReader reader): reader(reader) {}
T* operator&() {
static_assert(sizeof(T) < 0,
"You can't take the address of a list member because they are not stored in memory "
"in a directly-usable format.");
return nullptr;
}
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));
}
private:
Builder* builder;
uint index;
typedef internal::IndexingIterator<Reader, typename List<T>::Reader> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
friend class Builder;
reference(Builder* builder, uint index): builder(builder), index(index) {}
};
private:
internal::ListReader reader;
};
typedef internal::IndexingIterator<Builder, typename T::Builder, reference> iterator;
class Builder {
public:
Builder() = default;
inline explicit Builder(internal::ListBuilder builder): builder(builder) {}
inline typename T::Builder operator[](uint index) {
return typename T::Builder(builder.getStructElement(index * ELEMENTS,
(T::DATA_SIZE + T::REFERENCE_COUNT * WORDS_PER_REFERENCE) / ELEMENTS,
T::DATA_SIZE));
}
inline uint size() { return builder.size() / ELEMENTS; }
inline typename List<T>::Builder operator[](uint index) {
return typename List<T>::Builder(builder.getListElement(index * REFERENCES));
}
inline typename List<T>::Builder init(uint index, uint size) {
return typename List<T>::Builder(builder.initStructListElement(
index * REFERENCES, size * ELEMENTS, T::DEFAULT.words));
}
typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
......
......@@ -200,7 +200,7 @@ static void checkStruct(StructBuilder builder) {
ListBuilder list = builder.getListField(3 * REFERENCES, nullptr);
ASSERT_EQ(5 * ELEMENTS, list.size());
for (uint i = 0; i < 5; i++) {
ListBuilder element = list.getListElement(i * REFERENCES, FieldSize::TWO_BYTES);
ListBuilder element = list.getListElement(i * REFERENCES);
ASSERT_EQ((i + 1) * ELEMENTS, element.size());
for (uint j = 0; j <= i; j++) {
EXPECT_EQ(500u + j, element.getDataElement<uint16_t>(j * ELEMENTS));
......@@ -253,7 +253,7 @@ static void checkStruct(StructReader reader) {
ListReader list = reader.getListField(3 * REFERENCES, FieldSize::REFERENCE, nullptr);
ASSERT_EQ(5 * ELEMENTS, list.size());
for (uint i = 0; i < 5; i++) {
ListReader element = list.getListElement(i * REFERENCES, FieldSize::TWO_BYTES, nullptr);
ListReader element = list.getListElement(i * REFERENCES, FieldSize::TWO_BYTES);
ASSERT_EQ((i + 1) * ELEMENTS, element.size());
for (uint j = 0; j <= i; j++) {
EXPECT_EQ(500u + j, element.getDataElement<uint16_t>(j * ELEMENTS));
......
......@@ -863,7 +863,7 @@ ListBuilder ListBuilder::initStructListElement(
elementCount, elementDefaultValue);
}
ListBuilder ListBuilder::getListElement(WireReferenceCount index, FieldSize elementSize) const {
ListBuilder ListBuilder::getListElement(WireReferenceCount index) const {
return WireHelpers::getWritableListReference(
reinterpret_cast<WireReference*>(ptr) + index, segment, nullptr);
}
......@@ -900,10 +900,10 @@ StructReader ListReader::getStructElement(ElementCount index, const word* defaul
}
ListReader ListReader::getListElement(
WireReferenceCount index, FieldSize expectedElementSize, const word* defaultValue) const {
WireReferenceCount index, FieldSize expectedElementSize) const {
return WireHelpers::readListReference(
segment, reinterpret_cast<const WireReference*>(ptr) + index,
defaultValue, expectedElementSize, recursionLimit);
nullptr, expectedElementSize, recursionLimit);
}
} // namespace internal
......
......@@ -240,7 +240,7 @@ public:
// elementDefaultValue. As with StructBuilder::initStructListElement(), this should be the
// default value for the *type*, with all-null references.
ListBuilder getListElement(WireReferenceCount index, FieldSize elementSize) const;
ListBuilder getListElement(WireReferenceCount index) const;
// Get the existing list element at the given index. Returns an empty list if the element is
// not initialized.
......@@ -280,8 +280,7 @@ public:
StructReader getStructElement(ElementCount index, const word* defaultValue) const;
// Get the struct element at the given index.
ListReader getListElement(WireReferenceCount index, FieldSize expectedElementSize,
const word* defaultValue) const;
ListReader getListElement(WireReferenceCount index, FieldSize expectedElementSize) const;
// Get the list element at the given index.
private:
......
......@@ -61,30 +61,30 @@ isStruct _ = False
isList (ListType _) = True
isList _ = False
isPrimitiveList (ListType t) = isPrimitive t
isPrimitiveList _ = False
isNonStructList (ListType t) = not $ isStruct t
isNonStructList _ = False
isStructList (ListType t) = isStruct t
isStructList _ = False
cxxTypeString (BuiltinType BuiltinVoid) = "void"
cxxTypeString (BuiltinType BuiltinBool) = "bool"
cxxTypeString (BuiltinType BuiltinInt8) = "int8_t"
cxxTypeString (BuiltinType BuiltinInt16) = "int16_t"
cxxTypeString (BuiltinType BuiltinInt32) = "int32_t"
cxxTypeString (BuiltinType BuiltinInt64) = "int64_t"
cxxTypeString (BuiltinType BuiltinUInt8) = "uint8_t"
cxxTypeString (BuiltinType BuiltinUInt16) = "uint16_t"
cxxTypeString (BuiltinType BuiltinUInt32) = "uint32_t"
cxxTypeString (BuiltinType BuiltinUInt64) = "uint64_t"
cxxTypeString (BuiltinType BuiltinInt8) = " ::int8_t"
cxxTypeString (BuiltinType BuiltinInt16) = " ::int16_t"
cxxTypeString (BuiltinType BuiltinInt32) = " ::int32_t"
cxxTypeString (BuiltinType BuiltinInt64) = " ::int64_t"
cxxTypeString (BuiltinType BuiltinUInt8) = " ::uint8_t"
cxxTypeString (BuiltinType BuiltinUInt16) = " ::uint16_t"
cxxTypeString (BuiltinType BuiltinUInt32) = " ::uint32_t"
cxxTypeString (BuiltinType BuiltinUInt64) = " ::uint64_t"
cxxTypeString (BuiltinType BuiltinFloat32) = "float"
cxxTypeString (BuiltinType BuiltinFloat64) = "double"
cxxTypeString (BuiltinType BuiltinText) = "TODO"
cxxTypeString (BuiltinType BuiltinData) = "TODO"
cxxTypeString (EnumType desc) = enumName desc
cxxTypeString (StructType desc) = structName desc
cxxTypeString (InterfaceType desc) = interfaceName desc
cxxTypeString (ListType t) = concat ["::capnproto::List<", cxxTypeString t, ">"]
cxxTypeString (EnumType desc) = enumName desc -- TODO: full name
cxxTypeString (StructType desc) = structName desc -- TODO: full name
cxxTypeString (InterfaceType desc) = interfaceName desc -- TODO: full name
cxxTypeString (ListType t) = concat [" ::capnproto::List<", cxxTypeString t, ">"]
cxxFieldSizeString Size0 = "VOID";
cxxFieldSizeString Size1 = "BIT";
......@@ -161,7 +161,7 @@ fieldContext parent desc = mkStrContext context where
context "fieldIsPrimitive" = MuBool $ isPrimitive $ fieldType desc
context "fieldIsStruct" = MuBool $ isStruct $ fieldType desc
context "fieldIsList" = MuBool $ isList $ fieldType desc
context "fieldIsPrimitiveList" = MuBool $ isPrimitiveList $ fieldType desc
context "fieldIsNonStructList" = MuBool $ isNonStructList $ fieldType desc
context "fieldIsStructList" = MuBool $ isStructList $ fieldType desc
context "fieldDefaultBytes" =
case fieldDefaultValue desc >>= defaultValueBytes (fieldType desc) of
......@@ -173,12 +173,16 @@ fieldContext parent desc = mkStrContext context where
Just v -> MuVariable $ cxxValueString v
Nothing -> MuVariable $ cxxDefaultDefault $ fieldType desc
context "fieldElementSize" =
MuVariable $ cxxFieldSizeString $ fieldSize $ elementType $ fieldType desc
MuVariable $ cxxFieldSizeString $ elementSize $ elementType $ fieldType desc
context "fieldElementType" =
MuVariable $ cxxTypeString $ elementType $ fieldType desc
context s = parent s
structContext parent desc = mkStrContext context where
context "structName" = MuVariable $ structName desc
context "structFields" = MuList $ map (fieldContext context) $ structFields desc
context "structDataSize" = MuVariable $ packingDataSize $ structPacking desc
context "structReferenceCount" = MuVariable $ packingReferenceCount $ structPacking desc
context "structChildren" = MuList [] -- TODO
context "structDefault" = MuList [defaultBytesContext context
(encodeMessage (StructType desc) (StructValueDesc []))]
......@@ -191,7 +195,7 @@ fileContext desc = mkStrContext context where
"CAPNPROTO_INCLUDED_" ++ hashString (fileName desc)
context "fileNamespaces" = MuList [] -- TODO
context "fileStructs" = MuList $ map (structContext context) $ fileStructs desc
context s = MuVariable $ concat ["@@@", s, "@@@"]
context s = error ("Template variable not defined: " ++ s)
headerTemplate :: String
headerTemplate = ByteStringUTF8.toString $(embedFile "src/c++-header.mustache")
......
......@@ -41,6 +41,9 @@ struct {{structName}} {
struct {{structChildName}};
{{/structChildren}}
static constexpr ::capnproto::WordCount DATA_SIZE = {{structDataSize}} * ::capnproto::WORDS;
static constexpr ::capnproto::WireReferenceCount REFERENCE_COUNT =
{{structReferenceCount}} * ::capnproto::REFERENCES;
{{#structDefault}}
static const ::capnproto::internal::AlignedData<{{defaultWordCount}}> DEFAULT;
{{/structDefault}}
......@@ -91,10 +94,10 @@ public:
inline {{fieldType}}::Builder init{{fieldTitleCase}}();
inline {{fieldType}}::Builder get{{fieldTitleCase}}();
{{/fieldIsStruct}}
{{#fieldIsPrimitiveList}}
{{#fieldIsNonStructList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size);
inline {{fieldType}}::Builder get{{fieldTitleCase}}();
{{/fieldIsPrimitiveList}}
{{/fieldIsNonStructList}}
{{#fieldIsStructList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size);
inline {{fieldType}}::Builder get{{fieldTitleCase}}();
......@@ -160,7 +163,7 @@ inline {{fieldType}}::Builder {{structName}}::Builder::get{{fieldTitleCase}}() {
{{^fieldDefaultBytes}}{{fieldType}}::DEFAULT.words{{/fieldDefaultBytes}}));
}
{{/fieldIsStruct}}
{{#fieldIsPrimitiveList}}
{{#fieldIsNonStructList}}
inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}(unsigned int size) {
return {{fieldType}}::Builder(_builder.initListField(
{{fieldOffset}} * ::capnproto::REFERENCES,
......@@ -173,12 +176,12 @@ inline {{fieldType}}::Builder {{structName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
}
{{/fieldIsPrimitiveList}}
{{/fieldIsNonStructList}}
{{#fieldIsStructList}}
inline {{fieldType}}::Builder {{structName}}::Builder::init{{fieldTitleCase}}(unsigned int size) {
return {{fieldType}}::Builder(_builder.initStructListField(
{{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::ELEMENTS,
{{fieldType}}::DEFAULT.words));
{{fieldElementType}}::DEFAULT.words));
}
inline {{fieldType}}::Builder {{structName}}::Builder::get{{fieldTitleCase}}() {
return {{fieldType}}::Builder(_builder.getListField(
......
......@@ -32,6 +32,8 @@ namespace {{namespaceName}} {
{{/fileNamespaces}}
{{#fileStructs}}
constexpr ::capnproto::WordCount {{structName}}::DATA_SIZE;
constexpr ::capnproto::WireReferenceCount {{structName}}::REFERENCE_COUNT;
{{#structDefault}}
const ::capnproto::internal::AlignedData<{{defaultWordCount}}> {{structName}}::DEFAULT = {
{ {{defaultByteList}} }
......
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