Commit e4784bc8 authored by Kenton Varda's avatar Kenton Varda

Various refactoring and cleanup.

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