// 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 consts {

enum class EnumType : int32_t {

  VALUE = 1u,

  true_ = 2u,
};

inline zx_status_t Clone(::fidl::test::consts::EnumType value,
                         ::fidl::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 ::fidl::test::consts::BitsType operator|(
    ::fidl::test::consts::BitsType _lhs, ::fidl::test::consts::BitsType _rhs) {
  return static_cast<::fidl::test::consts::BitsType>(
      static_cast<uint32_t>(_lhs) | static_cast<uint32_t>(_rhs));
}

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

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

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

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

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

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

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

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 EnumType enumVal = EnumType::VALUE;

constexpr EnumType enumTrue = EnumType::true_;

constexpr int32_t enumPrimitiveVal = EnumType::VALUE;

constexpr int32_t enumPrimitiveTrue = EnumType::true_;

constexpr bool ENABLED_FLAG = true;

constexpr uint64_t DIAMOND = 1746410393481133080u;

constexpr double CONVERSION_FACTOR = 1.41421;

constexpr BitsType bitsVal = BitsType::VALUE;

constexpr BitsType bitsTrue = BitsType::true_;

constexpr int32_t bitsPrimitiveVal = BitsType::VALUE;

constexpr int32_t bitsPrimitiveTrue = BitsType::true_;

constexpr uint16_t ANSWER_IN_BINARY = 42u;

constexpr uint16_t ANSWER = 42u;
}  // namespace consts
}  // namespace test
}  // namespace fidl
namespace fidl {

template <>
struct CodingTraits<::fidl::test::consts::EnumType> {
  static constexpr size_t inline_size_old =
      sizeof(::fidl::test::consts::EnumType);
  static constexpr size_t inline_size_v1_no_ee =
      sizeof(::fidl::test::consts::EnumType);
  static void Encode(Encoder* encoder, ::fidl::test::consts::EnumType* value,
                     size_t offset) {
    int32_t underlying = static_cast<int32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::fidl::test::consts::EnumType* value,
                     size_t offset) {
    int32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::fidl::test::consts::EnumType>(underlying);
  }
};

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

template <>
struct CodingTraits<::fidl::test::consts::BitsType> {
  static constexpr size_t inline_size_old =
      sizeof(::fidl::test::consts::BitsType);
  static constexpr size_t inline_size_v1_no_ee =
      sizeof(::fidl::test::consts::BitsType);
  static void Encode(Encoder* encoder, ::fidl::test::consts::BitsType* value,
                     size_t offset) {
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::fidl::test::consts::BitsType* value,
                     size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::fidl::test::consts::BitsType>(underlying);
  }
};

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

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

//
// Proxies and stubs declarations
//
namespace fidl {
namespace test {
namespace consts {}  // namespace consts
}  // namespace test
}  // namespace fidl
