// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef THIRD_PARTY_CRUBIT_SUPPORT_RS_STD_SLICEREF_H_
#define THIRD_PARTY_CRUBIT_SUPPORT_RS_STD_SLICEREF_H_

#include <concepts>
#include <cstddef>
#include <cstdint>
#include <span>  // NOLINT(build/c++20); <internal link>
#include <type_traits>

#include "crubit/support/annotations_internal.h"
#include "absl/base/attributes.h"
#include "absl/types/span.h"
#include "support/internal/check_no_mutable_aliasing.h"

namespace rs_std {

// `rs_std::SliceRef` is a C++ representation of a pointer or reference to a
// Rust slice. `SliceRef<int const>` is like a `&[c_int]` or `*const [c_int]`,
// while `SliceRef<int>` is like a `&mut [c_int]` or `*mut [c_int]`. `SliceRef`
// is trivially destructible, copyable, and moveable.
// `rust_builtin_type_abi_assumptions.md` documents the ABI compatibility of
// these types.
template <typename T>
class CRUBIT_INTERNAL_RUST_TYPE("&[]")
    ABSL_ATTRIBUTE_TRIVIAL_ABI SliceRef final {
 public:
  // Creates a default `SliceRef` - one that represents an empty slice.
  // To mirror slices in Rust, the data pointer is not null.
  constexpr SliceRef() noexcept : dangling_ptr_(alignof(T)), size_(0) {}

  // Style waiver for implicit conversions granted in cl/662479273.
  // NOLINTNEXTLINE(google-explicit-constructor)
  constexpr SliceRef(absl::Span<T> span) noexcept
      // Store a dangling pointer assuming `span` is empty-- we have to
      // initialize the union to something.
      : dangling_ptr_(alignof(T)), size_(span.size()) {
    // Store a valid pointer when `span` is not empty.
    if (!span.empty()) {
      ptr_ = span.data();
    }
  }

  // Re-use implicit conversions to `absl::Span`. Prevent a delegation circle
  // by excluding `absl::Span<T>` as the converted type.
  template <typename Container>
    requires(std::convertible_to<Container &&, absl::Span<T>> &&
             !std::is_same_v<Container, absl::Span<T>>)
  // NOLINTNEXTLINE(google-explicit-constructor)
  constexpr SliceRef(Container&& container) noexcept
      : SliceRef(
            // This is using `static_cast` instead of `absl::implicit_cast` to
            // avoid a dependency on `absl/base/casts.h`, which has a lot of
            // transitive dependencies. Doing so is safe, because the extra
            // guarantees are already checked by std::convertible_to.
            static_cast<absl::Span<T>>(std::forward<Container>(container))) {}

  // Also mirror explicit conversions from `absl::Span`.
  template <typename Container>
    requires(std::constructible_from<absl::Span<T>, Container &&> &&
             !std::convertible_to<Container &&, absl::Span<T>> &&
             !std::is_same_v<Container, absl::Span<T>>)
  constexpr explicit SliceRef(Container&& container) noexcept
      : SliceRef(absl::Span<T>(std::forward<Container>(container))) {}

  // NOLINTNEXTLINE(google-explicit-constructor)
  constexpr operator std::span<T>() const noexcept {
    return std::span<T>(size_ > 0 ? ptr_ : nullptr, size_);
  }

  constexpr SliceRef(const SliceRef&) = default;
  constexpr SliceRef& operator=(const SliceRef&) = default;
  constexpr SliceRef(SliceRef&&) noexcept = default;
  constexpr SliceRef& operator=(SliceRef&&) noexcept = default;
  ~SliceRef() = default;

  constexpr T* data() const noexcept { return size_ > 0 ? ptr_ : nullptr; }
  constexpr size_t size() const noexcept { return size_; }

  constexpr absl::Span<T> to_span() const noexcept {
    return absl::Span<T>(data(), size());
  }

 private:
  // Stick to the following invariants when changing the data member values:
  // (1) `ptr_` and `dangling_ptr_` must never be 0 (to mirror slices in Rust).
  // (2) if `size_ > 0` then `ptr_` is a valid pointer, otherwise
  //     `dangling_ptr_` is a dangling pointer.
  //
  // `dangling_ptr_` is never read from in C++, and `ptr_` must only ever be
  // read from when `size_ > 0`.
  union {
    T* ptr_;
    uintptr_t dangling_ptr_;
  };
  size_t size_;
};

}  // namespace rs_std

namespace crubit::internal {

template <typename T>
struct PtrLike<rs_std::SliceRef<T>> {
  static constexpr bool kIsConst = std::is_const_v<T>;
  static PtrData AsPtrData(rs_std::SliceRef<T> t) {
    uintptr_t start = reinterpret_cast<uintptr_t>(t.data());
    return {
        .start = start,
        .end = start + t.size() * sizeof(T),
    };
  }
};

}  // namespace crubit::internal

#endif  // THIRD_PARTY_CRUBIT_SUPPORT_RS_STD_SLICEREF_H_
