{%- set class_name = union.name ~ "_Data" -%} {%- set enum_name = union.name ~ "_Tag" -%} {%- import "struct_macros.tmpl" as struct_macros %} class {{export_attribute}} {{class_name}} { public: // Used to identify Mojom Union Data Classes. typedef void MojomUnionDataType; {{class_name}}() {} // Do nothing in the destructor since it won't be called when it is a // non-inlined union. ~{{class_name}}() {} class BufferWriter { public: BufferWriter() = default; void Allocate(mojo::internal::Buffer* serialization_buffer) { serialization_buffer_ = serialization_buffer; index_ = serialization_buffer_->Allocate(sizeof({{class_name}})); new (data()) {{class_name}}(); } void AllocateInline(mojo::internal::Buffer* serialization_buffer, void* ptr) { const char* start = static_cast( serialization_buffer->data()); const char* slot = static_cast(ptr); DCHECK_GT(slot, start); serialization_buffer_ = serialization_buffer; index_ = slot - start; new (data()) {{class_name}}(); } bool is_null() const { return !serialization_buffer_; } {{class_name}}* data() { DCHECK(!is_null()); return serialization_buffer_->Get<{{class_name}}>(index_); } {{class_name}}* operator->() { return data(); } private: mojo::internal::Buffer* serialization_buffer_ = nullptr; size_t index_ = 0; }; static bool Validate(const void* data, mojo::internal::ValidationContext* validation_context, bool inlined); bool is_null() const { return size == 0; } void set_null() { size = 0U; tag = static_cast<{{enum_name}}>(0); data.unknown = 0U; } enum class {{enum_name}} : uint32_t { {% for field in union.fields %} {{field.name|upper}}, {%- endfor %} }; // A note on layout: // "Each non-static data member is allocated as if it were the sole member of // a struct." - Section 9.5.2 ISO/IEC 14882:2011 (The C++ Spec) union MOJO_ALIGNAS(8) Union_ { Union_() : unknown(0) {} {%- for field in union.fields %} {%- if field.kind.spec == 'b' %} uint8_t f_{{field.name}} : 1; {%- else %} {{field.kind|cpp_union_field_type}} f_{{field.name}}; {%- endif %} {%- endfor %} uint64_t unknown; }; uint32_t size; {{enum_name}} tag; Union_ data; }; static_assert(sizeof({{class_name}}) == mojo::internal::kUnionDataSize, "Bad sizeof({{class_name}})");