// 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/buffer_allocator.h>
#include <lib/fidl/llcpp/buffer_then_heap_allocator.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.h>
#include <lib/fidl/llcpp/memory.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/tracking_ptr.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/vector_view.h>
#include <lib/fit/function.h>
#include <lib/fit/optional.h>

#include <variant>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/result.h>
#include <lib/fidl/llcpp/server.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/txn_header.h>
#endif  // __Fuchsia__
#include <zircon/fidl.h>

namespace llcpp {

namespace fidl {
namespace test {
namespace bits {

// |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 |fit::nullopt|.
  constexpr inline static fit::optional<StrictBits> TryFrom(uint64_t value) {
    if (value & ~kMask.value_) {
      return fit::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 ::llcpp::fidl::test::bits::StrictBits StrictBits::SMALLEST =
    ::llcpp::fidl::test::bits::StrictBits(1u);
constexpr const ::llcpp::fidl::test::bits::StrictBits StrictBits::BIGGEST =
    ::llcpp::fidl::test::bits::StrictBits(9223372036854775808u);
constexpr const ::llcpp::fidl::test::bits::StrictBits StrictBits::kMask =
    ::llcpp::fidl::test::bits::StrictBits(9223372036854775809u);

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

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

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

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

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

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

constexpr inline void StrictBits::operator^=(
    const ::llcpp::fidl::test::bits::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 |fit::nullopt|.
  constexpr inline static fit::optional<MyBits> TryFrom(uint32_t value) {
    if (value & ~kMask.value_) {
      return fit::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 ::llcpp::fidl::test::bits::MyBits MyBits::MY_FIRST_BIT =
    ::llcpp::fidl::test::bits::MyBits(1u);
constexpr const ::llcpp::fidl::test::bits::MyBits MyBits::MY_OTHER_BIT =
    ::llcpp::fidl::test::bits::MyBits(2u);
constexpr const ::llcpp::fidl::test::bits::MyBits MyBits::MASK =
    ::llcpp::fidl::test::bits::MyBits(4u);
constexpr const ::llcpp::fidl::test::bits::MyBits MyBits::kMask =
    ::llcpp::fidl::test::bits::MyBits(7u);

constexpr inline ::llcpp::fidl::test::bits::MyBits MyBits::operator~() const {
  return ::llcpp::fidl::test::bits::MyBits(
      static_cast<uint32_t>(~this->value_ & kMask.value_));
}

constexpr inline ::llcpp::fidl::test::bits::MyBits MyBits::operator|(
    const ::llcpp::fidl::test::bits::MyBits& other) const {
  return ::llcpp::fidl::test::bits::MyBits(
      static_cast<uint32_t>(this->value_ | other.value_));
}

constexpr inline ::llcpp::fidl::test::bits::MyBits MyBits::operator&(
    const ::llcpp::fidl::test::bits::MyBits& other) const {
  return ::llcpp::fidl::test::bits::MyBits(
      static_cast<uint32_t>(this->value_ & other.value_));
}

constexpr inline ::llcpp::fidl::test::bits::MyBits MyBits::operator^(
    const ::llcpp::fidl::test::bits::MyBits& other) const {
  return ::llcpp::fidl::test::bits::MyBits(
      static_cast<uint32_t>(this->value_ ^ other.value_));
}

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

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

constexpr inline void MyBits::operator^=(
    const ::llcpp::fidl::test::bits::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 |fit::nullopt|.
  constexpr inline static fit::optional<FlexibleBits> TryFrom(uint64_t value) {
    if (value & ~kMask.value_) {
      return fit::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 ::llcpp::fidl::test::bits::FlexibleBits FlexibleBits::SMALLEST =
    ::llcpp::fidl::test::bits::FlexibleBits(1u);
constexpr const ::llcpp::fidl::test::bits::FlexibleBits FlexibleBits::BIGGEST =
    ::llcpp::fidl::test::bits::FlexibleBits(9223372036854775808u);
constexpr const ::llcpp::fidl::test::bits::FlexibleBits FlexibleBits::kMask =
    ::llcpp::fidl::test::bits::FlexibleBits(9223372036854775809u);

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

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

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

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

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

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

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

}  // namespace bits
}  // namespace test
}  // namespace fidl
}  // namespace llcpp

namespace fidl {

template <>
struct IsFidlType<::llcpp::fidl::test::bits::StrictBits>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<::llcpp::fidl::test::bits::StrictBits>);
static_assert(sizeof(::llcpp::fidl::test::bits::StrictBits) ==
              sizeof(uint64_t));

template <>
struct IsFidlType<::llcpp::fidl::test::bits::MyBits> : public std::true_type {};
static_assert(std::is_standard_layout_v<::llcpp::fidl::test::bits::MyBits>);
static_assert(sizeof(::llcpp::fidl::test::bits::MyBits) == sizeof(uint32_t));

template <>
struct IsFidlType<::llcpp::fidl::test::bits::FlexibleBits>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::bits::FlexibleBits>);
static_assert(sizeof(::llcpp::fidl::test::bits::FlexibleBits) ==
              sizeof(uint64_t));

}  // namespace fidl

namespace llcpp {

namespace fidl {
namespace test {
namespace bits {}  // namespace bits
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
