// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
/// Checks if the integer value represents a UTF-16 leading surrogate.
/// Leading surrogates are in the range 0xD800 to 0xDBFF.
///
/// Example:
/// ```mbt check
/// test {
/// inspect((0xD800 : UInt16).is_leading_surrogate(), content="true")
/// inspect((0xDBFF : UInt16).is_leading_surrogate(), content="true")
/// inspect((0xDC00 : UInt16).is_leading_surrogate(), content="false")
/// inspect((0x41 : UInt16).is_leading_surrogate(), content="false") // 'A'
/// }
/// ```
pub fn UInt16::is_leading_surrogate(self : Self) -> Bool {
self >= 0xD800 && self <= 0xDBFF
}
///|
/// The identity constructor for `UInt16`, allowing values to be written using
/// constructor syntax, e.g. `UInt16(3)`.
///
/// Example:
///
/// ```mbt check
/// test {
/// inspect(UInt16(3), content="3")
/// }
/// ```
pub fn UInt16::UInt16(self : UInt16) -> UInt16 = "%identity"
///|
/// Checks if the integer value represents a UTF-16 trailing surrogate.
/// Trailing surrogates are in the range 0xDC00 to 0xDFFF.
///
/// Example:
/// ```mbt check
/// test {
/// inspect((0xDC00 : UInt16).is_trailing_surrogate(), content="true")
/// inspect((0xDFFF : UInt16).is_trailing_surrogate(), content="true")
/// inspect((0xD800 : UInt16).is_trailing_surrogate(), content="false")
/// inspect((0x41 : UInt16).is_trailing_surrogate(), content="false") // 'A'
/// }
/// ```
pub fn UInt16::is_trailing_surrogate(self : Self) -> Bool {
self >= 0xDC00 && self <= 0xDFFF
}
///|
/// Checks if the integer value represents any UTF-16 surrogate (leading or trailing).
/// Surrogates are in the range 0xD800 to 0xDFFF.
///
/// Example:
/// ```mbt check
/// test {
/// inspect((0xD800 : UInt16).is_surrogate(), content="true") // leading surrogate
/// inspect((0xDC00 : UInt16).is_surrogate(), content="true") // trailing surrogate
/// inspect((0xDFFF : UInt16).is_surrogate(), content="true") // trailing surrogate
/// inspect((0x41 : UInt16).is_surrogate(), content="false") // 'A'
/// }
/// ```
pub fn UInt16::is_surrogate(self : Self) -> Bool {
self >= 0xD800 && self <= 0xDFFF
}
///|
/// Unsafe variant of `to_char`.
#doc(hidden)
pub fn UInt16::unsafe_to_char(self : UInt16) -> Char {
self.to_int().unsafe_to_char()
}
///|
/// Convert to `char`.
pub fn UInt16::to_char(self : UInt16) -> Char? {
if self is (0..=0xD7FF) || self is (0xE000..<_) {
Some(self.unsafe_to_char())
} else {
None
}
}
///|
pub impl Add for UInt16 with fn add(self : UInt16, that : UInt16) -> UInt16 {
(self.to_int() + that.to_int()).to_uint16()
}
///|
pub impl Sub for UInt16 with fn sub(self : UInt16, that : UInt16) -> UInt16 {
(self.to_int() - that.to_int()).to_uint16()
}
///|
pub impl Mul for UInt16 with fn mul(self : UInt16, that : UInt16) -> UInt16 {
(self.to_int() * that.to_int()).to_uint16()
}
///|
pub impl Div for UInt16 with fn div(self : UInt16, that : UInt16) -> UInt16 {
(self.to_int() / that.to_int()).to_uint16()
}
///|
pub impl Mod for UInt16 with fn mod(self : UInt16, that : UInt16) -> UInt16 {
(self.to_int() % that.to_int()).to_uint16()
}
///|
pub impl Eq for UInt16 with fn equal(self, that) {
self.to_int() == that.to_int()
}
///|
pub impl Eq for UInt16 with fn not_equal(self, that) {
self.to_int() != that.to_int()
}
///|
pub impl Compare for UInt16 with fn compare(self, that) {
self.to_int().compare(that.to_int())
}
///|
pub impl Hash for UInt16 with fn hash_combine(self, hasher) {
hasher.combine_int(self.to_int())
}
///|
pub impl Shl for UInt16 with fn shl(self : UInt16, that : Int) -> UInt16 {
(self.to_int() << that).to_uint16()
}
///|
pub impl Shr for UInt16 with fn shr(self : UInt16, that : Int) -> UInt16 {
(self.to_int() >> that).to_uint16()
}
///|
pub impl BitOr for UInt16 with fn lor(self : UInt16, that : UInt16) -> UInt16 {
(self.to_int() | that.to_int()).to_uint16()
}
///|
pub impl BitAnd for UInt16 with fn land(self : UInt16, that : UInt16) -> UInt16 {
(self.to_int() & that.to_int()).to_uint16()
}
///|
pub impl BitXOr for UInt16 with fn lxor(self : UInt16, that : UInt16) -> UInt16 {
(self.to_int() ^ that.to_int()).to_uint16()
}
///|
/// Performs a bitwise NOT operation on a `UInt16` value, flipping every bit
/// within its 16-bit width.
///
/// Parameters:
///
/// - `self` : The `UInt16` value to apply the bitwise NOT operation on.
///
/// Returns the result of the bitwise NOT operation as a `UInt16`.
///
/// Example:
///
/// ```mbt check
/// test {
/// inspect((0x0000 : UInt16).lnot().to_int(), content="65535")
/// inspect((0xFFFF : UInt16).lnot().to_int(), content="0")
/// }
/// ```
pub fn UInt16::lnot(self : UInt16) -> UInt16 {
self.to_int().lnot().to_uint16()
}
///|
pub impl Default for UInt16 with fn default() {
0
}
///|
pub impl ToJson for UInt16 with fn to_json(self : UInt16) -> Json {
Json::number(self.to_int().to_double())
}
///|
/// Convert to `uint`.
pub fn UInt16::to_uint(self : UInt16) -> UInt {
self.to_int().reinterpret_as_uint()
}
///|
/// Convert to `uint64`.
pub fn UInt16::to_uint64(self : UInt16) -> UInt64 {
self.to_int().to_uint64()
}