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

#pragma once

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

namespace test {
namespace consts {

//
// Domain objects declarations
//

enum class EnumType : int32_t {

  VALUE = 1u,

  true_ = 2u,
};

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

enum class BitsType : uint32_t {

  VALUE = 1u,

  true_ = 2u,
};

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

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

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

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

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

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

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

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

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

constexpr zx_rights_t ZX_RIGHTS_VAL = ZX_RIGHT_READ;

constexpr zx_obj_type_t ZX_OBJ_VAL = ZX_OBJ_TYPE_CHANNEL;

constexpr uint64_t ZX_CONST = ZX_CHANNEL_MAX_MSG_BYTES;

extern const char* USERNAME;

constexpr uint32_t POPULATION_USA_2018 = 330000000u;

constexpr int8_t OFFSET = -33;

constexpr float MIN_TEMP = -273.15f;

constexpr uint64_t FUCHSIA = 4054509061583223046u;

constexpr ::test::consts::EnumType enumVal = ::test::consts::EnumType::VALUE;

constexpr ::test::consts::EnumType enumTrue = ::test::consts::EnumType::true_;

constexpr int32_t enumPrimitiveVal = ::test::consts::EnumType::VALUE;

constexpr int32_t enumPrimitiveTrue = ::test::consts::EnumType::true_;

constexpr bool ENABLED_FLAG = true;

constexpr uint64_t DIAMOND = 1746410393481133080u;

constexpr double CONVERSION_FACTOR = 1.41421;

constexpr ::test::consts::BitsType bitsVal = ::test::consts::BitsType::VALUE;

constexpr ::test::consts::BitsType bitsTrue = ::test::consts::BitsType::true_;

constexpr uint32_t bitsPrimitiveVal = ::test::consts::BitsType::VALUE;

constexpr uint32_t bitsPrimitiveTrue = ::test::consts::BitsType::true_;

constexpr uint16_t ANSWER_IN_BINARY = 42u;

constexpr uint16_t ANSWER = 42u;

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

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

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

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

template <>
struct Equality<::test::consts::BitsType> {
  bool operator()(const ::test::consts::BitsType& _lhs, const ::test::consts::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
