| {{/* |
| // Copyright 2021 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. |
| */}} |
| |
| {{- define "Union:ForwardDeclaration:NaturalTypesHeader" }} |
| {{ EnsureNamespace . }} |
| |
| class {{ .Name }}; |
| {{- end }} |
| |
| {{- define "Union:NaturalTypesHeader" }} |
| {{ EnsureNamespace . }} |
| {{ if .IsResourceType }} |
| {{- IfdefFuchsia -}} |
| {{- end }} |
| extern "C" const fidl_type_t {{ .CodingTableType.Name }}; |
| |
| {{ .Docs }} |
| class {{ .Name }} { |
| private: |
| using Storage_ = |
| std::variant< |
| std::monostate |
| {{- range .Members }} |
| , {{ .Type }} |
| {{- end -}} |
| >; |
| |
| public: |
| // TODO: share union tag types between wire & natural. |
| enum class {{ .TagEnum.Self }} : fidl_union_tag_t { |
| {{- range .Members }} |
| {{ .TagName.Self }} = {{ .Ordinal }}, // {{ .Ordinal | printf "%#x" }} |
| {{- end }} |
| {{- if .IsFlexible }} |
| {{ .TagUnknown.Self }} = ::std::numeric_limits<::fidl_union_tag_t>::max(), |
| {{- end }} |
| }; |
| |
| {{- if .IsFlexible }} |
| // Create an unknown value of this union. |
| {{ .Name }}() : storage_(std::make_shared<Storage_>()) {} |
| {{- end }} |
| |
| {{ .Name }}({{ .Name }}&& other) noexcept |
| : {{ .Name }}(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) { |
| *storage_ = std::move(*other.storage_); |
| } |
| {{ .Name }}& operator=({{ .Name }}&& other) noexcept { |
| if (this != &other) { |
| *storage_ = std::move(*other.storage_); |
| } |
| return *this; |
| } |
| {{- if not .IsResourceType }} |
| {{ .Name }}(const {{ .Name }}& other) noexcept : {{ .Name }}(other.CloneStorage_()){} |
| {{ .Name }}& operator=(const {{ .Name }}& other) noexcept { |
| if (this != &other) { |
| storage_ = other.CloneStorage_(); |
| } |
| return *this; |
| } |
| |
| bool operator==(const {{ .Name }}& other) const noexcept { |
| return *storage_ == *other.storage_; |
| } |
| bool operator!=(const {{ .Name }}& other) const noexcept { |
| return *storage_ != *other.storage_; |
| } |
| {{- end }} |
| |
| constexpr {{ .TagEnum }} Which() const { |
| return {{ .Name }}::IndexToTag(storage_->index()).value(); |
| } |
| |
| {{- range .Members }} |
| static {{ $.Name }} With{{ .UpperCamelCaseName }}({{ .Type }} val) { |
| return {{ $.Name }}(std::make_shared<Storage_>( |
| std::in_place_index_t<{{ .NaturalIndex }}>{}, |
| std::move(val))); |
| } |
| |
| const ::fidl::internal::UnionMemberView<{{ .NaturalIndex }}, Storage_> {{ .Name }}() const { |
| return ::fidl::internal::UnionMemberView<{{ .NaturalIndex }}, Storage_>(storage_); |
| } |
| ::fidl::internal::UnionMemberView<{{ .NaturalIndex }}, Storage_> {{ .Name }}() { |
| return ::fidl::internal::UnionMemberView<{{ .NaturalIndex }}, Storage_>(storage_); |
| } |
| {{- end }} |
| |
| {{ .Name }}(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : storage_(std::make_shared<Storage_>()) {} |
| |
| private: |
| std::shared_ptr<Storage_> storage_; |
| {{- if not .IsResourceType }} |
| std::shared_ptr<Storage_> CloneStorage_() const; |
| {{- end }} |
| friend struct ::fidl::internal::NaturalUnionCodingTraits<{{ . }}>; |
| static constexpr auto kMembers = std::make_tuple( |
| ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>() |
| {{- range $i, $m := .Members }} |
| , ::fidl::internal::NaturalUnionMember<{{ $m.NaturalConstraint }}>() |
| {{- end -}} |
| ); |
| |
| explicit {{ .Name }}(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {} |
| |
| static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, {{ .TagEnum }} tag) { |
| switch (tag) { |
| {{- range .Members }} |
| case {{ .TagName }}: return {{ .NaturalIndex }}; |
| {{- end }} |
| {{- if .IsFlexible }} |
| case {{ .TagUnknown }}: return 0; |
| {{- end }} |
| default: { |
| decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag); |
| return 0; |
| } |
| } |
| } |
| |
| static constexpr std::optional<{{ .TagEnum }}> IndexToTag(size_t index) { |
| switch (index) { |
| {{- range .Members }} |
| case {{ .NaturalIndex }}: return {{ .TagName }}; |
| {{- end }} |
| {{- if .IsFlexible }} |
| default: return {{ .TagUnknown }}; |
| {{- else }} |
| default: return std::nullopt; |
| {{- end }} |
| } |
| } |
| |
| }; |
| |
| {{ if .IsResourceType }} |
| {{- EndifFuchsia -}} |
| {{- end }} |
| {{- end }} |
| |
| {{- define "Union:Traits:NaturalTypesHeader" }} |
| {{ if .IsResourceType }} |
| {{- IfdefFuchsia -}} |
| {{- end }} |
| |
| extern "C" const fidl_type_t {{ .CodingTableType.Self }}; |
| |
| {{ if .IsResourceType }} |
| template <> |
| struct IsResource<{{ . }}> : public std::true_type {}; |
| {{- end }} |
| template <> |
| struct IsFidlType<{{ . }}> : public std::true_type {}; |
| template <> |
| struct IsUnion<{{ . }}> : public std::true_type {}; |
| |
| template <> |
| struct internal::NaturalCodingTraits<{{ . }}, ::fidl::internal::NaturalCodingConstraintEmpty> final |
| : public ::fidl::internal::NaturalUnionCodingTraits<{{ . }}> {}; |
| |
| {{ if .IsResourceType }} |
| {{- EndifFuchsia -}} |
| {{- end }} |
| {{- end }} |
| |
| |
| {{- define "Union:NaturalTypesSource" }} |
| {{ if .IsResourceType }} |
| {{- IfdefFuchsia -}} |
| {{- end }} |
| |
| {{- EnsureNamespace "" }} |
| |
| {{ if not .IsResourceType }} |
| std::shared_ptr<{{ . }}::Storage_> {{ .NoLeading }}::CloneStorage_() const { |
| const Storage_& storage = *storage_; |
| switch (storage_->index()) { |
| {{- range $i, $m := .Members }} |
| case {{ Add $i 1 }}: |
| return std::make_shared<Storage_>( |
| std::in_place_index<{{ Add $i 1 }}>, |
| ::fidl::internal::NaturalClone(std::get<{{ Add $i 1 }}>(storage))); |
| {{- end }} |
| default: |
| return std::make_shared<Storage_>(); |
| } |
| } |
| {{- end }} |
| |
| {{ if .IsResourceType }} |
| {{- EndifFuchsia -}} |
| {{ end }} |
| {{- end }} |
| |
| {{- define "Union:Traits:TypeConversionsHeader" }} |
| {{ if .IsResourceType }} |
| {{- IfdefFuchsia -}} |
| {{- end }} |
| |
| {{ $wireType := .Wire }} |
| {{ $naturalType := .Unified }} |
| template <> |
| struct WireNaturalConversionTraits<{{ $wireType }}, {{ $naturalType }}> { |
| static {{ $naturalType }} ToNatural({{ $wireType }} src); |
| static {{ $wireType }} ToWire(fidl::AnyArena& arena, {{ $naturalType }} src); |
| }; |
| |
| template <> |
| struct WireNaturalConversionTraits<{{ $wireType }}, std::unique_ptr<{{ $naturalType }}>> { |
| static std::unique_ptr<{{ $naturalType }}> ToNatural({{ $wireType }} src); |
| static {{ $wireType }} ToWire(fidl::AnyArena& arena, std::unique_ptr<{{ $naturalType }}> src); |
| }; |
| |
| template <> |
| struct NaturalTypeForWireType<{{ $wireType }}> { |
| using type = std::unique_ptr<{{ $naturalType }}>; |
| }; |
| template <> |
| struct WireTypeForNaturalType<{{ $naturalType }}> { |
| using type = {{ $wireType }}; |
| }; |
| template <> |
| struct WireTypeForNaturalType<std::unique_ptr<{{ $naturalType }}>> { |
| using type = {{ $wireType }}; |
| }; |
| |
| {{ if .IsResourceType }} |
| {{- EndifFuchsia -}} |
| {{ end }} |
| {{- end }} |
| |
| {{- define "Union:Traits:TypeConversionsSource" }} |
| {{ if .IsResourceType }} |
| {{- IfdefFuchsia -}} |
| {{- end }} |
| |
| {{ $wireType := .Wire }} |
| {{ $naturalType := .Unified }} |
| {{ $naturalType }} WireNaturalConversionTraits<{{ $wireType }}, {{ $naturalType }}>::ToNatural({{ $wireType }} src) { |
| switch (src.Which()) { |
| {{- range .Members }} |
| case {{ .TagName.Wire }}: |
| return {{ $naturalType }}::With{{ .UpperCamelCaseName }}( |
| WireNaturalConversionTraits<{{ .Type.Wire }}, {{ .Type.Unified }}>::ToNatural(std::move(src.{{ .Name }}()))); |
| {{- end }} |
| {{- if .IsFlexible }} |
| default: |
| return {{ $naturalType }}(); |
| {{- else }} |
| default: |
| ZX_PANIC("unknown union tag in strict union"); |
| {{- end }} |
| } |
| } |
| {{ $wireType }} WireNaturalConversionTraits<{{ $wireType }}, {{ $naturalType }}>::ToWire(fidl::AnyArena& arena, {{ $naturalType }} src) { |
| switch (src.Which()) { |
| {{- range .Members }} |
| case {{ .TagName.Unified }}: |
| return {{ $wireType }}::With{{ .UpperCamelCaseName }}( |
| {{- if not .Type.InlineInEnvelope }}arena, {{- end }} |
| WireNaturalConversionTraits<{{ .Type.Wire }}, {{ .Type.Unified }}>::ToWire(arena, std::move(src.{{ .Name }}().value()))); |
| {{- end }} |
| {{- if .IsFlexible }} |
| default: |
| return {{ $wireType }}(); |
| {{- end }} |
| } |
| } |
| |
| std::unique_ptr<{{ $naturalType }}> WireNaturalConversionTraits<{{ .Wire }}, std::unique_ptr<{{ $naturalType }}>>::ToNatural({{ .Wire }} src) { |
| if (src.has_invalid_tag()) { |
| return nullptr; |
| } |
| return std::make_unique<{{ $naturalType }}>(WireNaturalConversionTraits<{{ .Wire }}, {{ $naturalType }}>::ToNatural(std::move(src))); |
| } |
| {{ $wireType }} WireNaturalConversionTraits<{{ $wireType }}, std::unique_ptr<{{ $naturalType }}>>::ToWire(fidl::AnyArena& arena, std::unique_ptr<{{ $naturalType }}> src) { |
| if (!src) { |
| return {{ $wireType }}(); |
| } |
| return WireNaturalConversionTraits<{{ $wireType }}, {{ $naturalType }}>::ToWire(arena, std::move(*src)); |
| } |
| |
| {{ if .IsResourceType }} |
| {{- EndifFuchsia -}} |
| {{ end }} |
| {{- end }} |