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

#pragma once

#include <lib/fidl/internal.h>
#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/object_view.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/vector_view.h>
#include <lib/fit/function.h>
#include <lib/stdcompat/optional.h>

#include <algorithm>
#include <cstddef>
#include <variant>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/client_end.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/result.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/server_end.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>
#include <lib/fidl/llcpp/transaction.h>
#include <lib/fidl/llcpp/wire_messaging.h>
#include <lib/fidl/txn_header.h>

#endif  // __Fuchsia__
#include <zircon/fidl.h>

namespace fidl_test_bits {
namespace wire {
// |StrictBits| is strict, hence is guaranteed to only contain
// members defined in the FIDL schema when receiving it in a message.
// Sending unknown members will fail at runtime.
class StrictBits final {
 public:
  constexpr StrictBits() = default;
  constexpr StrictBits(const StrictBits& other) = default;

  // Constructs an instance of |StrictBits| from an underlying primitive value,
  // preserving any bit member not defined in the FIDL schema.
  explicit constexpr StrictBits(uint64_t value) : value_(value) {}
  const static StrictBits SMALLEST;
  const static StrictBits BIGGEST;
  const static StrictBits 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 StrictBits& other) const {
    return value_ == other.value_;
  }
  constexpr inline bool operator!=(const StrictBits& other) const {
    return value_ != other.value_;
  }
  constexpr inline StrictBits operator~() const;
  constexpr inline StrictBits operator|(const StrictBits& other) const;
  constexpr inline StrictBits operator&(const StrictBits& other) const;
  constexpr inline StrictBits operator^(const StrictBits& other) const;
  constexpr inline void operator|=(const StrictBits& other);
  constexpr inline void operator&=(const StrictBits& other);
  constexpr inline void operator^=(const StrictBits& other);

  // Constructs an instance of |StrictBits| 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<StrictBits> TryFrom(uint64_t value) {
    if (value & ~kMask.value_) {
      return cpp17::nullopt;
    }
    return StrictBits(value & StrictBits::kMask.value_);
  }

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

 private:
  uint64_t value_ = 0;
};
constexpr const ::fidl_test_bits::wire::StrictBits StrictBits::SMALLEST =
    ::fidl_test_bits::wire::StrictBits(1u);
constexpr const ::fidl_test_bits::wire::StrictBits StrictBits::BIGGEST =
    ::fidl_test_bits::wire::StrictBits(9223372036854775808u);
constexpr const ::fidl_test_bits::wire::StrictBits StrictBits::kMask =
    ::fidl_test_bits::wire::StrictBits(9223372036854775809u);

constexpr inline ::fidl_test_bits::wire::StrictBits StrictBits::operator~()
    const {
  return ::fidl_test_bits::wire::StrictBits(
      static_cast<uint64_t>(~this->value_ & kMask.value_));
}

constexpr inline ::fidl_test_bits::wire::StrictBits StrictBits::operator|(
    const ::fidl_test_bits::wire::StrictBits& other) const {
  return ::fidl_test_bits::wire::StrictBits(
      static_cast<uint64_t>(this->value_ | other.value_));
}

constexpr inline ::fidl_test_bits::wire::StrictBits StrictBits::operator&(
    const ::fidl_test_bits::wire::StrictBits& other) const {
  return ::fidl_test_bits::wire::StrictBits(
      static_cast<uint64_t>(this->value_ & other.value_));
}

constexpr inline ::fidl_test_bits::wire::StrictBits StrictBits::operator^(
    const ::fidl_test_bits::wire::StrictBits& other) const {
  return ::fidl_test_bits::wire::StrictBits(
      static_cast<uint64_t>(this->value_ ^ other.value_));
}

constexpr inline void StrictBits::operator|=(
    const ::fidl_test_bits::wire::StrictBits& other) {
  this->value_ |= other.value_;
}

constexpr inline void StrictBits::operator&=(
    const ::fidl_test_bits::wire::StrictBits& other) {
  this->value_ &= other.value_;
}

constexpr inline void StrictBits::operator^=(
    const ::fidl_test_bits::wire::StrictBits& other) {
  this->value_ ^= other.value_;
}

// |MyBits| is strict, hence is guaranteed to only contain
// members defined in the FIDL schema when receiving it in a message.
// Sending unknown members will fail at runtime.
class MyBits final {
 public:
  constexpr MyBits() = default;
  constexpr MyBits(const MyBits& other) = default;

  // Constructs an instance of |MyBits| from an underlying primitive value,
  // preserving any bit member not defined in the FIDL schema.
  explicit constexpr MyBits(uint32_t value) : value_(value) {}
  const static MyBits MY_FIRST_BIT;
  const static MyBits MY_OTHER_BIT;
  const static MyBits MASK;
  const static MyBits kMask;

  explicit constexpr inline operator uint32_t() const { return value_; }
  explicit constexpr inline operator bool() const {
    return static_cast<bool>(value_);
  }
  constexpr inline bool operator==(const MyBits& other) const {
    return value_ == other.value_;
  }
  constexpr inline bool operator!=(const MyBits& other) const {
    return value_ != other.value_;
  }
  constexpr inline MyBits operator~() const;
  constexpr inline MyBits operator|(const MyBits& other) const;
  constexpr inline MyBits operator&(const MyBits& other) const;
  constexpr inline MyBits operator^(const MyBits& other) const;
  constexpr inline void operator|=(const MyBits& other);
  constexpr inline void operator&=(const MyBits& other);
  constexpr inline void operator^=(const MyBits& other);

  // Constructs an instance of |MyBits| 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<MyBits> TryFrom(uint32_t value) {
    if (value & ~kMask.value_) {
      return cpp17::nullopt;
    }
    return MyBits(value & MyBits::kMask.value_);
  }

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

 private:
  uint32_t value_ = 0;
};
constexpr const ::fidl_test_bits::wire::MyBits MyBits::MY_FIRST_BIT =
    ::fidl_test_bits::wire::MyBits(1u);
constexpr const ::fidl_test_bits::wire::MyBits MyBits::MY_OTHER_BIT =
    ::fidl_test_bits::wire::MyBits(2u);
constexpr const ::fidl_test_bits::wire::MyBits MyBits::MASK =
    ::fidl_test_bits::wire::MyBits(4u);
constexpr const ::fidl_test_bits::wire::MyBits MyBits::kMask =
    ::fidl_test_bits::wire::MyBits(7u);

constexpr inline ::fidl_test_bits::wire::MyBits MyBits::operator~() const {
  return ::fidl_test_bits::wire::MyBits(
      static_cast<uint32_t>(~this->value_ & kMask.value_));
}

constexpr inline ::fidl_test_bits::wire::MyBits MyBits::operator|(
    const ::fidl_test_bits::wire::MyBits& other) const {
  return ::fidl_test_bits::wire::MyBits(
      static_cast<uint32_t>(this->value_ | other.value_));
}

constexpr inline ::fidl_test_bits::wire::MyBits MyBits::operator&(
    const ::fidl_test_bits::wire::MyBits& other) const {
  return ::fidl_test_bits::wire::MyBits(
      static_cast<uint32_t>(this->value_ & other.value_));
}

constexpr inline ::fidl_test_bits::wire::MyBits MyBits::operator^(
    const ::fidl_test_bits::wire::MyBits& other) const {
  return ::fidl_test_bits::wire::MyBits(
      static_cast<uint32_t>(this->value_ ^ other.value_));
}

constexpr inline void MyBits::operator|=(
    const ::fidl_test_bits::wire::MyBits& other) {
  this->value_ |= other.value_;
}

constexpr inline void MyBits::operator&=(
    const ::fidl_test_bits::wire::MyBits& other) {
  this->value_ &= other.value_;
}

constexpr inline void MyBits::operator^=(
    const ::fidl_test_bits::wire::MyBits& other) {
  this->value_ ^= other.value_;
}

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

  // Constructs an instance of |FlexibleBits| from an underlying primitive
  // value, preserving any bit member not defined in the FIDL schema.
  explicit constexpr 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);

  // 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_);
  }
  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;
};
constexpr const ::fidl_test_bits::wire::FlexibleBits FlexibleBits::SMALLEST =
    ::fidl_test_bits::wire::FlexibleBits(1u);
constexpr const ::fidl_test_bits::wire::FlexibleBits FlexibleBits::BIGGEST =
    ::fidl_test_bits::wire::FlexibleBits(9223372036854775808u);
constexpr const ::fidl_test_bits::wire::FlexibleBits FlexibleBits::kMask =
    ::fidl_test_bits::wire::FlexibleBits(9223372036854775809u);

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

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

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

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

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

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

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

}  // namespace wire
}  // namespace fidl_test_bits
namespace fidl {

template <>
struct IsFidlType<::fidl_test_bits::wire::StrictBits> : public std::true_type {
};
static_assert(std::is_standard_layout_v<::fidl_test_bits::wire::StrictBits>);
static_assert(sizeof(::fidl_test_bits::wire::StrictBits) == sizeof(uint64_t));

template <>
struct IsFidlType<::fidl_test_bits::wire::MyBits> : public std::true_type {};
static_assert(std::is_standard_layout_v<::fidl_test_bits::wire::MyBits>);
static_assert(sizeof(::fidl_test_bits::wire::MyBits) == sizeof(uint32_t));

template <>
struct IsFidlType<::fidl_test_bits::wire::FlexibleBits>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<::fidl_test_bits::wire::FlexibleBits>);
static_assert(sizeof(::fidl_test_bits::wire::FlexibleBits) == sizeof(uint64_t));

}  // namespace fidl
