// 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 CRUBIT_SUPPORT_RS_STD_CHAR_H_
#define CRUBIT_SUPPORT_RS_STD_CHAR_H_

#include <cstdint>
#include <optional>

#include "absl/base/optimization.h"

namespace rs_std {

// `rs_std::rs_char` is a C++ representation of the `char` type from Rust.
// `rust_builtin_type_abi_assumptions.md` documents the ABI compatiblity of
// these types.
class rs_char final {
 public:
  // Creates a default `rs_char` - one that represents ASCII NUL character.
  //
  // Providing the default constructor helps to ensure that the `value_` always
  // effectively stores a C++ equivalent of a well-defined Rust's `u32` value
  // (and never has a `MaybeUninit<u32>` value).  See also the P2723R1 proposal
  // for C++ which argues that zero-initialization may mitigate 10% of exploits.
  constexpr rs_char() = default;

  // Converts a `uint32_t` into a `rs_std::rs_char`.
  //
  // Note that not all valid `uint32_t`s are valid `rs_std::rs_char`s.
  // `from_u32` will return `std::nullopt` if the input is not a valid value for
  // a `rs_std::rs_char`.
  //
  // See also
  // https://doc.rust-lang.org/reference/behavior-considered-undefined.html
  // which documents that undefined behavior may result in presence of "A value
  // in a char which is a surrogate or above char::MAX."
  //
  // This function mimics Rust's `char::from_u32`:
  // https://doc.rust-lang.org/std/primitive.char.html#method.from_u32
  static constexpr std::optional<rs_char> from_u32(char32_t c) {
    // TODO(lukasza): Consider using slightly more efficient checks similarly
    // to how `char_try_from_u32` is implemented in Rust standard library.
    if (ABSL_PREDICT_FALSE(c > 0x10ffff)) {
      // Value greater than Rust's `char::MAX`:
      // https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.MAX
      return std::nullopt;
    }

    if (ABSL_PREDICT_FALSE(c >= 0xd800 && c <= 0xdfff)) {
      // Surrogate characters.
      return std::nullopt;
    }

    return from_u32_unchecked(c);
  }

  constexpr rs_char(const rs_char&) = default;
  constexpr rs_char& operator=(const rs_char&) = default;
  constexpr rs_char(rs_char&&) = default;
  constexpr rs_char& operator=(rs_char&&) = default;
  ~rs_char() = default;

  explicit constexpr operator std::uint32_t() const { return value_; }

  constexpr bool operator==(const rs_char& other) const {
    return value_ == other.value_;
  }
  constexpr bool operator!=(const rs_char& other) const {
    return value_ != other.value_;
  }
  constexpr bool operator<=(const rs_char& other) const {
    return value_ <= other.value_;
  }
  constexpr bool operator<(const rs_char& other) const {
    return value_ < other.value_;
  }
  constexpr bool operator>=(const rs_char& other) const {
    return value_ >= other.value_;
  }
  constexpr bool operator>(const rs_char& other) const {
    return value_ > other.value_;
  }

  // The highest valid code point a char can have, '\u{10FFFF}'.
  //
  // This constant mimics Rust's `char::MAX`:
  // https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.MAX
  static const rs_char MAX;

 private:
  // This function mimics Rust's `char::from_u32_unchecked`:
  // https://doc.rust-lang.org/std/primitive.char.html#method.from_u32_unchecked
  //
  // TODO(b/254095482): Figure out how to annotate/expose unsafe functions in
  // C++ and then make this method public.
  static constexpr rs_char from_u32_unchecked(std::uint32_t value) {
    return rs_char(value);
  }

  // Private constructor - intended to only be used from `from_u32_unchecked`.
  explicit constexpr rs_char(std::uint32_t value) : value_(value) {}

  // See "layout tests" comments in `char_test.cc` for explanation why
  // `char32_t` is not used.
  std::uint32_t value_ = '\0';
};

// Definition of `rs_char::MAX` - it can't be defined and declared within the
// `class` definition, because before `rs_char` is fully defined the compiler
// complains that `constexpr` variable cannot have non-literal type
// 'const rs_char'.
constexpr rs_char rs_char::MAX = rs_char::from_u32_unchecked(0x10ffff);

}  // namespace rs_std

#endif  // CRUBIT_SUPPORT_RS_STD_CHAR_H_
