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

#pragma once

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

namespace test {
namespace bits {

//
// Domain objects declarations
//

enum class StrictBits : uint64_t {

  SMALLEST = 1u,

  BIGGEST = 9223372036854775808u,
};

const static StrictBits StrictBitsMask = static_cast<StrictBits>(9223372036854775809u);

constexpr inline ::test::bits::StrictBits operator|(::test::bits::StrictBits _lhs, ::test::bits::StrictBits _rhs) {
  return static_cast<::test::bits::StrictBits>(
      static_cast<uint64_t>(_lhs) | static_cast<uint64_t>(_rhs));
}

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

constexpr inline ::test::bits::StrictBits operator&(::test::bits::StrictBits _lhs,
                                                    ::test::bits::StrictBits _rhs) {
  return static_cast<::test::bits::StrictBits>(
      static_cast<uint64_t>(_lhs) & static_cast<uint64_t>(_rhs));
}

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

constexpr inline ::test::bits::StrictBits operator^(::test::bits::StrictBits _lhs,
                                                    ::test::bits::StrictBits _rhs) {
  return static_cast<::test::bits::StrictBits>(
      static_cast<uint64_t>(_lhs) ^ static_cast<uint64_t>(_rhs));
}

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

constexpr inline ::test::bits::StrictBits operator~(::test::bits::StrictBits _value) {
  return static_cast<::test::bits::StrictBits>(
      ~static_cast<uint64_t>(_value) & static_cast<uint64_t>(::test::bits::StrictBitsMask));
}

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

enum class MyBits : uint32_t {

  MY_FIRST_BIT = 1u,

  MY_OTHER_BIT = 2u,

  MASK = 4u,
};

const static MyBits MyBitsMask = static_cast<MyBits>(7u);

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

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

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

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

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

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

constexpr inline ::test::bits::MyBits operator~(::test::bits::MyBits _value) {
  return static_cast<::test::bits::MyBits>(
      ~static_cast<uint32_t>(_value) & static_cast<uint32_t>(::test::bits::MyBitsMask));
}

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

// |FlexibleBits| is flexible, hence may contain unknown members not
// defined in the FIDL schema.
class FlexibleBits final {
 public:
  constexpr FlexibleBits() = default;

  // Constructs an instance of |FlexibleBits| from an underlying primitive value
  // if the primitive does not contain any unknown members not defined in the
  // FIDL schema. Otherwise, returns |cpp17::nullopt|.
  constexpr inline static cpp17::optional<FlexibleBits> TryFrom(uint64_t value) {
    if (value & ~kMask.value_) {
      return cpp17::nullopt;
    }
    return FlexibleBits(value & FlexibleBits::kMask.value_);
  }

  // Constructs an instance of |FlexibleBits| from an underlying primitive value,
  // clearing any bit member not defined in the FIDL schema.
  constexpr inline static FlexibleBits TruncatingUnknown(uint64_t value) {
    return FlexibleBits(value & FlexibleBits::kMask.value_);
  }

  // Constructs an instance of |FlexibleBits| from an underlying primitive value,
  // preserving any bit member not defined in the FIDL schema.
  constexpr explicit FlexibleBits(uint64_t value) : value_(value) {}
  const static FlexibleBits SMALLEST;
  const static FlexibleBits BIGGEST;
  const static FlexibleBits kMask;

  explicit constexpr inline operator uint64_t() const { return value_; }
  explicit constexpr inline operator bool() const { return static_cast<bool>(value_); }
  constexpr inline bool operator==(const FlexibleBits& other) const { return value_ == other.value_; }
  constexpr inline bool operator!=(const FlexibleBits& other) const { return value_ != other.value_; }
  constexpr inline FlexibleBits operator~() const;
  constexpr inline FlexibleBits operator|(const FlexibleBits& other) const;
  constexpr inline FlexibleBits operator&(const FlexibleBits& other) const;
  constexpr inline FlexibleBits operator^(const FlexibleBits& other) const;
  constexpr inline void operator|=(const FlexibleBits& other);
  constexpr inline void operator&=(const FlexibleBits& other);
  constexpr inline void operator^=(const FlexibleBits& other);
  constexpr inline FlexibleBits unknown_bits() const {
    return *this & FlexibleBits(~kMask.value_);
  }
  constexpr inline bool has_unknown_bits() const { return static_cast<bool>(unknown_bits()); }

 private:
  uint64_t value_ = 0;
};

#if !(__cplusplus < 201703)
constexpr const ::test::bits::FlexibleBits FlexibleBits::SMALLEST = ::test::bits::FlexibleBits(1u);
constexpr const ::test::bits::FlexibleBits FlexibleBits::BIGGEST = ::test::bits::FlexibleBits(9223372036854775808u);
constexpr const ::test::bits::FlexibleBits FlexibleBits::kMask = ::test::bits::FlexibleBits(9223372036854775809u);

#endif  // !(__cplusplus < 201703)

constexpr inline ::test::bits::FlexibleBits FlexibleBits::operator~() const {
  return ::test::bits::FlexibleBits(static_cast<uint64_t>(~this->value_ & kMask.value_));
}

constexpr inline ::test::bits::FlexibleBits FlexibleBits::operator|(
    const ::test::bits::FlexibleBits& other) const {
  return ::test::bits::FlexibleBits(static_cast<uint64_t>(this->value_ | other.value_));
}

constexpr inline ::test::bits::FlexibleBits FlexibleBits::operator&(
    const ::test::bits::FlexibleBits& other) const {
  return ::test::bits::FlexibleBits(static_cast<uint64_t>(this->value_ & other.value_));
}

constexpr inline ::test::bits::FlexibleBits FlexibleBits::operator^(
    const ::test::bits::FlexibleBits& other) const {
  return ::test::bits::FlexibleBits(static_cast<uint64_t>(this->value_ ^ other.value_));
}

constexpr inline void FlexibleBits::operator|=(
    const ::test::bits::FlexibleBits& other) {
  this->value_ |= other.value_;
}

constexpr inline void FlexibleBits::operator&=(
    const ::test::bits::FlexibleBits& other) {
  this->value_ &= other.value_;
}

constexpr inline void FlexibleBits::operator^=(
    const ::test::bits::FlexibleBits& other) {
  this->value_ ^= other.value_;
}

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

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

inline zx_status_t Clone(::test::bits::StrictBits value,
                         ::test::bits::StrictBits* result) {
  return ::test::bits::Clone(value, result);
}

template <>
struct Equality<::test::bits::StrictBits> {
  bool operator()(const ::test::bits::StrictBits& _lhs, const ::test::bits::StrictBits& _rhs) const {
    uint64_t _lhs_underlying = static_cast<uint64_t>(_lhs);
    uint64_t _rhs_underlying = static_cast<uint64_t>(_rhs);
    return ::fidl::Equals(_lhs_underlying, _rhs_underlying);
  }
};
template <>
struct CodingTraits<::test::bits::MyBits> {
  static constexpr size_t inline_size_v2 = sizeof(::test::bits::MyBits);
  static void Encode(Encoder* encoder, ::test::bits::MyBits* 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::bits::MyBits* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::bits::MyBits>(underlying);
  }
};

inline zx_status_t Clone(::test::bits::MyBits value,
                         ::test::bits::MyBits* result) {
  return ::test::bits::Clone(value, result);
}

template <>
struct Equality<::test::bits::MyBits> {
  bool operator()(const ::test::bits::MyBits& _lhs, const ::test::bits::MyBits& _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);
  }
};
template <>
struct CodingTraits<::test::bits::FlexibleBits> {
  static constexpr size_t inline_size_v2 = sizeof(::test::bits::FlexibleBits);
  static void Encode(Encoder* encoder, ::test::bits::FlexibleBits* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint64_t underlying = static_cast<uint64_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::bits::FlexibleBits* value, size_t offset) {
    uint64_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::bits::FlexibleBits>(underlying);
  }
};

inline zx_status_t Clone(::test::bits::FlexibleBits value,
                         ::test::bits::FlexibleBits* result) {
  return ::test::bits::Clone(value, result);
}

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

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