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

#pragma once

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

namespace test {
namespace bitsconstants {

//
// Domain objects declarations
//

enum class BitsType : uint32_t {

  A = 1u,

  B = 128u,

  C = 2u,
};

const static BitsType BitsTypeMask = static_cast<BitsType>(131u);

constexpr inline ::test::bitsconstants::BitsType operator|(::test::bitsconstants::BitsType _lhs, ::test::bitsconstants::BitsType _rhs) {
  return static_cast<::test::bitsconstants::BitsType>(
      static_cast<uint32_t>(_lhs) | static_cast<uint32_t>(_rhs));
}

constexpr inline ::test::bitsconstants::BitsType& operator|=(::test::bitsconstants::BitsType& _lhs,
                                                             ::test::bitsconstants::BitsType _rhs) {
  _lhs = _lhs | _rhs;
  return _lhs;
}

constexpr inline ::test::bitsconstants::BitsType operator&(::test::bitsconstants::BitsType _lhs,
                                                           ::test::bitsconstants::BitsType _rhs) {
  return static_cast<::test::bitsconstants::BitsType>(
      static_cast<uint32_t>(_lhs) & static_cast<uint32_t>(_rhs));
}

constexpr inline ::test::bitsconstants::BitsType& operator&=(::test::bitsconstants::BitsType& _lhs,
                                                             ::test::bitsconstants::BitsType _rhs) {
  _lhs = _lhs & _rhs;
  return _lhs;
}

constexpr inline ::test::bitsconstants::BitsType operator^(::test::bitsconstants::BitsType _lhs,
                                                           ::test::bitsconstants::BitsType _rhs) {
  return static_cast<::test::bitsconstants::BitsType>(
      static_cast<uint32_t>(_lhs) ^ static_cast<uint32_t>(_rhs));
}

constexpr inline ::test::bitsconstants::BitsType& operator^=(::test::bitsconstants::BitsType& _lhs,
                                                             ::test::bitsconstants::BitsType _rhs) {
  _lhs = _lhs ^ _rhs;
  return _lhs;
}

constexpr inline ::test::bitsconstants::BitsType operator~(::test::bitsconstants::BitsType _value) {
  return static_cast<::test::bitsconstants::BitsType>(
      ~static_cast<uint32_t>(_value) & static_cast<uint32_t>(::test::bitsconstants::BitsTypeMask));
}

inline zx_status_t Clone(::test::bitsconstants::BitsType value,
                         ::test::bitsconstants::BitsType* result) {
  *result = value;
  return ZX_OK;
}

constexpr ::test::bitsconstants::BitsType Const3 = static_cast<::test::bitsconstants::BitsType>(131);

constexpr ::test::bitsconstants::BitsType Const2 = static_cast<::test::bitsconstants::BitsType>(129);

constexpr ::test::bitsconstants::BitsType Const1 = ::test::bitsconstants::BitsType::A;

}  // namespace bitsconstants
}  // namespace test
namespace fidl {
template <>
struct CodingTraits<::test::bitsconstants::BitsType> {
  static constexpr size_t inline_size_v2 = sizeof(::test::bitsconstants::BitsType);
  static void Encode(Encoder* encoder, ::test::bitsconstants::BitsType* 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, ::test::bitsconstants::BitsType* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::bitsconstants::BitsType>(underlying);
  }
};

inline zx_status_t Clone(::test::bitsconstants::BitsType value,
                         ::test::bitsconstants::BitsType* result) {
  return ::test::bitsconstants::Clone(value, result);
}

template <>
struct Equality<::test::bitsconstants::BitsType> {
  bool operator()(const ::test::bitsconstants::BitsType& _lhs, const ::test::bitsconstants::BitsType& _rhs) const {
    uint32_t _lhs_underlying = static_cast<uint32_t>(_lhs);
    uint32_t _rhs_underlying = static_cast<uint32_t>(_rhs);
    return ::fidl::Equals(_lhs_underlying, _rhs_underlying);
  }
};

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