blob: 96cd3395eea398794948e333be30d4dab9ef1199 [file] [log] [blame]
{{/*
// Copyright 2019 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 "Bits:CommonTypesHeader" }}
{{ EnsureNamespace . }}
{{- .Docs }}
{{- if .IsStrict }}
// |{{ .Name }}| is strict, hence is guaranteed to only contain
// members defined in the FIDL schema when receiving it in a message.
// Sending unknown members will fail at runtime.
{{- else }}
// |{{ .Name }}| is flexible, hence may contain unknown members not
// defined in the FIDL schema.
{{- end }}
class {{ .Name }} final {
public:
constexpr {{ .Name }}() = default;
// Constructs an instance of |{{ .Name }}| from an underlying primitive value,
// preserving any bit member not defined in the FIDL schema.
explicit constexpr {{ .Name }}({{ .Type }} value) : value_(value) {}
{{- range .Members }}
const static {{ $.Name }} {{ .Name }};
{{- end }}
const static {{ .Name }} kMask;
explicit constexpr inline operator {{ .Type }}() const { return value_; }
explicit constexpr inline operator bool() const { return static_cast<bool>(value_); }
constexpr inline bool operator==(const {{ .Name }}& other) const { return value_ == other.value_; }
constexpr inline bool operator!=(const {{ .Name }}& other) const { return value_ != other.value_; }
constexpr inline {{ .Name }} operator~() const;
constexpr inline {{ .Name }} operator|(const {{ .Name }}& other) const;
constexpr inline {{ .Name }} operator&(const {{ .Name }}& other) const;
constexpr inline {{ .Name }} operator^(const {{ .Name }}& other) const;
constexpr inline {{ .Name }} operator-(const {{ .Name }}& other) const;
constexpr inline void operator|=(const {{ .Name }}& other);
constexpr inline void operator&=(const {{ .Name }}& other);
constexpr inline void operator^=(const {{ .Name }}& other);
constexpr inline void operator-=(const {{ .Name }}& other);
// Constructs an instance of |{{ .Name }}| from an underlying primitive value
// if the primitive does not contain any unknown members not defined in the
// FIDL schema. Otherwise, returns |std::nullopt|.
constexpr inline static std::optional<{{ .Name }}> TryFrom({{ .Type }} value) {
if (value & ~kMask.value_) {
return std::nullopt;
}
return {{ .Name }}(value & {{ .Name }}::kMask.value_);
}
// Constructs an instance of |{{ .Name }}| from an underlying primitive value,
// clearing any bit member not defined in the FIDL schema.
constexpr inline static {{ .Name }} TruncatingUnknown({{ .Type }} value) {
return {{ .Name }}(value & {{ .Name }}::kMask.value_);
}
{{- if .IsFlexible }}
constexpr inline {{ .Name }} unknown_bits() const {
return *this & {{ .Name }}(~kMask.value_);
}
constexpr inline bool has_unknown_bits() const { return static_cast<bool>(unknown_bits()); }
{{- end }}
private:
{{ .Type }} value_ = 0;
};
{{- range $member := .Members }}
constexpr const {{ $ }} {{ $.Name }}::{{ $member.Name }} =
{{ $ }}({{ $member.Value }});
{{- end }}
constexpr const {{ . }} {{ .Name }}::kMask = {{ $ }}({{ .Mask }}u);
constexpr inline {{ . }} {{ .Name }}::operator~() const {
return {{ $ }}(static_cast<{{ .Type }}>(~this->value_ & kMask.value_));
}
constexpr inline {{ . }} {{ .Name }}::operator|(
const {{ . }}& other) const {
return {{ $ }}(static_cast<{{ .Type }}>(this->value_ | other.value_));
}
constexpr inline {{ . }} {{ .Name }}::operator&(
const {{ . }}& other) const {
return {{ $ }}(static_cast<{{ .Type }}>(this->value_ & other.value_));
}
constexpr inline {{ . }} {{ .Name }}::operator^(
const {{ . }}& other) const {
return {{ $ }}(static_cast<{{ .Type }}>(this->value_ ^ other.value_));
}
constexpr inline {{ . }} {{ .Name }}::operator-(
const {{ . }}& other) const {
return {{ $ }}(static_cast<{{ .Type }}>(this->value_ & ~other.value_));
}
constexpr inline void {{ .Name }}::operator|=(
const {{ . }}& other) {
this->value_ |= other.value_;
}
constexpr inline void {{ .Name }}::operator&=(
const {{ . }}& other) {
this->value_ &= other.value_;
}
constexpr inline void {{ .Name }}::operator^=(
const {{ . }}& other) {
this->value_ ^= other.value_;
}
constexpr inline void {{ .Name }}::operator-=(
const {{ . }}& other) {
this->value_ &= ~other.value_;
}
{{ end }}
{{- define "Bits:Traits:WireTypesHeader" }}
template <bool IsRecursive>
struct internal::WireCodingTraits<{{ . }}, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
static constexpr size_t inline_size = sizeof({{ .Type }});
static constexpr bool is_memcpy_compatible = {{ not .Strictness }};
static void Encode(internal::WireEncoder* encoder, {{ . }}* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
{{- if .Strictness }}
if (unlikely(static_cast<{{ .Type }}>(*value) & ~{{ .Mask }}ull)) {
encoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
}
{{- end }}
*position.As<{{ . }}>() = *value;
}
static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
{{- if .Strictness }}
{{ . }} value = *position.As<{{ . }}>();
if (unlikely(static_cast<{{ .Type }}>(value) & ~{{ .Mask }}ull)) {
decoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
}
{{- end }}
}
};
{{ end }}
{{- define "Bits:Traits:CommonTypesHeader" }}
template <>
struct IsFidlType<{{ . }}> : public std::true_type {};
template <>
struct ContainsHandle<{{ . }}> : public std::false_type {};
static_assert(std::is_standard_layout_v<{{ . }}>);
static_assert(sizeof({{ . }}) == sizeof({{ .Type }}));
{{- end }}
{{- define "Bits:WireTypesHeader" }}
{{ EnsureNamespace . -}}
using {{ .Name }} = {{ .Unified }};
{{- end }}
{{- define "Bits:Traits:NaturalTypesHeader" }}
template <>
struct internal::NaturalCodingTraits<{{ . }}, ::fidl::internal::NaturalCodingConstraintEmpty> {
static constexpr size_t inline_size_v2 = sizeof({{ .Type }});
static constexpr bool is_memcpy_compatible = {{ not .Strictness }};
static void Encode(internal::NaturalEncoder* encoder, {{ . }}* value, size_t offset, size_t recursion_depth) {
{{- if .Strictness }}
if (unlikely(static_cast<{{ .Type }}>(*value) & ~{{ .Mask }}ull)) {
encoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
}
{{- end }}
*encoder->template GetPtr<{{ . }}>(offset) = *value;
}
static void Decode(internal::NaturalDecoder* decoder, {{ . }}* value, size_t offset, size_t recursion_depth) {
*value = *decoder->template GetPtr<{{ . }}>(offset);
{{- if .Strictness }}
if (unlikely(static_cast<{{ .Type }}>(*value) & ~{{ .Mask }}ull)) {
decoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
}
{{- end }}
}
};
{{- end }}
{{- define "Bits:Traits:TypeConversionsHeader" }}
template <>
struct NaturalTypeForWireType<{{ .Wire }}> {
using type = {{ .Unified }};
};
template <>
struct WireTypeForNaturalType<{{ .Unified }}> {
using type = {{ .Wire }};
};
{{- end }}