blob: 976156441fccdce275ce944c178164af29c2beba [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package templates
const Union = `
{{- define "UnionForwardDeclaration" }}
class {{ .Name }};
{{- end }}
{{- define "UnionDeclaration" }}
{{range .DocComments}}
//{{ . }}
{{- end}}
class {{ .Name }} {
public:
{{ .Name }}();
~{{ .Name }}();
{{ .Name }}({{ .Name }}&&);
{{ .Name }}& operator=({{ .Name }}&&);
enum class Tag : fidl_union_tag_t {
{{- range $index, $member := .Members }}
{{ .TagName }} = {{ $index }},
{{- end }}
Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
};
static inline ::std::unique_ptr<{{ .Name }}> New() { return ::std::make_unique<{{ .Name }}>(); }
void Encode(::fidl::Encoder* encoder, size_t offset);
static void Decode(::fidl::Decoder* decoder, {{ .Name }}* value, size_t offset);
zx_status_t Clone({{ .Name }}* result) const;
bool has_invalid_tag() const { return Which() == Tag::Invalid; }
{{- range $index, $member := .Members }}
bool is_{{ .Name }}() const { return Which() == Tag({{ $index }}); }
{{range .DocComments}}
//{{ . }}
{{- end}}
{{ .Type.Decl }}& {{ .Name }}() {
if (!is_{{ .Name }}()) {
value_.emplace<{{ $index }} + 1>();
}
return value_.template get<{{ $index }} + 1>();
}
{{range .DocComments}}
//{{ . }}
{{- end}}
const {{ .Type.Decl }}& {{ .Name }}() const { return value_.template get<{{ $index }} + 1>(); }
void set_{{ .Name }}({{ .Type.Decl }} value);
{{- end }}
Tag Which() const {
size_t index = value_.index();
if (index == 0) {
return Tag::Invalid;
} else {
return Tag(index - 1);
}
}
private:
friend bool operator==(const {{ .Name }}& lhs, const {{ .Name }}& rhs);
using Variant = fit::internal::variant<fit::internal::monostate
{{- range .Members -}}
, {{ .Type.Decl -}}
{{- end -}}
>;
Variant value_;
};
bool operator==(const {{ .Name }}& lhs, const {{ .Name }}& rhs);
inline bool operator!=(const {{ .Name }}& lhs, const {{ .Name }}& rhs) {
return !(lhs == rhs);
}
inline zx_status_t Clone(const {{ .Namespace }}::{{ .Name }}& value,
{{ .Namespace }}::{{ .Name }}* result) {
return value.Clone(result);
}
using {{ .Name }}Ptr = ::std::unique_ptr<{{ .Name }}>;
{{- end }}
{{- define "UnionDefinition" }}
{{ .Name }}::{{ .Name }}() : value_() {}
{{ .Name }}::~{{ .Name }}() {
}
{{ .Name }}::{{ .Name }}({{ .Name }}&& other) : value_(std::move(other.value_)) {
}
{{ .Name }}& {{ .Name }}::operator=({{ .Name }}&& other) {
if (this != &other) {
value_ = std::move(other.value_);
}
return *this;
}
void {{ .Name }}::Encode(::fidl::Encoder* encoder, size_t offset) {
fidl_union_tag_t tag = static_cast<fidl_union_tag_t>(Which());
::fidl::Encode(encoder, &tag, offset);
switch (tag) {
{{- range $index, $member := .Members }}
case {{ $index }}:
::fidl::Encode(encoder, &{{ .Name }}(), offset + {{ .Offset }});
break;
{{- end }}
default:
break;
}
}
void {{ .Name }}::Decode(::fidl::Decoder* decoder, {{ .Name }}* value, size_t offset) {
fidl_union_tag_t tag;
::fidl::Decode(decoder, &tag, offset);
switch (tag) {
{{- range $index, $member := .Members }}
case {{ $index }}:
{
{{ .Type.Decl }} member{};
::fidl::Decode(decoder, &member, offset + {{ .Offset }});
value->set_{{ .Name }}(std::move(member));
break;
}
{{- end }}
default:
value->value_.emplace<0>();
}
}
zx_status_t {{ .Name }}::Clone({{ .Name }}* result) const {
zx_status_t status = ZX_OK;
switch (Which()) {
{{- range $index, $member := .Members }}
case Tag::{{ .TagName }}:
{
{{ .Type.Decl }} member{};
status = ::fidl::Clone({{ .Name }}(), &member);
if (status == ZX_OK) {
result->set_{{ .Name }}(std::move(member));
}
}
break;
{{- end }}
case Tag::Invalid:
result->value_.emplace<0>();
break;
}
return status;
}
bool operator==(const {{ .Name }}& lhs, const {{ .Name }}& rhs) {
if (lhs.Which() != rhs.Which()) {
return false;
}
switch (lhs.Which()) {
{{- range $index, $member := .Members }}
case {{ $.Name }}::Tag::{{ .TagName }}:
return ::fidl::Equals(lhs.{{ .Name }}(), rhs.{{ .Name }}());
{{- end }}
case {{ .Name }}::Tag::Invalid:
return true;
default:
return false;
}
}
{{- range $index, $member := .Members }}
void {{ $.Name }}::set_{{ .Name }}({{ .Type.Decl }} value) {
value_.emplace<static_cast<size_t>(Tag::{{ .TagName }}) + 1>(std::move(value));
}
{{- end }}
{{- end }}
{{- define "UnionTraits" }}
template <>
struct CodingTraits<{{ .Namespace }}::{{ .Name }}>
: public EncodableCodingTraits<{{ .Namespace }}::{{ .Name }}, {{ .Size }}> {};
inline zx_status_t Clone(const {{ .Namespace }}::{{ .Name }}& value,
{{ .Namespace }}::{{ .Name }}* result) {
return {{ .Namespace }}::Clone(value, result);
}
{{- end }}
`