// WARNING: This file is machine generated by fidlgen.

#pragma once

#include "lib/fidl/cpp/internal/header.h"

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fidl {
namespace test {
namespace enum_ {

enum class MyStrictEnum : uint32_t {

  FOO = 1u,

  BAR = 2u,
};

inline zx_status_t Clone(::fidl::test::enum_::MyStrictEnum value,
                         ::fidl::test::enum_::MyStrictEnum* result) {
  *result = value;
  return ZX_OK;
}

class MyFlexibleEnumWithCustomUnknown final {
 public:
  constexpr MyFlexibleEnumWithCustomUnknown() : value_(0) {}
  constexpr explicit MyFlexibleEnumWithCustomUnknown(uint32_t value)
      : value_(value) {}
  constexpr MyFlexibleEnumWithCustomUnknown(
      const MyFlexibleEnumWithCustomUnknown& other) = default;
  constexpr operator uint32_t() const { return value_; }

  constexpr bool IsUnknown() const {
    switch (value_) {
      case 1u:

      case 2u:

        return false;
      default:
        return true;
    }
  }

  constexpr static MyFlexibleEnumWithCustomUnknown Unknown() {
    return MyFlexibleEnumWithCustomUnknown(0x3);
  }

  static const MyFlexibleEnumWithCustomUnknown FOO;

  static const MyFlexibleEnumWithCustomUnknown BAR;

  static const MyFlexibleEnumWithCustomUnknown CUSTOM_UNKNOWN;

 private:
  uint32_t value_;
};

#if !(__cplusplus < 201703)
constexpr const ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown
    MyFlexibleEnumWithCustomUnknown::FOO =
        ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown(1u);
constexpr const ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown
    MyFlexibleEnumWithCustomUnknown::BAR =
        ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown(2u);
constexpr const ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown
    MyFlexibleEnumWithCustomUnknown::CUSTOM_UNKNOWN =
        ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown(3u);
#endif  // !(__cplusplus < 201703)

inline zx_status_t Clone(
    ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown value,
    ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown* result) {
  *result = value;
  return ZX_OK;
}

class MyFlexibleEnum final {
 public:
  constexpr MyFlexibleEnum() : value_(0) {}
  constexpr explicit MyFlexibleEnum(uint32_t value) : value_(value) {}
  constexpr MyFlexibleEnum(const MyFlexibleEnum& other) = default;
  constexpr operator uint32_t() const { return value_; }

  constexpr bool IsUnknown() const {
    switch (value_) {
      case 1u:

      case 2u:

        return false;
      default:
        return true;
    }
  }

  constexpr static MyFlexibleEnum Unknown() {
    return MyFlexibleEnum(0xffffffff);
  }

  static const MyFlexibleEnum FOO;

  static const MyFlexibleEnum BAR;

 private:
  uint32_t value_;
};

#if !(__cplusplus < 201703)
constexpr const ::fidl::test::enum_::MyFlexibleEnum MyFlexibleEnum::FOO =
    ::fidl::test::enum_::MyFlexibleEnum(1u);
constexpr const ::fidl::test::enum_::MyFlexibleEnum MyFlexibleEnum::BAR =
    ::fidl::test::enum_::MyFlexibleEnum(2u);
#endif  // !(__cplusplus < 201703)

inline zx_status_t Clone(::fidl::test::enum_::MyFlexibleEnum value,
                         ::fidl::test::enum_::MyFlexibleEnum* result) {
  *result = value;
  return ZX_OK;
}

}  // namespace enum_
}  // namespace test
template <>
struct CodingTraits<::fidl::test::enum_::MyStrictEnum> {
  static constexpr size_t inline_size_old =
      sizeof(::fidl::test::enum_::MyStrictEnum);
  static constexpr size_t inline_size_v1_no_ee =
      sizeof(::fidl::test::enum_::MyStrictEnum);
  static void Encode(
      Encoder* encoder, ::fidl::test::enum_::MyStrictEnum* value, size_t offset,
      cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::fidl::test::enum_::MyStrictEnum* value,
                     size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::fidl::test::enum_::MyStrictEnum>(underlying);
  }
};

inline zx_status_t Clone(::fidl::test::enum_::MyStrictEnum value,
                         ::fidl::test::enum_::MyStrictEnum* result) {
  return ::fidl::test::enum_::Clone(value, result);
}
template <>
struct Equality<::fidl::test::enum_::MyStrictEnum> {
  bool operator()(const ::fidl::test::enum_::MyStrictEnum& _lhs,
                  const ::fidl::test::enum_::MyStrictEnum& _rhs) const {
    return _lhs == _rhs;
  }
};

template <>
struct CodingTraits<::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown> {
  static constexpr size_t inline_size_old =
      sizeof(::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown);
  static constexpr size_t inline_size_v1_no_ee =
      sizeof(::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown);
  static void Encode(
      Encoder* encoder,
      ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown* value,
      size_t offset,
      cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(
      Decoder* decoder,
      ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown* value,
      size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown>(
        underlying);
  }
};

inline zx_status_t Clone(
    ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown value,
    ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown* result) {
  return ::fidl::test::enum_::Clone(value, result);
}
template <>
struct Equality<::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown> {
  bool operator()(
      const ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown& _lhs,
      const ::fidl::test::enum_::MyFlexibleEnumWithCustomUnknown& _rhs) const {
    return _lhs == _rhs;
  }
};

template <>
struct CodingTraits<::fidl::test::enum_::MyFlexibleEnum> {
  static constexpr size_t inline_size_old =
      sizeof(::fidl::test::enum_::MyFlexibleEnum);
  static constexpr size_t inline_size_v1_no_ee =
      sizeof(::fidl::test::enum_::MyFlexibleEnum);
  static void Encode(
      Encoder* encoder, ::fidl::test::enum_::MyFlexibleEnum* value,
      size_t offset,
      cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder,
                     ::fidl::test::enum_::MyFlexibleEnum* value,
                     size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::fidl::test::enum_::MyFlexibleEnum>(underlying);
  }
};

inline zx_status_t Clone(::fidl::test::enum_::MyFlexibleEnum value,
                         ::fidl::test::enum_::MyFlexibleEnum* result) {
  return ::fidl::test::enum_::Clone(value, result);
}
template <>
struct Equality<::fidl::test::enum_::MyFlexibleEnum> {
  bool operator()(const ::fidl::test::enum_::MyFlexibleEnum& _lhs,
                  const ::fidl::test::enum_::MyFlexibleEnum& _rhs) const {
    return _lhs == _rhs;
  }
};

//
// Proxies and stubs declarations
//
}  // namespace fidl
