Commit e4784bc8 authored by Kenton Varda's avatar Kenton Varda

Various refactoring and cleanup.

parent f017105e
......@@ -41,10 +41,10 @@ struct PointerHelpers {
return typename T::Reader(reader.getStructField(index, nullptr));
}
static inline typename T::Builder get(StructBuilder builder, WireReferenceCount index) {
return typename T::Builder(builder.getStructField(index, T::STRUCT_SIZE, nullptr));
return typename T::Builder(builder.getStructField(index, structSize<T>(), nullptr));
}
static inline typename T::Builder init(StructBuilder builder, WireReferenceCount index) {
return typename T::Builder(builder.initStructField(index, T::STRUCT_SIZE));
return typename T::Builder(builder.initStructField(index, structSize<T>()));
}
};
......@@ -65,36 +65,36 @@ struct PointerHelpers<List<T>> {
template <>
struct PointerHelpers<Text> {
static inline Text::Reader get(StructReader reader, WireReferenceCount index) {
return reader.getTextField(index, nullptr, 0 * BYTES);
return reader.getBlobField<Text>(index, nullptr, 0 * BYTES);
}
static inline Text::Builder get(StructBuilder builder, WireReferenceCount index) {
return builder.getTextField(index, nullptr, 0 * BYTES);
return builder.getBlobField<Text>(index, nullptr, 0 * BYTES);
}
static inline void set(StructBuilder builder, WireReferenceCount index, Text::Reader value) {
builder.setTextField(index, value);
builder.setBlobField<Text>(index, value);
}
static inline Text::Builder init(StructBuilder builder, WireReferenceCount index, int size) {
return builder.initTextField(index, size * BYTES);
return builder.initBlobField<Text>(index, size * BYTES);
}
};
template <>
struct PointerHelpers<Data> {
static inline Data::Reader get(StructReader reader, WireReferenceCount index) {
return reader.getDataField(index, nullptr, 0 * BYTES);
return reader.getBlobField<Data>(index, nullptr, 0 * BYTES);
}
static inline Data::Builder get(StructBuilder builder, WireReferenceCount index) {
return builder.getDataField(index, nullptr, 0 * BYTES);
return builder.getBlobField<Data>(index, nullptr, 0 * BYTES);
}
static inline void set(StructBuilder builder, WireReferenceCount index, Data::Reader value) {
builder.setDataField(index, value);
builder.setBlobField<Data>(index, value);
}
static inline Data::Builder init(StructBuilder builder, WireReferenceCount index, int size) {
return builder.initDataField(index, size * BYTES);
return builder.initBlobField<Data>(index, size * BYTES);
}
};
#ifdef CAPNPROTO_PRIVATE
#if defined(CAPNPROTO_PRIVATE) || defined(__CDT_PARSER__)
struct TrustedMessage {
typedef const word* Reader;
......@@ -116,4 +116,15 @@ struct PointerHelpers<TrustedMessage> {
} // namespace internal
} // namespace capnproto
#define CAPNPROTO_DECLARE_ENUM(type) \
template <> struct KindOf<type> { static constexpr Kind kind = Kind::ENUM; }
#define CAPNPROTO_DECLARE_STRUCT(type, dataWordSize, pointerCount, preferredElementEncoding) \
template <> struct KindOf<type> { static constexpr Kind kind = Kind::STRUCT; }; \
template <> struct StructSizeFor<type> { \
static constexpr StructSize value = StructSize( \
dataWordSize * WORDS, pointerCount * REFERENCES, FieldSize::preferredElementEncoding); \
}
#define CAPNPROTO_DECLARE_INTERFACE(type) \
template <> struct KindOf<type> { static constexpr Kind kind = Kind::INTERFACE; }
#endif // CAPNPROTO_GENERATED_HEADER_SUPPORT_H_
......@@ -1119,25 +1119,31 @@ ListBuilder StructBuilder::getListField(
references + refIndex, segment, defaultValue);
}
Text::Builder StructBuilder::initTextField(WireReferenceCount refIndex, ByteCount size) const {
template <>
Text::Builder StructBuilder::initBlobField<Text>(WireReferenceCount refIndex, ByteCount size) const {
return WireHelpers::initTextReference(references + refIndex, segment, size);
}
void StructBuilder::setTextField(WireReferenceCount refIndex, Text::Reader value) const {
template <>
void StructBuilder::setBlobField<Text>(WireReferenceCount refIndex, Text::Reader value) const {
WireHelpers::setTextReference(references + refIndex, segment, value);
}
Text::Builder StructBuilder::getTextField(
template <>
Text::Builder StructBuilder::getBlobField<Text>(
WireReferenceCount refIndex, const void* defaultValue, ByteCount defaultSize) const {
return WireHelpers::getWritableTextReference(
references + refIndex, segment, defaultValue, defaultSize);
}
Data::Builder StructBuilder::initDataField(WireReferenceCount refIndex, ByteCount size) const {
template <>
Data::Builder StructBuilder::initBlobField<Data>(WireReferenceCount refIndex, ByteCount size) const {
return WireHelpers::initDataReference(references + refIndex, segment, size);
}
void StructBuilder::setDataField(WireReferenceCount refIndex, Data::Reader value) const {
template <>
void StructBuilder::setBlobField<Data>(WireReferenceCount refIndex, Data::Reader value) const {
WireHelpers::setDataReference(references + refIndex, segment, value);
}
Data::Builder StructBuilder::getDataField(
template <>
Data::Builder StructBuilder::getBlobField<Data>(
WireReferenceCount refIndex, const void* defaultValue, ByteCount defaultSize) const {
return WireHelpers::getWritableDataReference(
references + refIndex, segment, defaultValue, defaultSize);
......@@ -1148,11 +1154,6 @@ ObjectBuilder StructBuilder::getObjectField(
return WireHelpers::getWritableObjectReference(segment, references + refIndex, defaultValue);
}
const word* StructBuilder::getTrustedPointer(WireReferenceCount refIndex) const {
PRECOND(segment == nullptr, "getTrustedPointer() only allowed on trusted messages.");
return reinterpret_cast<const word*>(references + refIndex);
}
StructReader StructBuilder::asReader() const {
return StructReader(segment, data, references,
dataSize, referenceCount, bit0Offset, std::numeric_limits<int>::max());
......@@ -1190,13 +1191,15 @@ ListReader StructReader::getListField(
segment, ref, defaultValue, expectedElementSize, nestingLimit);
}
Text::Reader StructReader::getTextField(
template <>
Text::Reader StructReader::getBlobField<Text>(
WireReferenceCount refIndex, const void* defaultValue, ByteCount defaultSize) const {
const WireReference* ref = refIndex >= referenceCount ? nullptr : references + refIndex;
return WireHelpers::readTextReference(segment, ref, defaultValue, defaultSize);
}
Data::Reader StructReader::getDataField(
template <>
Data::Reader StructReader::getBlobField<Data>(
WireReferenceCount refIndex, const void* defaultValue, ByteCount defaultSize) const {
const WireReference* ref = refIndex >= referenceCount ? nullptr : references + refIndex;
return WireHelpers::readDataReference(segment, ref, defaultValue, defaultSize);
......@@ -1208,6 +1211,11 @@ ObjectReader StructReader::getObjectField(
segment, references + refIndex, defaultValue, nestingLimit);
}
const word* StructReader::getTrustedPointer(WireReferenceCount refIndex) const {
PRECOND(segment == nullptr, "getTrustedPointer() only allowed on trusted messages.");
return reinterpret_cast<const word*>(references + refIndex);
}
// =======================================================================================
// ListBuilder
......@@ -1269,28 +1277,34 @@ ListBuilder ListBuilder::getListElement(ElementCount index) const {
reinterpret_cast<WireReference*>(ptr + index * step / BITS_PER_BYTE), segment, nullptr);
}
Text::Builder ListBuilder::initTextElement(ElementCount index, ByteCount size) const {
template <>
Text::Builder ListBuilder::initBlobElement<Text>(ElementCount index, ByteCount size) const {
return WireHelpers::initTextReference(
reinterpret_cast<WireReference*>(ptr + index * step / BITS_PER_BYTE), segment, size);
}
void ListBuilder::setTextElement(ElementCount index, Text::Reader value) const {
template <>
void ListBuilder::setBlobElement<Text>(ElementCount index, Text::Reader value) const {
WireHelpers::setTextReference(
reinterpret_cast<WireReference*>(ptr + index * step / BITS_PER_BYTE), segment, value);
}
Text::Builder ListBuilder::getTextElement(ElementCount index) const {
template <>
Text::Builder ListBuilder::getBlobElement<Text>(ElementCount index) const {
return WireHelpers::getWritableTextReference(
reinterpret_cast<WireReference*>(ptr + index * step / BITS_PER_BYTE), segment, "", 0 * BYTES);
}
Data::Builder ListBuilder::initDataElement(ElementCount index, ByteCount size) const {
template <>
Data::Builder ListBuilder::initBlobElement<Data>(ElementCount index, ByteCount size) const {
return WireHelpers::initDataReference(
reinterpret_cast<WireReference*>(ptr + index * step / BITS_PER_BYTE), segment, size);
}
void ListBuilder::setDataElement(ElementCount index, Data::Reader value) const {
template <>
void ListBuilder::setBlobElement<Data>(ElementCount index, Data::Reader value) const {
WireHelpers::setDataReference(
reinterpret_cast<WireReference*>(ptr + index * step / BITS_PER_BYTE), segment, value);
}
Data::Builder ListBuilder::getDataElement(ElementCount index) const {
template <>
Data::Builder ListBuilder::getBlobElement<Data>(ElementCount index) const {
return WireHelpers::getWritableDataReference(
reinterpret_cast<WireReference*>(ptr + index * step / BITS_PER_BYTE), segment, nullptr,
0 * BYTES);
......@@ -1375,13 +1389,15 @@ ListReader ListReader::getListElement(
nullptr, expectedElementSize, nestingLimit);
}
Text::Reader ListReader::getTextElement(ElementCount index) const {
template <>
Text::Reader ListReader::getBlobElement<Text>(ElementCount index) const {
return WireHelpers::readTextReference(
segment, checkAlignment(ptr + index * step / BITS_PER_BYTE),
"", 0 * BYTES);
}
Data::Reader ListReader::getDataElement(ElementCount index) const {
template <>
Data::Reader ListReader::getBlobElement<Data>(ElementCount index) const {
return WireHelpers::readDataReference(
segment, checkAlignment(ptr + index * step / BITS_PER_BYTE),
nullptr, 0 * BYTES);
......
......@@ -49,8 +49,7 @@ struct WireHelpers;
class SegmentReader;
class SegmentBuilder;
class FieldDescriptor;
typedef Id<uint8_t, FieldDescriptor> FieldNumber;
// =============================================================================
enum class FieldSize: uint8_t {
// TODO: Rename to FieldLayout or maybe ValueLayout.
......@@ -117,6 +116,48 @@ inline constexpr PointersPerElement pointersPerElement(FieldSize size) {
return size == FieldSize::REFERENCE ? 1 * REFERENCES / ELEMENTS : 0 * REFERENCES / ELEMENTS;
}
} // namespace internal
enum class Kind: uint8_t {
PRIMITIVE,
BLOB,
ENUM,
STRUCT,
INTERFACE,
LIST,
UNKNOWN
};
namespace internal {
template <typename T> struct KindOf { static constexpr Kind kind = Kind::UNKNOWN; };
template <> struct KindOf<Void> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<bool> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<int8_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<int16_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<int32_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<int64_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<uint8_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<uint16_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<uint32_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<uint64_t> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<float> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<double> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct KindOf<Text> { static constexpr Kind kind = Kind::BLOB; };
template <> struct KindOf<Data> { static constexpr Kind kind = Kind::BLOB; };
} // namespace internal
template <typename T>
inline constexpr Kind kind() {
return internal::KindOf<T>::kind;
}
// =============================================================================
namespace internal {
template <int wordCount>
union AlignedData {
// Useful for declaring static constant data blobs as an array of bytes, but forcing those
......@@ -143,39 +184,40 @@ struct StructSize {
: data(data), pointers(pointers), preferredListEncoding(preferredListEncoding) {}
};
template <typename T> struct StructSizeFor;
// Specialized for every struct type with member: static constexpr StructSize value"
template <typename T>
class IsEnum {
// Detects whether a primitive value is an enum.
inline constexpr StructSize structSize() {
return StructSizeFor<T>::value;
}
typedef char no;
typedef long yes;
// -------------------------------------------------------------------
// Masking of default values
static no test(int i);
static yes test(...);
template <typename T, Kind kind = kind<T>()> struct MaskType;
template <typename T> struct MaskType<T, Kind::PRIMITIVE> { typedef T Type; };
template <typename T> struct MaskType<T, Kind::ENUM> { typedef uint16_t Type; };
template <> struct MaskType<float, Kind::PRIMITIVE> { typedef uint32_t Type; };
template <> struct MaskType<double, Kind::PRIMITIVE> { typedef uint64_t Type; };
public:
static constexpr bool value = sizeof(test(T())) == sizeof(yes);
template <typename T> struct MaskType<T, Kind::UNKNOWN> {
// Union discriminants end up here.
static_assert(sizeof(T) == 2, "Don't know how to mask this type.");
typedef uint16_t Type;
};
// -------------------------------------------------------------------
// Masking of default values
template <typename T, bool isEnum = IsEnum<T>::value> struct MaskType { typedef T Type; };
template <typename T> struct MaskType<T, false> { typedef T Type; };
template <typename T> struct MaskType<T, true> { typedef uint16_t Type; };
template <> struct MaskType<float, false> { typedef uint32_t Type; };
template <> struct MaskType<double, false> { typedef uint64_t Type; };
template <typename T>
using Mask = typename MaskType<T>::Type;
template <typename T>
CAPNPROTO_ALWAYS_INLINE(
typename MaskType<T>::Type mask(T value, typename MaskType<T>::Type mask));
CAPNPROTO_ALWAYS_INLINE(Mask<T> mask(T value, Mask<T> mask));
template <typename T>
CAPNPROTO_ALWAYS_INLINE(
T unmask(typename MaskType<T>::Type value, typename MaskType<T>::Type mask));
CAPNPROTO_ALWAYS_INLINE(T unmask(Mask<T> value, Mask<T> mask));
template <typename T>
inline typename MaskType<T>::Type mask(T value, typename MaskType<T>::Type mask) {
return static_cast<typename MaskType<T>::Type>(value) ^ mask;
inline Mask<T> mask(T value, Mask<T> mask) {
return static_cast<Mask<T> >(value) ^ mask;
}
template <>
......@@ -195,7 +237,7 @@ inline uint64_t mask<double>(double value, uint64_t mask) {
}
template <typename T>
inline T unmask(typename MaskType<T>::Type value, typename MaskType<T>::Type mask) {
inline T unmask(Mask<T> value, Mask<T> mask) {
return static_cast<T>(value ^ mask);
}
......@@ -261,8 +303,7 @@ public:
// multiples of the field size, determined by the type.
template <typename T>
CAPNPROTO_ALWAYS_INLINE(T getDataField(
ElementCount offset, typename MaskType<T>::Type mask) const);
CAPNPROTO_ALWAYS_INLINE(T getDataField(ElementCount offset, Mask<T> mask) const);
// Like getDataField() but applies the given XOR mask to the data on load. Used for reading
// fields with non-zero default values.
......@@ -273,7 +314,7 @@ public:
template <typename T>
CAPNPROTO_ALWAYS_INLINE(void setDataField(
ElementCount offset, typename NoInfer<T>::Type value, typename MaskType<T>::Type mask) const);
ElementCount offset, typename NoInfer<T>::Type value, Mask<T> mask) const);
// Like setDataField() but applies the given XOR mask before storing. Used for writing fields
// with non-zero default values.
......@@ -304,31 +345,23 @@ public:
// already allocated, it is allocated as a deep copy of the given default value (a trusted
// message). If the default value is null, an empty list is used.
Text::Builder initTextField(WireReferenceCount refIndex, ByteCount size) const;
// Initialize the text field to the given size in bytes (not including NUL terminator) and return
// a Text::Builder which can be used to fill in the content.
void setTextField(WireReferenceCount refIndex, Text::Reader value) const;
// Set the text field to a copy of the given text.
template <typename T>
typename T::Builder initBlobField(WireReferenceCount refIndex, ByteCount size) const;
// Initialize a Text or Data field to the given size in bytes (not including NUL terminator for
// Text) and return a Text::Builder which can be used to fill in the content.
Text::Builder getTextField(WireReferenceCount refIndex,
const void* defaultValue, ByteCount defaultSize) const;
// Get the text field. If it is not initialized, initialize it to a copy of the given default.
template <typename T>
void setBlobField(WireReferenceCount refIndex, typename T::Reader value) const;
// Set the blob field to a copy of the given blob.
Data::Builder initDataField(WireReferenceCount refIndex, ByteCount size) const;
void setDataField(WireReferenceCount refIndex, Data::Reader value) const;
Data::Builder getDataField(WireReferenceCount refIndex,
const void* defaultValue, ByteCount defaultSize) const;
// Same as *Text*, but for data blobs.
template <typename T>
typename T::Builder getBlobField(WireReferenceCount refIndex,
const void* defaultValue, ByteCount defaultSize) const;
// Get the blob field. If it is not initialized, initialize it to a copy of the given default.
ObjectBuilder getObjectField(WireReferenceCount refIndex, const word* defaultValue) const;
// Read a pointer of arbitrary type.
const word* getTrustedPointer(WireReferenceCount refIndex) const;
// If this is a trusted message, get a word* pointing at the location of the pointer. This
// word* can actually be passed to readTrusted() to read the designated sub-object later. If
// this isn't a trusted message, throws an exception.
StructReader asReader() const;
// Gets a StructReader pointing at the same memory.
......@@ -378,7 +411,7 @@ public:
template <typename T>
CAPNPROTO_ALWAYS_INLINE(
T getDataField(ElementCount offset, typename MaskType<T>::Type mask) const);
T getDataField(ElementCount offset, Mask<T> mask) const);
// Like getDataField(offset), but applies the given XOR mask to the result. Used for reading
// fields with non-zero default values.
......@@ -393,18 +426,18 @@ public:
// Get the list field at the given index in the reference segment, or the default value if not
// initialized. The default value is allowed to be null, in which case an empty list is used.
Text::Reader getTextField(WireReferenceCount refIndex,
const void* defaultValue, ByteCount defaultSize) const;
// Gets the text field, or the given default value if not initialized.
Data::Reader getDataField(WireReferenceCount refIndex,
const void* defaultValue, ByteCount defaultSize) const;
// Gets the data field, or the given default value if not initialized.
template <typename T>
typename T::Reader getBlobField(WireReferenceCount refIndex,
const void* defaultValue, ByteCount defaultSize) const;
// Gets the text or data field, or the given default value if not initialized.
ObjectReader getObjectField(WireReferenceCount refIndex, const word* defaultValue) const;
// Read a pointer of arbitrary type.
WireReferenceCount getReferenceCount() { return referenceCount; }
const word* getTrustedPointer(WireReferenceCount refIndex) const;
// If this is a trusted message, get a word* pointing at the location of the pointer. This
// word* can actually be passed to readTrusted() to read the designated sub-object later. If
// this isn't a trusted message, throws an exception.
private:
SegmentReader* segment; // Memory segment in which the struct resides.
......@@ -486,20 +519,18 @@ public:
// Get the existing list element at the given index. Returns an empty list if the element is
// not initialized.
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.
void setTextElement(ElementCount index, Text::Reader value) const;
// Set the text element to a copy of the given text.
template <typename T>
typename T::Builder initBlobElement(ElementCount index, ByteCount size) const;
// Initialize a Text or Data element to the given size in bytes (not including NUL terminator for
// Text) and return a Text::Builder which can be used to fill in the content.
Text::Builder getTextElement(ElementCount index) const;
// Get the text element. If it is not initialized, returns an empty Text::Builder.
template <typename T>
void setBlobElement(ElementCount index, typename T::Reader value) const;
// Set the blob element to a copy of the given blob.
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.
template <typename T>
typename T::Builder getBlobElement(ElementCount index) const;
// Get the blob element. If it is not initialized, return an empty blob builder.
ObjectBuilder getObjectElement(ElementCount index, const word* defaultValue) const;
// Gets a pointer element of arbitrary type.
......@@ -556,11 +587,9 @@ public:
ListReader getListElement(ElementCount index, FieldSize expectedElementSize) const;
// Get the list element at the given index.
Text::Reader getTextElement(ElementCount index) const;
// Get the text element. If it is not initialized, returns an empty Text::Reader.
Data::Reader getDataElement(ElementCount index) const;
// Get the data element. If it is not initialized, returns an empty Data::Reader.
template <typename T>
typename T::Reader getBlobElement(ElementCount index) const;
// Gets the text or data field. If it is not initialized, returns an empty blob reader.
ObjectReader getObjectElement(ElementCount index, const word* defaultValue) const;
// Gets a pointer element of arbitrary type.
......@@ -666,8 +695,8 @@ inline Void StructBuilder::getDataField<Void>(ElementCount offset) const {
}
template <typename T>
inline T StructBuilder::getDataField(ElementCount offset, typename MaskType<T>::Type mask) const {
return unmask<T>(getDataField<typename MaskType<T>::Type>(offset), mask);
inline T StructBuilder::getDataField(ElementCount offset, Mask<T> mask) const {
return unmask<T>(getDataField<Mask<T> >(offset), mask);
}
template <typename T>
......@@ -692,8 +721,8 @@ inline void StructBuilder::setDataField<Void>(ElementCount offset, Void value) c
template <typename T>
inline void StructBuilder::setDataField(
ElementCount offset, typename NoInfer<T>::Type value, typename MaskType<T>::Type m) const {
setDataField<typename MaskType<T>::Type>(offset, mask<T>(value, m));
ElementCount offset, typename NoInfer<T>::Type value, Mask<T> m) const {
setDataField<Mask<T> >(offset, mask<T>(value, m));
}
// -------------------------------------------------------------------
......@@ -732,8 +761,8 @@ inline Void StructReader::getDataField<Void>(ElementCount offset) const {
}
template <typename T>
T StructReader::getDataField(ElementCount offset, typename MaskType<T>::Type mask) const {
return unmask<T>(getDataField<typename MaskType<T>::Type>(offset), mask);
T StructReader::getDataField(ElementCount offset, Mask<T> mask) const {
return unmask<T>(getDataField<Mask<T> >(offset), mask);
}
// -------------------------------------------------------------------
......@@ -805,6 +834,25 @@ inline Void ListReader::getDataElement<Void>(ElementCount index) const {
return Void::VOID;
}
// These are defined in the source file.
template <> typename Text::Builder StructBuilder::initBlobField<Text>(WireReferenceCount refIndex, ByteCount size) const;
template <> void StructBuilder::setBlobField<Text>(WireReferenceCount refIndex, typename Text::Reader value) const;
template <> typename Text::Builder StructBuilder::getBlobField<Text>(WireReferenceCount refIndex, const void* defaultValue, ByteCount defaultSize) const;
template <> typename Text::Reader StructReader::getBlobField<Text>(WireReferenceCount refIndex, const void* defaultValue, ByteCount defaultSize) const;
template <> typename Text::Builder ListBuilder::initBlobElement<Text>(ElementCount index, ByteCount size) const;
template <> void ListBuilder::setBlobElement<Text>(ElementCount index, typename Text::Reader value) const;
template <> typename Text::Builder ListBuilder::getBlobElement<Text>(ElementCount index) const;
template <> typename Text::Reader ListReader::getBlobElement<Text>(ElementCount index) const;
template <> typename Data::Builder StructBuilder::initBlobField<Data>(WireReferenceCount refIndex, ByteCount size) const;
template <> void StructBuilder::setBlobField<Data>(WireReferenceCount refIndex, typename Data::Reader value) const;
template <> typename Data::Builder StructBuilder::getBlobField<Data>(WireReferenceCount refIndex, const void* defaultValue, ByteCount defaultSize) const;
template <> typename Data::Reader StructReader::getBlobField<Data>(WireReferenceCount refIndex, const void* defaultValue, ByteCount defaultSize) const;
template <> typename Data::Builder ListBuilder::initBlobElement<Data>(ElementCount index, ByteCount size) const;
template <> void ListBuilder::setBlobElement<Data>(ElementCount index, typename Data::Reader value) const;
template <> typename Data::Builder ListBuilder::getBlobElement<Data>(ElementCount index) const;
template <> typename Data::Reader ListReader::getBlobElement<Data>(ElementCount index) const;
} // namespace internal
} // namespace capnproto
......
......@@ -28,43 +28,25 @@
#include <initializer_list>
namespace capnproto {
namespace internal {
template <typename T>
class IsPrimitive {
typedef char no;
typedef long yes;
template <typename U> static no test(typename U::Reader*);
template <typename U> static yes test(...);
public:
static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
template <typename T, Kind kind = kind<T>()>
struct MaybeReaderBuilder {
typedef typename T::Reader Reader;
typedef typename T::Builder Builder;
};
template <typename T>
constexpr bool isPrimitive() { return IsPrimitive<T>::value; }
template <typename T, bool isPrimitive = isPrimitive<T>()>
struct MaybeReaderBuilder {};
template <typename T>
struct MaybeReaderBuilder<T, true> {
struct MaybeReaderBuilder<T, Kind::PRIMITIVE> {
typedef T Reader;
typedef T Builder;
};
template <typename T>
struct MaybeReaderBuilder<T, false> {
typedef typename T::Reader Reader;
typedef typename T::Builder Builder;
};
template <typename t>
struct PointerHelpers;
} // namespace internal
template <typename T, bool isPrimitive = internal::isPrimitive<T>()>
template <typename T, Kind kind = kind<T>()>
struct List;
template <typename T>
......@@ -77,6 +59,8 @@ using BuilderFor = typename internal::MaybeReaderBuilder<T>::Builder;
namespace internal {
template <typename T, Kind k> struct KindOf<List<T, k>> { static constexpr Kind kind = Kind::LIST; };
template <size_t size> struct FieldSizeForByteSize;
template <> struct FieldSizeForByteSize<1> { static constexpr FieldSize value = FieldSize::BYTE; };
template <> struct FieldSizeForByteSize<2> { static constexpr FieldSize value = FieldSize::TWO_BYTES; };
......@@ -84,12 +68,14 @@ template <> struct FieldSizeForByteSize<4> { static constexpr FieldSize value =
template <> struct FieldSizeForByteSize<8> { static constexpr FieldSize value = FieldSize::EIGHT_BYTES; };
template <typename T> struct FieldSizeForType {
static constexpr FieldSize value = isPrimitive<T>() ?
static constexpr FieldSize value =
// Primitive types that aren't special-cased below can be determined from sizeof().
FieldSizeForByteSize<sizeof(T)>::value :
kind<T>() == Kind::PRIMITIVE ? FieldSizeForByteSize<sizeof(T)>::value :
kind<T>() == Kind::ENUM ? FieldSize::TWO_BYTES :
kind<T>() == Kind::STRUCT ? FieldSize::INLINE_COMPOSITE :
// Non-primitive types that aren't special-cased below are presumed to be structs.
FieldSize::INLINE_COMPOSITE;
// Everything else is a pointer.
FieldSize::REFERENCE;
};
// Void and bool are special.
......@@ -172,7 +158,7 @@ private:
} // namespace internal
template <typename T>
struct List<T, true> {
struct List<T, Kind::PRIMITIVE> {
// List of primitives.
class Reader {
......@@ -265,14 +251,17 @@ private:
return reader.getListField(index, internal::FieldSizeForType<T>::value, nullptr);
}
template <typename U, bool b>
template <typename U, Kind k>
friend class List;
template <typename U>
friend struct internal::PointerHelpers;
};
template <typename T>
struct List<T, false> {
struct List<T, Kind::ENUM>: public List<T, Kind::PRIMITIVE> {};
template <typename T>
struct List<T, Kind::STRUCT> {
// List of structs.
class Reader {
......@@ -300,7 +289,8 @@ struct List<T, false> {
inline uint size() { return builder.size() / ELEMENTS; }
inline typename T::Builder operator[](uint index) {
return typename T::Builder(builder.getStructElement(index * ELEMENTS, T::STRUCT_SIZE));
return typename T::Builder(builder.getStructElement(
index * ELEMENTS, internal::structSize<T>()));
}
typedef internal::IndexingIterator<Builder, typename T::Builder> iterator;
......@@ -320,7 +310,7 @@ private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initStructListElement(
index * ELEMENTS, size * ELEMENTS, T::STRUCT_SIZE);
index * ELEMENTS, size * ELEMENTS, internal::structSize<T>());
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
......@@ -333,7 +323,7 @@ private:
inline static internal::ListBuilder initAsFieldOf(
internal::StructBuilder& builder, WireReferenceCount index, uint size) {
return builder.initStructListField(index, size * ELEMENTS, T::STRUCT_SIZE);
return builder.initStructListField(index, size * ELEMENTS, internal::structSize<T>());
}
inline static internal::ListBuilder getAsFieldOf(
internal::StructBuilder& builder, WireReferenceCount index) {
......@@ -344,14 +334,14 @@ private:
return reader.getListField(index, internal::FieldSize::INLINE_COMPOSITE, nullptr);
}
template <typename U, bool b>
template <typename U, Kind k>
friend class List;
template <typename U>
friend struct internal::PointerHelpers;
};
template <typename T>
struct List<List<T>, false> {
struct List<List<T>, Kind::LIST> {
// List of lists.
class Reader {
......@@ -426,122 +416,25 @@ private:
return reader.getListField(index, internal::FieldSize::REFERENCE, nullptr);
}
template <typename U, bool b>
template <typename U, Kind k>
friend class List;
template <typename U>
friend struct internal::PointerHelpers;
};
template <>
struct List<Data, false> {
class Reader {
public:
Reader() = default;
inline explicit Reader(internal::ListReader reader): reader(reader) {}
inline uint size() { return reader.size() / ELEMENTS; }
inline Data::Reader operator[](uint index) {
return reader.getDataElement(index * ELEMENTS);
}
typedef internal::IndexingIterator<Reader, Data::Reader> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
private:
internal::ListReader reader;
};
class Builder {
public:
Builder() = default;
inline explicit Builder(internal::ListBuilder builder): builder(builder) {}
inline uint size() { return builder.size() / ELEMENTS; }
inline Data::Builder operator[](uint index) {
return builder.getDataElement(index * ELEMENTS);
}
inline void set(uint index, Data::Reader value) {
builder.setDataElement(index * ELEMENTS, value);
}
inline Data::Builder init(uint index, uint size) {
return builder.initDataElement(index * ELEMENTS, size * BYTES);
}
typedef internal::IndexingIterator<Builder, 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:
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);
}
inline static internal::ListBuilder initAsFieldOf(
internal::StructBuilder& builder, WireReferenceCount index, uint size) {
return builder.initListField(index, internal::FieldSize::REFERENCE, size * ELEMENTS);
}
inline static internal::ListBuilder getAsFieldOf(
internal::StructBuilder& builder, WireReferenceCount index) {
return builder.getListField(index, nullptr);
}
inline static internal::ListReader getAsFieldOf(
internal::StructReader& reader, WireReferenceCount index) {
return reader.getListField(index, internal::FieldSize::REFERENCE, nullptr);
}
template <typename U, bool b>
friend class List;
template <typename U>
friend struct internal::PointerHelpers;
};
template <>
struct List<Text, false> {
template <typename T>
struct List<T, Kind::BLOB> {
class Reader {
public:
Reader() = default;
inline explicit Reader(internal::ListReader reader): reader(reader) {}
inline uint size() { return reader.size() / ELEMENTS; }
inline Text::Reader operator[](uint index) {
return reader.getTextElement(index * ELEMENTS);
inline typename T::Reader operator[](uint index) {
return reader.getBlobElement<T>(index * ELEMENTS);
}
typedef internal::IndexingIterator<Reader, Text::Reader> iterator;
typedef internal::IndexingIterator<Reader, typename T::Reader> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
......@@ -555,17 +448,17 @@ struct List<Text, false> {
inline explicit Builder(internal::ListBuilder builder): builder(builder) {}
inline uint size() { return builder.size() / ELEMENTS; }
inline Text::Builder operator[](uint index) {
return builder.getTextElement(index * ELEMENTS);
inline typename T::Builder operator[](uint index) {
return builder.getBlobElement<T>(index * ELEMENTS);
}
inline void set(uint index, Text::Reader value) {
builder.setTextElement(index * ELEMENTS, value);
inline void set(uint index, typename T::Reader value) {
builder.setBlobElement<T>(index * ELEMENTS, value);
}
inline Text::Builder init(uint index, uint size) {
return builder.initTextElement(index * ELEMENTS, size * BYTES);
inline typename T::Builder init(uint index, uint size) {
return builder.initBlobElement<T>(index * ELEMENTS, size * BYTES);
}
typedef internal::IndexingIterator<Builder, Text::Builder> iterator;
typedef internal::IndexingIterator<Builder, typename T::Builder> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
......@@ -580,7 +473,7 @@ struct List<Text, false> {
CAPNPROTO_INLINE_DPRECOND(pos == size() && i == end,
"List::copyFrom() argument had different size.");
}
void copyFrom(std::initializer_list<Text::Reader> other) {
void copyFrom(std::initializer_list<typename T::Reader> other) {
CAPNPROTO_INLINE_DPRECOND(other.size() == size(),
"List::copyFrom() argument had different size.");
for (uint i = 0; i < other.size(); i++) {
......@@ -620,7 +513,7 @@ private:
return reader.getListField(index, internal::FieldSize::REFERENCE, nullptr);
}
template <typename U, bool b>
template <typename U, Kind k>
friend class List;
template <typename U>
friend struct internal::PointerHelpers;
......
......@@ -275,12 +275,12 @@ inline typename RootType::Reader MessageReader::getRoot() {
template <typename RootType>
inline typename RootType::Builder MessageBuilder::initRoot() {
return typename RootType::Builder(initRoot(RootType::STRUCT_SIZE));
return typename RootType::Builder(initRoot(internal::structSize<RootType>()));
}
template <typename RootType>
inline typename RootType::Builder MessageBuilder::getRoot() {
return typename RootType::Builder(getRoot(RootType::STRUCT_SIZE));
return typename RootType::Builder(getRoot(internal::structSize<RootType>()));
}
template <typename RootType>
......
......@@ -81,7 +81,7 @@ T instance() noexcept;
// definition. So...
namespace internal {
struct PlacementNew {} placementNew;
struct PlacementNew {};
} // namespace internal;
} // namespace capnproto
......@@ -93,7 +93,7 @@ namespace capnproto {
template <typename T, typename... Params>
void constructAt(T* location, Params&&... params) {
new (internal::placementNew, location) T(capnproto::forward<Params>(params)...);
new (internal::PlacementNew(), location) T(capnproto::forward<Params>(params)...);
}
// =======================================================================================
......
......@@ -66,13 +66,6 @@ struct {{typeFullName}} {
{{/enumerants}}
};
{{/structNestedEnums}}
static constexpr ::capnproto::internal::StructSize STRUCT_SIZE =
::capnproto::internal::StructSize(
{{structDataSize}} * ::capnproto::WORDS,
{{structReferenceCount}} * ::capnproto::REFERENCES,
::capnproto::internal::FieldSize::{{structPreferredListEncoding}});
{{/typeStruct}}
{{#typeUnion}}
......@@ -81,8 +74,8 @@ struct {{typeFullName}} {
{{fieldUpperCase}} = {{fieldUnionDiscriminant}},
{{/unionFields}}
};
{{/typeUnion}}
{{#typeFields}}
{{#fieldDefaultBytes}}
static const ::capnproto::internal::AlignedData<{{defaultWordCount}}> DEFAULT_{{fieldUpperCase}};
......@@ -100,6 +93,36 @@ enum class {{enumName}}: uint16_t {
{{/enumerants}}
};
{{/fileEnums}}
{{! =========================================================================================== }}
{{#fileNamespaces}}
} // namespace
{{/fileNamespaces}}
namespace capnproto {
namespace internal {
{{#fileTypes}}
{{#typeStructOrUnion}}
{{#typeStruct}}
CAPNPROTO_DECLARE_STRUCT(
::{{#fileNamespaces}}{{namespaceName}}::{{/fileNamespaces}}{{typeFullName}},
{{structDataSize}}, {{structReferenceCount}}, {{structPreferredListEncoding}});
{{#structNestedEnums}}
CAPNPROTO_DECLARE_ENUM(::{{#fileNamespaces}}{{namespaceName}}::{{/fileNamespaces}}{{typeFullName}}::{{enumName}});
{{/structNestedEnums}}
{{/typeStruct}}
{{/typeStructOrUnion}}
{{/fileTypes}}
{{#fileEnums}}
CAPNPROTO_DECLARE_ENUM(::{{#fileNamespaces}}{{namespaceName}}::{{/fileNamespaces}}{{enumName}});
{{/fileEnums}}
} // namespace capnproto
} // namespace internal
{{#fileNamespaces}}
namespace {{namespaceName}} {
{{/fileNamespaces}}
{{! =========================================================================================== }}
{{#fileTypes}}
{{#typeStructOrUnion}}
......@@ -271,7 +294,7 @@ inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return _reader.getInline{{fieldBlobType}}Field(
return _reader.getInlineBlobField<{{fieldType}}>(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
......@@ -281,7 +304,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return _builder.getInline{{fieldBlobType}}Field(
return _builder.getInlineBlobField<{{fieldType}}>(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
......@@ -290,7 +313,7 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}({{fieldType}}::Read
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
_builder.setInline{{fieldBlobType}}Field(
_builder.setInlineBlobField<{{fieldType}}>(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES,
value);
......@@ -300,7 +323,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return _builder.initInline{{fieldBlobType}}Field(
return _builder.initInlineBlobField<{{fieldType}}>(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
......@@ -311,7 +334,7 @@ inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return _reader.get{{fieldBlobType}}Field(
return _reader.getBlobField<{{fieldType}}>(
{{fieldOffset}} * ::capnproto::REFERENCES,
{{#fieldDefaultBytes}}
DEFAULT_{{fieldUpperCase}}.words, {{defaultBlobSize}} * ::capnproto::BYTES
......@@ -324,7 +347,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return _builder.get{{fieldBlobType}}Field({{fieldOffset}} * ::capnproto::REFERENCES,
return _builder.getBlobField<{{fieldType}}>({{fieldOffset}} * ::capnproto::REFERENCES,
{{#fieldDefaultBytes}}
DEFAULT_{{fieldUpperCase}}.words, {{defaultBlobSize}} * ::capnproto::BYTES
{{/fieldDefaultBytes}}
......@@ -335,14 +358,14 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}({{fieldType}}::Read
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
_builder.set{{fieldBlobType}}Field({{fieldOffset}} * ::capnproto::REFERENCES, value);
_builder.setBlobField<{{fieldType}}>({{fieldOffset}} * ::capnproto::REFERENCES, value);
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(unsigned int size) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return _builder.init{{fieldBlobType}}Field(
return _builder.initBlobField<{{fieldType}}>(
{{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::BYTES);
}
{{/fieldIsInlineBlob}}
......@@ -367,7 +390,8 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initStructField(
{{fieldOffset}} * ::capnproto::REFERENCES, {{fieldType}}::STRUCT_SIZE));
{{fieldOffset}} * ::capnproto::REFERENCES,
::capnproto::internal::structSize<{{fieldType}}>()));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
......@@ -375,7 +399,8 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.getStructField(
{{fieldOffset}} * ::capnproto::REFERENCES, {{fieldType}}::STRUCT_SIZE,
{{fieldOffset}} * ::capnproto::REFERENCES,
::capnproto::internal::structSize<{{fieldType}}>(),
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
}
......@@ -486,7 +511,7 @@ inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
::capnproto::internal::structSize<{{fieldInlineElementType}}>()));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
......@@ -498,7 +523,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
::capnproto::internal::structSize<{{fieldInlineElementType}}>()));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
......@@ -509,7 +534,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
::capnproto::internal::structSize<{{fieldInlineElementType}}>()));
}
{{/fieldIsStructList}}
{{/fieldIsInlineList}}
......@@ -557,7 +582,7 @@ inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Reader(_reader.get{{fieldBlobType}}Field(
return {{fieldType}}::Reader(_reader.getBlobField<{{fieldType}}>(
{{fieldOffset}} * ::capnproto::REFERENCES, nullptr, 0 * ::capnproto::BYTES));
}
......@@ -566,7 +591,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.init{{fieldBlobType}}Field(
return {{fieldType}}::Builder(_builder.initBlobField<{{fieldType}}>(
{{fieldOffset}} * ::capnproto::REFERENCES,
size{{fieldInlineMultiplier}} * ::capnproto::BYTES));
}
......@@ -575,7 +600,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.get{{fieldBlobType}}Field(
return {{fieldType}}::Builder(_builder.getBlobField<{{fieldType}}>(
{{fieldOffset}} * ::capnproto::REFERENCES, nullptr, 0 * ::capnproto::BYTES));
}
{{/fieldIsInlineBlobList}}
......@@ -600,7 +625,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
return {{fieldType}}::Builder(_builder.initStructListField(
{{fieldOffset}} * ::capnproto::REFERENCES,
size{{fieldInlineMultiplier}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
::capnproto::internal::structSize<{{fieldInlineElementType}}>()));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
......
......@@ -34,8 +34,6 @@ namespace {{namespaceName}} {
{{#fileTypes}}
{{#typeStructOrUnion}}
{{#typeStruct}}
constexpr ::capnproto::internal::StructSize {{structFullName}}::STRUCT_SIZE;
{{#structFields}}
{{#fieldDefaultBytes}}
const ::capnproto::internal::AlignedData<{{defaultWordCount}}>
......
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