motoko 3.13.4 → 3.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"name":"core","version":"preview-0.6.0","files":{"Order.mo":{"content":"/// Utilities for `Order` (comparison between two values).\n\nimport Types \"Types\";\n\nmodule {\n\n /// A type to represent an order.\n public type Order = Types.Order;\n\n /// Check if an order is #less.\n public func isLess(order : Order) : Bool {\n switch order {\n case (#less) { true };\n case _ { false }\n }\n };\n\n /// Check if an order is #equal.\n public func isEqual(order : Order) : Bool {\n switch order {\n case (#equal) { true };\n case _ { false }\n }\n };\n\n /// Check if an order is #greater.\n public func isGreater(order : Order) : Bool {\n switch order {\n case (#greater) { true };\n case _ { false }\n }\n };\n\n /// Returns true if only if `order1` and `order2` are the same.\n public func equal(order1 : Order, order2 : Order) : Bool {\n switch (order1, order2) {\n case (#less, #less) { true };\n case (#equal, #equal) { true };\n case (#greater, #greater) { true };\n case _ { false }\n }\n };\n\n /// Returns an iterator that yields all possible `Order` values:\n /// `#less`, `#equal`, `#greater`.\n public func allValues() : Types.Iter<Order> {\n var nextState : ?Order = ?#less;\n {\n next = func() : ?Order {\n let state = nextState;\n switch state {\n case (?#less) { nextState := ?#equal };\n case (?#equal) { nextState := ?#greater };\n case (?#greater) { nextState := null };\n case (null) {}\n };\n state\n }\n }\n }\n\n}\n"},"Nat64.mo":{"content":"/// Utility functions on 64-bit unsigned integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Nat64 \"mo:core/Nat64\";\n/// ```\nimport Nat \"Nat\";\nimport Iter \"Iter\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// 64-bit natural numbers.\n public type Nat64 = Prim.Types.Nat64;\n\n /// Maximum 64-bit natural number. `2 ** 64 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.maxValue == (18446744073709551615 : Nat64);\n /// ```\n public let maxValue : Nat64 = 18446744073709551615;\n\n /// Converts a 64-bit unsigned integer to an unsigned integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.toNat(123) == (123 : Nat);\n /// ```\n public let toNat : Nat64 -> Nat = Prim.nat64ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 64-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.fromNat(123) == (123 : Nat64);\n /// ```\n public let fromNat : Nat -> Nat64 = Prim.natToNat64;\n\n /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.fromNat32(123) == (123 : Nat64);\n /// ```\n public func fromNat32(x : Nat32) : Nat64 {\n Prim.nat32ToNat64(x)\n };\n\n /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.toNat32(123) == (123 : Nat32);\n /// ```\n public func toNat32(x : Nat64) : Nat32 {\n Prim.nat64ToNat32(x)\n };\n\n /// Converts a signed integer with infinite precision to a 64-bit unsigned integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.fromIntWrap(123) == (123 : Nat64);\n /// ```\n public let fromIntWrap : Int -> Nat64 = Prim.intToNat64Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.toText(1234) == (\"1234\" : Text);\n /// ```\n public func toText(x : Nat64) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.min(123, 456) == (123 : Nat64);\n /// ```\n public func min(x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.max(123, 456) == (456 : Nat64);\n /// ```\n public func max(x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat64 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.equal(1, 1);\n /// assert (1 : Nat64) == (1 : Nat64);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Nat64 = 111;\n /// let b : Nat64 = 222;\n /// assert not Nat64.equal(a, b);\n /// ```\n public func equal(x : Nat64, y : Nat64) : Bool { x == y };\n\n /// Inequality function for Nat64 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.notEqual(1, 2);\n /// assert (1 : Nat64) != (2 : Nat64);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat64, y : Nat64) : Bool { x != y };\n\n /// \"Less than\" function for Nat64 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.less(1, 2);\n /// assert (1 : Nat64) < (2 : Nat64);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat64, y : Nat64) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat64 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.lessOrEqual(1, 2);\n /// assert (1 : Nat64) <= (2 : Nat64);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat64, y : Nat64) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat64 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.greater(2, 1);\n /// assert (2 : Nat64) > (1 : Nat64);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat64, y : Nat64) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat64 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.greaterOrEqual(2, 1);\n /// assert (2 : Nat64) >= (1 : Nat64);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat64, y : Nat64) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat64`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.compare(2, 3) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([2, 3, 1] : [Nat64], Nat64.compare) == [1, 2, 3];\n /// ```\n public func compare(x : Nat64, y : Nat64) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.add(1, 2) == 3;\n /// assert (1 : Nat64) + (2 : Nat64) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat64, Nat64>([2, 3, 1], 0, Nat64.add) == 6;\n /// ```\n public func add(x : Nat64, y : Nat64) : Nat64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.sub(3, 1) == 2;\n /// assert (3 : Nat64) - (1 : Nat64) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat64, Nat64>([2, 3, 1], 10, Nat64.sub) == 4;\n /// ```\n public func sub(x : Nat64, y : Nat64) : Nat64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.mul(2, 3) == 6;\n /// assert (2 : Nat64) * (3 : Nat64) == 6;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat64, Nat64>([2, 3, 1], 1, Nat64.mul) == 6;\n /// ```\n public func mul(x : Nat64, y : Nat64) : Nat64 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.div(6, 2) == 3;\n /// assert (6 : Nat64) / (2 : Nat64) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat64, y : Nat64) : Nat64 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.rem(6, 4) == 2;\n /// assert (6 : Nat64) % (4 : Nat64) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat64, y : Nat64) : Nat64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.pow(2, 3) == 8;\n /// assert (2 : Nat64) ** (3 : Nat64) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat64, y : Nat64) : Nat64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitnot(0) == 18446744073709551615;\n /// assert ^(0 : Nat64) == 18446744073709551615;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Nat64) : Nat64 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitand(1, 3) == 1;\n /// assert (1 : Nat64) & (3 : Nat64) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Nat64, y : Nat64) : Nat64 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitor(1, 3) == 3;\n /// assert (1 : Nat64) | (3 : Nat64) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Nat64, y : Nat64) : Nat64 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitxor(1, 3) == 2;\n /// assert (1 : Nat64) ^ (3 : Nat64) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Nat64, y : Nat64) : Nat64 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitshiftLeft(1, 3) == 8;\n /// assert (1 : Nat64) << (3 : Nat64) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Nat64, y : Nat64) : Nat64 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitshiftRight(8, 3) == 1;\n /// assert (8 : Nat64) >> (3 : Nat64) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Nat64, y : Nat64) : Nat64 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitrotLeft(1, 3) == 8;\n /// assert (1 : Nat64) <<> (3 : Nat64) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Nat64, y : Nat64) : Nat64 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitrotRight(8, 3) == 1;\n /// assert (8 : Nat64) <>> (3 : Nat64) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Nat64, y : Nat64) : Nat64 { x <>> y };\n\n /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bittest(5, 2);\n /// ```\n public func bittest(x : Nat64, p : Nat) : Bool {\n Prim.btstNat64(x, Prim.natToNat64(p))\n };\n\n /// Returns the value of setting bit `p mod 64` in `x` to `1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitset(5, 1) == 7;\n /// ```\n public func bitset(x : Nat64, p : Nat) : Nat64 {\n x | (1 << Prim.natToNat64(p))\n };\n\n /// Returns the value of clearing bit `p mod 64` in `x` to `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitclear(5, 2) == 1;\n /// ```\n public func bitclear(x : Nat64, p : Nat) : Nat64 {\n x & ^(1 << Prim.natToNat64(p))\n };\n\n /// Returns the value of flipping bit `p mod 64` in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitflip(5, 2) == 1;\n /// ```\n public func bitflip(x : Nat64, p : Nat) : Nat64 {\n x ^ (1 << Prim.natToNat64(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitcountNonZero(5) == 2;\n /// ```\n public let bitcountNonZero : (x : Nat64) -> Nat64 = Prim.popcntNat64;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitcountLeadingZero(5) == 61;\n /// ```\n public let bitcountLeadingZero : (x : Nat64) -> Nat64 = Prim.clzNat64;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.bitcountTrailingZero(16) == 4;\n /// ```\n public let bitcountTrailingZero : (x : Nat64) -> Nat64 = Prim.ctzNat64;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.explode 0xbb772266aa885511 == (187, 119, 34, 102, 170, 136, 85, 17);\n /// ```\n public let explode : (x : Nat64) -> (msb : Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeNat64;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.addWrap(Nat64.maxValue, 1) == 0;\n /// assert Nat64.maxValue +% (1 : Nat64) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Nat64, y : Nat64) : Nat64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.subWrap(0, 1) == 18446744073709551615;\n /// assert (0 : Nat64) -% (1 : Nat64) == 18446744073709551615;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Nat64, y : Nat64) : Nat64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.mulWrap(4294967296, 4294967296) == 0;\n /// assert (4294967296 : Nat64) *% (4294967296 : Nat64) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Nat64, y : Nat64) : Nat64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat64.powWrap(2, 64) == 0;\n /// assert (2 : Nat64) **% (64 : Nat64) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Nat64, y : Nat64) : Nat64 { x **% y };\n\n /// Returns an iterator over `Nat64` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat64.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat64.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Nat64, toExclusive : Nat64) : Iter.Iter<Nat64> {\n if (fromInclusive >= toExclusive) {\n Iter.empty()\n } else {\n object {\n var n = fromInclusive;\n public func next() : ?Nat64 {\n if (n == toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over `Nat64` values from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat64.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat64.rangeInclusive(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Nat64, to : Nat64) : Iter.Iter<Nat64> {\n if (from > to) {\n Iter.empty()\n } else {\n object {\n var n = from;\n var done = false;\n public func next() : ?Nat64 {\n if (done) {\n null\n } else {\n let result = n;\n if (n == to) {\n done := true\n } else {\n n += 1\n };\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over all Nat64 values, from 0 to maxValue.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat64.allValues();\n /// assert iter.next() == ?0;\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Nat64> {\n rangeInclusive(0, maxValue)\n };\n\n}\n"},"Array.mo":{"content":"/// Provides extended utility functions on immutable Arrays (values of type `[T]`).\n///\n/// Note the difference between mutable (`[var T]`) and immutable (`[T]`) arrays.\n/// Mutable arrays allow their elements to be modified after creation, while\n/// immutable arrays are fixed once created.\n///\n/// WARNING: If you are looking for a list that can grow and shrink in size,\n/// it is recommended you use `List` for those purposes.\n/// Arrays must be created with a fixed size.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Array \"mo:core/Array\";\n/// ```\n\nimport Order \"Order\";\nimport Result \"Result\";\nimport VarArray \"VarArray\";\nimport Option \"Option\";\nimport Types \"Types\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Creates an empty array (equivalent to `[]`).\n ///\n /// ```motoko include=import\n /// let array = Array.empty<Text>();\n /// assert array == [];\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func empty<T>() : [T] = [];\n\n /// Creates an array containing `item` repeated `size` times.\n ///\n /// ```motoko include=import\n /// let array = Array.repeat<Text>(\"Echo\", 3);\n /// assert array == [\"Echo\", \"Echo\", \"Echo\"];\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func repeat<T>(item : T, size : Nat) : [T] = Prim.Array_tabulate<T>(size, func _ = item);\n\n /// Creates an immutable array of size `size`. Each element at index i\n /// is created by applying `generator` to i.\n ///\n /// ```motoko include=import\n /// let array : [Nat] = Array.tabulate<Nat>(4, func i = i * 2);\n /// assert array == [0, 2, 4, 6];\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `generator` runs in O(1) time and space.\n public func tabulate<T>(size : Nat, generator : Nat -> T) : [T] = Prim.Array_tabulate<T>(size, generator);\n\n /// Transforms a mutable array into an immutable array.\n ///\n /// ```motoko include=import\n /// let varArray = [var 0, 1, 2];\n /// varArray[2] := 3;\n /// let array = Array.fromVarArray<Nat>(varArray);\n /// assert array == [0, 1, 3];\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func fromVarArray<T>(varArray : [var T]) : [T] = Prim.Array_tabulate<T>(varArray.size(), func i = varArray[i]);\n\n /// Transforms an immutable array into a mutable array.\n ///\n /// ```motoko include=import\n /// import VarArray \"mo:core/VarArray\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [0, 1, 2];\n /// let varArray = Array.toVarArray<Nat>(array);\n /// varArray[2] := 3;\n /// assert VarArray.equal(varArray, [var 0, 1, 3], Nat.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func toVarArray<T>(array : [T]) : [var T] {\n let size = array.size();\n if (size == 0) {\n return [var]\n };\n let newArray = Prim.Array_init<T>(size, array[0]);\n var i = 0;\n while (i < size) {\n newArray[i] := array[i];\n i += 1\n };\n newArray\n };\n\n /// Tests if two arrays contain equal values (i.e. they represent the same\n /// list of elements). Uses `equal` to compare elements in the arrays.\n ///\n /// ```motoko include=import\n /// // Use the equal function from the Nat module to compare Nats\n /// import {equal} \"mo:core/Nat\";\n ///\n /// let array1 = [0, 1, 2, 3];\n /// let array2 = [0, 1, 2, 3];\n /// assert Array.equal(array1, array2, equal);\n /// ```\n ///\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func equal<T>(array1 : [T], array2 : [T], equal : (T, T) -> Bool) : Bool {\n let size1 = array1.size();\n let size2 = array2.size();\n if (size1 != size2) {\n return false\n };\n var i = 0;\n while (i < size1) {\n if (not equal(array1[i], array2[i])) {\n return false\n };\n i += 1\n };\n true\n };\n\n /// Returns the first value in `array` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let array = [1, 9, 4, 8];\n /// let found = Array.find<Nat>(array, func x = x > 8);\n /// assert found == ?9;\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func find<T>(array : [T], predicate : T -> Bool) : ?T {\n for (element in array.vals()) {\n if (predicate element) {\n return ?element\n }\n };\n null\n };\n\n /// Returns the first index in `array` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let array = ['A', 'B', 'C', 'D'];\n /// let found = Array.findIndex<Char>(array, func(x) { x == 'C' });\n /// assert found == ?2;\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func findIndex<T>(array : [T], predicate : T -> Bool) : ?Nat {\n for ((index, element) in enumerate(array)) {\n if (predicate element) {\n return ?index\n }\n };\n null\n };\n\n /// Create a new array by concatenating the values of `array1` and `array2`.\n /// Note that `Array.concat` copies its arguments and has linear complexity.\n ///\n /// ```motoko include=import\n /// let array1 = [1, 2, 3];\n /// let array2 = [4, 5, 6];\n /// let result = Array.concat<Nat>(array1, array2);\n /// assert result == [1, 2, 3, 4, 5, 6];\n /// ```\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(size1 + size2)\n public func concat<T>(array1 : [T], array2 : [T]) : [T] {\n let size1 = array1.size();\n let size2 = array2.size();\n Prim.Array_tabulate<T>(\n size1 + size2,\n func i {\n if (i < size1) {\n array1[i]\n } else {\n array2[i - size1]\n }\n }\n )\n };\n\n /// Sorts the elements in the array according to `compare`.\n /// Sort is deterministic and stable.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [4, 2, 6];\n /// let sorted = Array.sort(array, Nat.compare);\n /// assert sorted == [2, 4, 6];\n /// ```\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func sort<T>(array : [T], compare : (T, T) -> Order.Order) : [T] {\n let varArray : [var T] = toVarArray(array);\n VarArray.sortInPlace(varArray, compare);\n fromVarArray(varArray)\n };\n\n /// Creates a new array by reversing the order of elements in `array`.\n ///\n /// ```motoko include=import\n /// let array = [10, 11, 12];\n /// let reversed = Array.reverse(array);\n /// assert reversed == [12, 11, 10];\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func reverse<T>(array : [T]) : [T] {\n let size = array.size();\n Prim.Array_tabulate<T>(size, func i = array[size - i - 1])\n };\n\n /// Calls `f` with each element in `array`.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n /// var sum = 0;\n /// let array = [0, 1, 2, 3];\n /// Array.forEach<Nat>(array, func(x) {\n /// sum += x;\n /// });\n /// assert sum == 6;\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func forEach<T>(array : [T], f : T -> ()) {\n for (item in array.vals()) {\n f(item)\n }\n };\n\n /// Creates a new array by applying `f` to each element in `array`. `f` \"maps\"\n /// each element it is applied to of type `X` to an element of type `Y`.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n /// let array1 = [0, 1, 2, 3];\n /// let array2 = Array.map<Nat, Nat>(array1, func x = x * 2);\n /// assert array2 == [0, 2, 4, 6];\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<T, R>(array : [T], f : T -> R) : [R] = Prim.Array_tabulate<R>(array.size(), func i = f(array[i]));\n\n /// Creates a new array by applying `predicate` to every element\n /// in `array`, retaining the elements for which `predicate` returns true.\n ///\n /// ```motoko include=import\n /// let array = [4, 2, 6, 1, 5];\n /// let evenElements = Array.filter<Nat>(array, func x = x % 2 == 0);\n /// assert evenElements == [4, 2, 6];\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func filter<T>(array : [T], f : T -> Bool) : [T] {\n var count = 0;\n let keep = Prim.Array_tabulate<Bool>(\n array.size(),\n func i {\n if (f(array[i])) {\n count += 1;\n true\n } else {\n false\n }\n }\n );\n var nextKeep = 0;\n Prim.Array_tabulate<T>(\n count,\n func _ {\n while (not keep[nextKeep]) {\n nextKeep += 1\n };\n nextKeep += 1;\n array[nextKeep - 1]\n }\n )\n };\n\n /// Creates a new array by applying `f` to each element in `array`,\n /// and keeping all non-null elements. The ordering is retained.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:core/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let newArray =\n /// Array.filterMap<Nat, Text>( // mapping from Nat to Text values\n /// array,\n /// func x = if (x == 0) { null } else { ?toText(100 / x) } // can't divide by 0, so return null\n /// );\n /// assert newArray == [\"25\", \"50\", \"100\"];\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func filterMap<T, R>(array : [T], f : T -> ?R) : [R] {\n var count = 0;\n let options = Prim.Array_tabulate<?R>(\n array.size(),\n func i {\n let result = f(array[i]);\n switch (result) {\n case (?element) {\n count += 1;\n result\n };\n case null {\n null\n }\n }\n }\n );\n\n var nextSome = 0;\n Prim.Array_tabulate<R>(\n count,\n func _ {\n while (Option.isNull(options[nextSome])) {\n nextSome += 1\n };\n nextSome += 1;\n switch (options[nextSome - 1]) {\n case (?element) element;\n case null {\n Prim.trap \"Array.filterMap(): malformed array\"\n }\n }\n }\n )\n };\n\n /// Creates a new array by applying `f` to each element in `array`.\n /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n /// returns an `#ok` containing the new array.\n ///\n /// ```motoko include=import\n /// let array = [4, 3, 2, 1, 0];\n /// // divide 100 by every element in the array\n /// let result = Array.mapResult<Nat, Nat, Text>(array, func x {\n /// if (x > 0) {\n /// #ok(100 / x)\n /// } else {\n /// #err \"Cannot divide by zero\"\n /// }\n /// });\n /// assert result == #err \"Cannot divide by zero\";\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapResult<T, R, E>(array : [T], f : T -> Result.Result<R, E>) : Result.Result<[R], E> {\n let size = array.size();\n\n var error : ?Result.Result<[R], E> = null;\n let results = Prim.Array_tabulate<?R>(\n size,\n func i {\n switch (f(array[i])) {\n case (#ok element) {\n ?element\n };\n case (#err e) {\n switch (error) {\n case null {\n // only take the first error\n error := ?(#err e)\n };\n case _ {}\n };\n null\n }\n }\n }\n );\n\n switch error {\n case null {\n // unpack the option\n #ok(\n map<?R, R>(\n results,\n func element {\n switch element {\n case (?element) {\n element\n };\n case null {\n Prim.trap \"Array.mapResult(): malformed array\"\n }\n }\n }\n )\n )\n };\n case (?error) {\n error\n }\n }\n };\n\n /// Creates a new array by applying `f` to each element in `array` and its index.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n /// let array = [10, 10, 10, 10];\n /// let newArray = Array.mapEntries<Nat, Nat>(array, func (x, i) = i * x);\n /// assert newArray == [0, 10, 20, 30];\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapEntries<T, R>(array : [T], f : (T, Nat) -> R) : [R] = Prim.Array_tabulate<R>(array.size(), func i = f(array[i], i));\n\n /// Creates a new array by applying `k` to each element in `array`,\n /// and concatenating the resulting arrays in order.\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4];\n /// let newArray = Array.flatMap<Nat, Int>(array, func x = [x, -x].values());\n /// assert newArray == [1, -1, 2, -2, 3, -3, 4, -4];\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `k` runs in O(1) time and space.\n public func flatMap<T, R>(array : [T], k : T -> Types.Iter<R>) : [R] {\n var flatSize = 0;\n let arrays = Prim.Array_tabulate<[R]>(\n array.size(),\n func i {\n let subArray = fromIter<R>(k(array[i]));\n flatSize += subArray.size();\n subArray\n }\n );\n\n // could replace with a call to flatten,\n // but it would require an extra pass (to compute `flatSize`)\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<R>(\n flatSize,\n func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n }\n )\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// ```motoko include=import\n /// import {add} \"mo:core/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let sum =\n /// Array.foldLeft<Nat, Nat>(\n /// array,\n /// 0, // start the sum at 0\n /// func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!\n /// );\n /// assert sum == 7;\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldLeft<T, A>(array : [T], base : A, combine : (A, T) -> A) : A {\n var acc = base;\n for (element in array.vals()) {\n acc := combine(acc, element)\n };\n acc\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:core/Nat\";\n ///\n /// let array = [1, 9, 4, 8];\n /// let bookTitle = Array.foldRight<Nat, Text>(array, \"\", func(x, acc) = toText(x) # acc);\n /// assert bookTitle == \"1948\";\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldRight<T, A>(array : [T], base : A, combine : (T, A) -> A) : A {\n var acc = base;\n let size = array.size();\n var i = size;\n while (i > 0) {\n i -= 1;\n acc := combine(array[i], acc)\n };\n acc\n };\n\n /// Combines an iterator of arrays into a single array. Retains the original\n /// ordering of the elements.\n ///\n /// Consider using `Array.flatten()` for better performance.\n ///\n /// ```motoko include=import\n /// let arrays = [[0, 1, 2], [2, 3], [], [4]];\n /// let joinedArray = Array.join<Nat>(arrays.values());\n /// assert joinedArray == [0, 1, 2, 2, 3, 4];\n /// ```\n ///\n /// Runtime: O(number of elements in array)\n ///\n /// Space: O(number of elements in array)\n public func join<T>(arrays : Types.Iter<[T]>) : [T] {\n flatten(fromIter(arrays))\n };\n\n /// Combines an array of arrays into a single array. Retains the original\n /// ordering of the elements.\n ///\n /// This has better performance compared to `Array.join()`.\n ///\n /// ```motoko include=import\n /// let arrays = [[0, 1, 2], [2, 3], [], [4]];\n /// let flatArray = Array.flatten<Nat>(arrays);\n /// assert flatArray == [0, 1, 2, 2, 3, 4];\n /// ```\n ///\n /// Runtime: O(number of elements in array)\n ///\n /// Space: O(number of elements in array)\n public func flatten<T>(arrays : [[T]]) : [T] {\n var flatSize = 0;\n for (subArray in arrays.vals()) {\n flatSize += subArray.size()\n };\n\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<T>(\n flatSize,\n func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n }\n )\n };\n\n /// Create an array containing a single value.\n ///\n /// ```motoko include=import\n /// let array = Array.singleton(2);\n /// assert array == [2];\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func singleton<T>(element : T) : [T] = [element];\n\n /// Returns the size of an array. Equivalent to `array.size()`.\n public func size<T>(array : [T]) : Nat = array.size();\n\n /// Returns whether an array is empty, i.e. contains zero elements.\n public func isEmpty<T>(array : [T]) : Bool = array.size() == 0;\n\n /// Converts an iterator to an array.\n public func fromIter<T>(iter : Types.Iter<T>) : [T] {\n var list : Types.Pure.List<T> = null;\n var size = 0;\n label l loop {\n switch (iter.next()) {\n case (?element) {\n list := ?(element, list);\n size += 1\n };\n case null { break l }\n }\n };\n if (size == 0) { return [] };\n let array = Prim.Array_init<T>(\n size,\n switch list {\n case (?(h, _)) h;\n case null {\n Prim.trap(\"Array.fromIter(): unreachable\")\n }\n }\n );\n var i = size : Nat;\n while (i > 0) {\n i -= 1;\n switch list {\n case (?(h, t)) {\n array[i] := h;\n list := t\n };\n case null {\n Prim.trap(\"Array.fromIter(): unreachable\")\n }\n }\n };\n Prim.Array_tabulate<T>(size, func i = array[i])\n };\n\n /// Returns an iterator (`Iter`) over the indices of `array`.\n /// An iterator provides a single method `next()`, which returns\n /// indices in order, or `null` when out of index to iterate over.\n ///\n /// Note: You can also use `array.keys()` instead of this function. See example\n /// below.\n ///\n /// ```motoko include=import\n /// let array = [10, 11, 12];\n ///\n /// var sum = 0;\n /// for (element in array.keys()) {\n /// sum += element;\n /// };\n /// assert sum == 3; // 0 + 1 + 2\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func keys<T>(array : [T]) : Types.Iter<Nat> = array.keys();\n\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n ///\n /// Note: You can also use `array.values()` instead of this function. See example\n /// below.\n ///\n /// ```motoko include=import\n /// let array = [10, 11, 12];\n ///\n /// var sum = 0;\n /// for (element in array.values()) {\n /// sum += element;\n /// };\n /// assert sum == 33;\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func values<T>(array : [T]) : Types.Iter<T> = array.vals();\n\n /// Iterator provides a single method `next()`, which returns\n /// pairs of (index, element) in order, or `null` when out of elements to iterate over.\n ///\n /// ```motoko include=import\n /// let array = [10, 11, 12];\n ///\n /// var sum = 0;\n /// for ((index, element) in Array.enumerate(array)) {\n /// sum += element;\n /// };\n /// assert sum == 33;\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func enumerate<T>(array : [T]) : Types.Iter<(Nat, T)> = object {\n let size = array.size();\n var index = 0;\n public func next() : ?(Nat, T) {\n if (index >= size) {\n return null\n };\n let i = index;\n index += 1;\n ?(i, array[i])\n }\n };\n\n /// Returns true if all elements in `array` satisfy the predicate function.\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4];\n /// assert Array.all<Nat>(array, func x = x > 0);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func all<T>(array : [T], predicate : T -> Bool) : Bool {\n for (element in array.vals()) {\n if (not predicate(element)) {\n return false\n }\n };\n true\n };\n\n /// Returns true if any element in `array` satisfies the predicate function.\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4];\n /// assert Array.any<Nat>(array, func x = x > 3);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func any<T>(array : [T], predicate : T -> Bool) : Bool {\n for (element in array.vals()) {\n if (predicate(element)) {\n return true\n }\n };\n false\n };\n\n /// Returns the index of the first `element` in the `array`.\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.indexOf<Char>('c', array, Char.equal) == ?0;\n /// assert Array.indexOf<Char>('f', array, Char.equal) == ?2;\n /// assert Array.indexOf<Char>('g', array, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size())\n ///\n /// Space: O(1)\n public func indexOf<T>(element : T, array : [T], equal : (T, T) -> Bool) : ?Nat = nextIndexOf<T>(element, array, 0, equal);\n\n /// Returns the index of the next occurence of `element` in the `array` starting from the `from` index (inclusive).\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.nextIndexOf<Char>('c', array, 0, Char.equal) == ?0;\n /// assert Array.nextIndexOf<Char>('f', array, 0, Char.equal) == ?2;\n /// assert Array.nextIndexOf<Char>('f', array, 2, Char.equal) == ?2;\n /// assert Array.nextIndexOf<Char>('f', array, 3, Char.equal) == ?3;\n /// assert Array.nextIndexOf<Char>('f', array, 4, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size())\n ///\n /// Space: O(1)\n public func nextIndexOf<T>(element : T, array : [T], fromInclusive : Nat, equal : (T, T) -> Bool) : ?Nat {\n var index = fromInclusive;\n let size = array.size();\n while (index < size) {\n if (equal(array[index], element)) {\n return ?index\n } else {\n index += 1\n }\n };\n null\n };\n\n /// Returns the index of the last `element` in the `array`.\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.lastIndexOf<Char>('c', array, Char.equal) == ?0;\n /// assert Array.lastIndexOf<Char>('f', array, Char.equal) == ?3;\n /// assert Array.lastIndexOf<Char>('e', array, Char.equal) == ?5;\n /// assert Array.lastIndexOf<Char>('g', array, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size())\n ///\n /// Space: O(1)\n public func lastIndexOf<T>(element : T, array : [T], equal : (T, T) -> Bool) : ?Nat = prevIndexOf<T>(element, array, array.size(), equal);\n\n /// Returns the index of the previous occurence of `element` in the `array` starting from the `from` index (exclusive).\n ///\n /// Negative indices are relative to the end of the array. For example, `-1` corresponds to the last element in the array.\n ///\n /// If the indices are out of bounds, they are clamped to the array bounds.\n /// If the first index is greater than the second, the function returns an empty iterator.\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.prevIndexOf<Char>('c', array, array.size(), Char.equal) == ?0;\n /// assert Array.prevIndexOf<Char>('e', array, array.size(), Char.equal) == ?5;\n /// assert Array.prevIndexOf<Char>('e', array, 5, Char.equal) == ?4;\n /// assert Array.prevIndexOf<Char>('e', array, 4, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size());\n /// Space: O(1);\n public func prevIndexOf<T>(element : T, array : [T], fromExclusive : Nat, equal : (T, T) -> Bool) : ?Nat {\n var i = fromExclusive;\n while (i > 0) {\n i -= 1;\n if (equal(array[i], element)) {\n return ?i\n }\n };\n null\n };\n\n /// Returns an iterator over a slice of `array` starting at `fromInclusive` up to (but not including) `toExclusive`.\n ///\n /// Negative indices are relative to the end of the array. For example, `-1` corresponds to the last element in the array.\n ///\n /// If the indices are out of bounds, they are clamped to the array bounds.\n /// If the first index is greater than the second, the function returns an empty iterator.\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4, 5];\n /// let iter1 = Array.range<Nat>(array, 3, array.size());\n /// assert iter1.next() == ?4;\n /// assert iter1.next() == ?5;\n /// assert iter1.next() == null;\n ///\n /// let iter2 = Array.range<Nat>(array, 3, -1);\n /// assert iter2.next() == ?4;\n /// assert iter2.next() == null;\n ///\n /// let iter3 = Array.range<Nat>(array, 0, 0);\n /// assert iter3.next() == null;\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func range<T>(array : [T], fromInclusive : Int, toExclusive : Int) : Types.Iter<T> {\n let size = array.size();\n // Convert negative indices to positive and handle bounds\n let startInt = if (fromInclusive < 0) {\n let s = size + fromInclusive;\n if (s < 0) { 0 } else { s }\n } else {\n if (fromInclusive > size) { size } else { fromInclusive }\n };\n let endInt = if (toExclusive < 0) {\n let e = size + toExclusive;\n if (e < 0) { 0 } else { e }\n } else {\n if (toExclusive > size) { size } else { toExclusive }\n };\n // Convert to Nat (always non-negative due to bounds checking above)\n let start = Prim.abs(startInt);\n let end = Prim.abs(endInt);\n object {\n var pos = start;\n public func next() : ?T {\n if (pos >= end) {\n null\n } else {\n let elem = array[pos];\n pos += 1;\n ?elem\n }\n }\n }\n };\n\n /// Returns a new array containing elements from `array` starting at index `fromInclusive` up to (but not including) index `toExclusive`.\n /// If the indices are out of bounds, they are clamped to the array bounds.\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4, 5];\n ///\n /// let slice1 = Array.sliceToArray<Nat>(array, 1, 4);\n /// assert slice1 == [2, 3, 4];\n ///\n /// let slice2 = Array.sliceToArray<Nat>(array, 1, -1);\n /// assert slice2 == [2, 3, 4];\n /// ```\n ///\n /// Runtime: O(toExclusive - fromInclusive)\n ///\n /// Space: O(toExclusive - fromInclusive)\n public func sliceToArray<T>(array : [T], fromInclusive : Int, toExclusive : Int) : [T] {\n let size = array.size();\n // Convert negative indices to positive and handle bounds\n let startInt = if (fromInclusive < 0) {\n let s = size + fromInclusive;\n if (s < 0) { 0 } else { s }\n } else {\n if (fromInclusive > size) { size } else { fromInclusive }\n };\n let endInt = if (toExclusive < 0) {\n let e = size + toExclusive;\n if (e < 0) { 0 } else { e }\n } else {\n if (toExclusive > size) { size } else { toExclusive }\n };\n // Convert to Nat (always non-negative due to bounds checking above)\n let start = Prim.abs(startInt);\n let end = Prim.abs(endInt);\n Prim.Array_tabulate<T>(end - start, func i = array[start + i])\n };\n\n /// Converts the array to its textual representation using `f` to convert each element to `Text`.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [1, 2, 3];\n /// let text = Array.toText<Nat>(array, Nat.toText);\n /// assert text == \"[1, 2, 3]\";\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func toText<T>(array : [T], f : T -> Text) : Text {\n let size = array.size();\n if (size == 0) { return \"[]\" };\n var text = \"[\";\n var i = 0;\n while (i < size) {\n if (i != 0) {\n text #= \", \"\n };\n text #= f(array[i]);\n i += 1\n };\n text #= \"]\";\n text\n };\n\n /// Compares two arrays using the provided comparison function for elements.\n /// Returns #less, #equal, or #greater if `array1` is less than, equal to,\n /// or greater than `array2` respectively.\n ///\n /// If arrays have different sizes but all elements up to the shorter length are equal,\n /// the shorter array is considered #less than the longer array.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array1 = [1, 2, 3];\n /// let array2 = [1, 2, 4];\n /// assert Array.compare<Nat>(array1, array2, Nat.compare) == #less;\n /// ```\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array3 = [1, 2];\n /// let array4 = [1, 2, 3];\n /// assert Array.compare<Nat>(array3, array4, Nat.compare) == #less;\n /// ```\n ///\n /// Runtime: O(min(size1, size2))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func compare<T>(array1 : [T], array2 : [T], compare : (T, T) -> Order.Order) : Order.Order {\n let size1 = array1.size();\n let size2 = array2.size();\n var i = 0;\n let minSize = if (size1 < size2) { size1 } else { size2 };\n while (i < minSize) {\n switch (compare(array1[i], array2[i])) {\n case (#less) { return #less };\n case (#greater) { return #greater };\n case (#equal) { i += 1 }\n }\n };\n if (size1 < size2) { #less } else if (size1 > size2) { #greater } else {\n #equal\n }\n };\n\n}\n"},"CertifiedData.mo":{"content":"/// Certified data.\n///\n/// The Internet Computer allows canister smart contracts to store a small amount of data during\n/// update method processing so that during query call processing, the canister can obtain\n/// a certificate about that data.\n///\n/// This module provides a _low-level_ interface to this API, aimed at advanced\n/// users and library implementors. See the Internet Computer Functional\n/// Specification and corresponding documentation for how to use this to make query\n/// calls to your canister tamperproof.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Set the certified data.\n ///\n /// Must be called from an update method, else traps.\n /// Must be passed a blob of at most 32 bytes, else traps.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import CertifiedData \"mo:core/CertifiedData\";\n /// import Blob \"mo:core/Blob\";\n ///\n /// // Must be in an update call\n ///\n /// let array : [Nat8] = [1, 2, 3];\n /// let blob = Blob.fromArray(array);\n /// CertifiedData.set(blob);\n /// ```\n ///\n /// See a full example on how to use certified variables here: https://github.com/dfinity/examples/tree/master/motoko/cert-var\n ///\n public let set : (data : Blob) -> () = Prim.setCertifiedData;\n\n /// Gets a certificate\n ///\n /// Returns `null` if no certificate is available, e.g. when processing an\n /// update call or inter-canister call. This returns a non-`null` value only\n /// when processing a query call.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import CertifiedData \"mo:core/CertifiedData\";\n /// // Must be in a query call\n ///\n /// CertifiedData.getCertificate();\n /// ```\n /// See a full example on how to use certified variables here: https://github.com/dfinity/examples/tree/master/motoko/cert-var\n ///\n public let getCertificate : () -> ?Blob = Prim.getCertificate;\n\n}\n"},"InternetComputer.mo":{"content":"/// Low-level interface to the Internet Computer.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Calls `canister`'s update or query function, `name`, with the binary contents of `data` as IC argument.\n /// Returns the response to the call, an IC _reply_ or _reject_, as a Motoko future:\n ///\n /// * The message data of an IC reply determines the binary contents of `reply`.\n /// * The error code and textual message data of an IC reject determines the future's `Error` value.\n ///\n /// Note: `call` is an asynchronous function and can only be applied in an asynchronous context.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import IC \"mo:core/InternetComputer\";\n /// import Principal \"mo:core/Principal\";\n ///\n /// persistent actor {\n /// type OutputType = { decimals : Nat32 };\n ///\n /// public func example() : async ?OutputType {\n /// let ledger = Principal.fromText(\"ryjl3-tyaaa-aaaaa-aaaba-cai\");\n /// let method = \"decimals\";\n /// let input = ();\n ///\n /// let rawReply = await IC.call(ledger, method, to_candid (input)); // serialized Candid\n /// let output : ?OutputType = from_candid (rawReply);\n /// assert output == ?{ decimals = 8 };\n /// output\n /// }\n /// }\n /// ```\n ///\n /// [Learn more about Candid serialization](https://internetcomputer.org/docs/current/motoko/main/reference/language-manual#candid-serialization)\n public let call : (canister : Principal, name : Text, data : Blob) -> async (reply : Blob) = Prim.call_raw;\n\n /// `isReplicated` is true for update messages and for queries that passed through consensus.\n public let isReplicated : () -> Bool = Prim.isReplicatedExecution;\n\n /// Given computation, `comp`, counts the number of actual and (for IC system calls) notional WebAssembly\n /// instructions performed during the execution of `comp()`.\n ///\n /// More precisely, returns the difference between the state of the IC instruction counter (_performance counter_ `0`) before and after executing `comp()`\n /// (see [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter)).\n ///\n /// NB: `countInstructions(comp)` will _not_ account for any deferred garbage collection costs incurred by `comp()`.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import IC \"mo:core/InternetComputer\";\n ///\n /// let count = IC.countInstructions(func() {\n /// // ...\n /// });\n /// ```\n public func countInstructions(comp : () -> ()) : Nat64 {\n let init = Prim.performanceCounter(0);\n let pre = Prim.performanceCounter(0);\n comp();\n let post = Prim.performanceCounter(0);\n // performance_counter costs around 200 extra instructions; we perform an empty measurement to decide the overhead\n let overhead = pre - init;\n post - pre - overhead\n };\n\n /// Returns the current value of IC _performance counter_ `counter`.\n ///\n /// * Counter `0` is the _current execution instruction counter_, counting instructions only since the beginning of the current IC message.\n /// This counter is reset to value `0` on shared function entry and every `await`.\n /// It is therefore only suitable for measuring the cost of synchronous code.\n ///\n /// * Counter `1` is the _call context instruction counter_ for the current shared function call.\n /// For replicated message executing, this excludes the cost of nested IC calls (even to the current canister).\n /// For non-replicated messages, such as composite queries, it includes the cost of nested calls.\n /// The current value of this counter is preserved across `awaits` (unlike counter `0`).\n ///\n /// * The function (currently) traps if `counter` >= 2.\n ///\n /// Consult [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter) for details.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import IC \"mo:core/InternetComputer\";\n ///\n /// let c1 = IC.performanceCounter(1);\n /// // ...\n /// let diff : Nat64 = IC.performanceCounter(1) - c1;\n /// ```\n public let performanceCounter : (counter : Nat32) -> (value : Nat64) = Prim.performanceCounter;\n\n /// Returns the time (in nanoseconds from the epoch start) by when the update message should\n /// reply to the best effort message so that it can be received by the requesting canister.\n /// Queries and unbounded-time update messages return null.\n public func replyDeadline() : ?Nat {\n let raw = Prim.replyDeadline();\n if (raw == 0) null else ?Prim.nat64ToNat(raw)\n };\n\n}\n"},"Nat32.mo":{"content":"/// Utility functions on 32-bit unsigned integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Nat32 \"mo:core/Nat32\";\n/// ```\nimport Nat \"Nat\";\nimport Iter \"Iter\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// 32-bit natural numbers.\n public type Nat32 = Prim.Types.Nat32;\n\n /// Maximum 32-bit natural number. `2 ** 32 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.maxValue == (4294967295 : Nat32);\n /// ```\n public let maxValue : Nat32 = 4294967295;\n\n /// Converts a 32-bit unsigned integer to an unsigned integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.toNat(123) == (123 : Nat);\n /// ```\n public let toNat : Nat32 -> Nat = Prim.nat32ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 32-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.fromNat(123) == (123 : Nat32);\n /// ```\n public let fromNat : Nat -> Nat32 = Prim.natToNat32;\n\n /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.fromNat16(123) == (123 : Nat32);\n /// ```\n public func fromNat16(x : Nat16) : Nat32 {\n Prim.nat16ToNat32(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.toNat16(123) == (123 : Nat16);\n /// ```\n public func toNat16(x : Nat32) : Nat16 {\n Prim.nat32ToNat16(x)\n };\n\n /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.fromNat64(123) == (123 : Nat32);\n /// ```\n public func fromNat64(x : Nat64) : Nat32 {\n Prim.nat64ToNat32(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.toNat64(123) == (123 : Nat64);\n /// ```\n public func toNat64(x : Nat32) : Nat64 {\n Prim.nat32ToNat64(x)\n };\n\n /// Converts a signed integer with infinite precision to a 32-bit unsigned integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.fromIntWrap(123) == (123 : Nat32);\n /// ```\n public let fromIntWrap : Int -> Nat32 = Prim.intToNat32Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.toText(1234) == (\"1234\" : Text);\n /// ```\n public func toText(x : Nat32) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.min(123, 456) == (123 : Nat32);\n /// ```\n public func min(x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.max(123, 456) == (456 : Nat32);\n /// ```\n public func max(x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat32 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.equal(1, 1);\n /// assert (1 : Nat32) == (1 : Nat32);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Nat32 = 111;\n /// let b : Nat32 = 222;\n /// assert not Nat32.equal(a, b);\n /// ```\n public func equal(x : Nat32, y : Nat32) : Bool { x == y };\n\n /// Inequality function for Nat32 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.notEqual(1, 2);\n /// assert (1 : Nat32) != (2 : Nat32);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat32, y : Nat32) : Bool { x != y };\n\n /// \"Less than\" function for Nat32 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.less(1, 2);\n /// assert (1 : Nat32) < (2 : Nat32);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat32, y : Nat32) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat32 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.lessOrEqual(1, 2);\n /// assert (1 : Nat32) <= (2 : Nat32);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat32, y : Nat32) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat32 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.greater(2, 1);\n /// assert (2 : Nat32) > (1 : Nat32);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat32, y : Nat32) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat32 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.greaterOrEqual(2, 1);\n /// assert (2 : Nat32) >= (1 : Nat32);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat32, y : Nat32) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat32`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.compare(2, 3) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([2, 3, 1] : [Nat32], Nat32.compare) == [1, 2, 3];\n /// ```\n public func compare(x : Nat32, y : Nat32) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.add(1, 2) == 3;\n /// assert (1 : Nat32) + (2 : Nat32) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat32, Nat32>([2, 3, 1], 0, Nat32.add) == 6;\n /// ```\n public func add(x : Nat32, y : Nat32) : Nat32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.sub(2, 1) == 1;\n /// assert (2 : Nat32) - (1 : Nat32) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat32, Nat32>([2, 3, 1], 20, Nat32.sub) == 14;\n /// ```\n public func sub(x : Nat32, y : Nat32) : Nat32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.mul(2, 3) == 6;\n /// assert (2 : Nat32) * (3 : Nat32) == 6;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat32, Nat32>([2, 3, 1], 1, Nat32.mul) == 6;\n /// ```\n public func mul(x : Nat32, y : Nat32) : Nat32 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.div(6, 2) == 3;\n /// assert (6 : Nat32) / (2 : Nat32) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat32, y : Nat32) : Nat32 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.rem(6, 4) == 2;\n /// assert (6 : Nat32) % (4 : Nat32) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat32, y : Nat32) : Nat32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.pow(2, 3) == 8;\n /// assert (2 : Nat32) ** (3 : Nat32) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat32, y : Nat32) : Nat32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitnot(0) == 4294967295;\n /// assert ^(0 : Nat32) == 4294967295;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Nat32) : Nat32 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitand(1, 3) == 1;\n /// assert (1 : Nat32) & (3 : Nat32) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Nat32, y : Nat32) : Nat32 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitor(1, 3) == 3;\n /// assert (1 : Nat32) | (3 : Nat32) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Nat32, y : Nat32) : Nat32 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitxor(1, 3) == 2;\n /// assert (1 : Nat32) ^ (3 : Nat32) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Nat32, y : Nat32) : Nat32 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitshiftLeft(1, 3) == 8;\n /// assert (1 : Nat32) << (3 : Nat32) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Nat32, y : Nat32) : Nat32 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitshiftRight(8, 3) == 1;\n /// assert (8 : Nat32) >> (3 : Nat32) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Nat32, y : Nat32) : Nat32 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitrotLeft(1, 3) == 8;\n /// assert (1 : Nat32) <<> (3 : Nat32) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Nat32, y : Nat32) : Nat32 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitrotRight(1, 1) == 2147483648;\n /// assert (1 : Nat32) <>> (1 : Nat32) == 2147483648;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Nat32, y : Nat32) : Nat32 { x <>> y };\n\n /// Returns the value of bit `p mod 32` in `x`, `(x & 2^(p mod 32)) == 2^(p mod 32)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bittest(5, 2);\n /// ```\n public func bittest(x : Nat32, p : Nat) : Bool {\n Prim.btstNat32(x, Prim.natToNat32(p))\n };\n\n /// Returns the value of setting bit `p mod 32` in `x` to `1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitset(5, 1) == 7;\n /// ```\n public func bitset(x : Nat32, p : Nat) : Nat32 {\n x | (1 << Prim.natToNat32(p))\n };\n\n /// Returns the value of clearing bit `p mod 32` in `x` to `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitclear(5, 2) == 1;\n /// ```\n public func bitclear(x : Nat32, p : Nat) : Nat32 {\n x & ^(1 << Prim.natToNat32(p))\n };\n\n /// Returns the value of flipping bit `p mod 32` in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitflip(5, 2) == 1;\n /// ```\n public func bitflip(x : Nat32, p : Nat) : Nat32 {\n x ^ (1 << Prim.natToNat32(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitcountNonZero(5) == 2;\n /// ```\n public let bitcountNonZero : (x : Nat32) -> Nat32 = Prim.popcntNat32;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitcountLeadingZero(5) == 29;\n /// ```\n public let bitcountLeadingZero : (x : Nat32) -> Nat32 = Prim.clzNat32;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.bitcountTrailingZero(16) == 4;\n /// ```\n public let bitcountTrailingZero : (x : Nat32) -> Nat32 = Prim.ctzNat32;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.explode 0xaa885511 == (170, 136, 85, 17);\n /// ```\n public let explode : (x : Nat32) -> (msb : Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeNat32;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.addWrap(4294967295, 1) == 0;\n /// assert (4294967295 : Nat32) +% (1 : Nat32) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Nat32, y : Nat32) : Nat32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.subWrap(0, 1) == 4294967295;\n /// assert (0 : Nat32) -% (1 : Nat32) == 4294967295;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Nat32, y : Nat32) : Nat32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.mulWrap(2147483648, 2) == 0;\n /// assert (2147483648 : Nat32) *% (2 : Nat32) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Nat32, y : Nat32) : Nat32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat32.powWrap(2, 32) == 0;\n /// assert (2 : Nat32) **% (32 : Nat32) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Nat32, y : Nat32) : Nat32 { x **% y };\n\n /// Returns an iterator over `Nat32` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat32.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat32.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Nat32, toExclusive : Nat32) : Iter.Iter<Nat32> {\n if (fromInclusive >= toExclusive) {\n Iter.empty()\n } else {\n object {\n var n = fromInclusive;\n public func next() : ?Nat32 {\n if (n == toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over `Nat32` values from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat32.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat32.rangeInclusive(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Nat32, to : Nat32) : Iter.Iter<Nat32> {\n if (from > to) {\n Iter.empty()\n } else {\n object {\n var n = from;\n var done = false;\n public func next() : ?Nat32 {\n if (done) {\n null\n } else {\n let result = n;\n if (n == to) {\n done := true\n } else {\n n += 1\n };\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over all Nat32 values, from 0 to maxValue.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat32.allValues();\n /// assert iter.next() == ?0;\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Nat32> {\n rangeInclusive(0, maxValue)\n };\n\n}\n"},"internal/PRNG.mo":{"content":"/// Collection of pseudo-random number generators\n///\n/// The algorithms deliver deterministic statistical randomness,\n/// not cryptographic randomness.\n///\n/// Algorithm 1: 128-bit Seiran PRNG\n/// See: https://github.com/andanteyk/prng-seiran\n///\n/// Algorithm 2: SFC64 and SFC32 (Chris Doty-Humphrey’s Small Fast Chaotic PRNG)\n/// See: https://numpy.org/doc/stable/reference/random/bit_generators/sfc64.html\n///\n/// Copyright: 2023 MR Research AG\n/// Main author: react0r-com\n/// Contributors: Timo Hanke (timohanke)\nimport Nat \"../Nat\";\n\nmodule {\n /// Constructs an SFC 64-bit generator.\n /// The recommended constructor arguments are: 24, 11, 3.\n ///\n /// Example:\n /// ```motoko\n /// import PRNG \"mo:core/internal/PRNG\";\n ///\n /// let rng = PRNG.SFC64(24, 11, 3);\n /// ```\n /// For convenience, the function `SFC64a()` returns a generator constructed\n /// with the recommended parameter set (24, 11, 3).\n public class SFC64(p : Nat64, q : Nat64, r : Nat64) {\n // state\n var a : Nat64 = 0;\n var b : Nat64 = 0;\n var c : Nat64 = 0;\n var d : Nat64 = 0;\n\n /// Initializes the PRNG state with a particular seed\n ///\n /// Example:\n /// ```motoko\n public func init(seed : Nat64) = init3(seed, seed, seed);\n\n /// Initializes the PRNG state with a hardcoded seed.\n /// No argument is required.\n ///\n /// Example:\n public func initPre() = init(0xcafef00dbeef5eed);\n\n /// Initializes the PRNG state with three state variables\n ///\n /// Example:\n public func init3(seed1 : Nat64, seed2 : Nat64, seed3 : Nat64) {\n a := seed1;\n b := seed2;\n c := seed3;\n d := 1;\n\n for (_ in Nat.range(0, 11)) ignore next()\n };\n\n /// Returns one output and advances the PRNG's state\n ///\n /// Example:\n public func next() : Nat64 {\n let tmp = a +% b +% d;\n a := b ^ (b >> q);\n b := c +% (c << r);\n c := (c <<> p) +% tmp;\n d +%= 1;\n tmp\n }\n };\n\n /// SFC64a is the same as numpy.\n /// See: [sfc64_next()](https:///github.com/numpy/numpy/blob/b6d372c25fab5033b828dd9de551eb0b7fa55800/numpy/random/src/sfc64/sfc64.h#L28)\n public func sfc64a() : SFC64 { SFC64(24, 11, 3) }\n}\n"},"Error.mo":{"content":"/// Error values and inspection.\n///\n/// The `Error` type is the argument to `throw`, parameter of `catch`.\n/// The `Error` type is opaque.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Error value resulting from `async` computations\n public type Error = Prim.Types.Error;\n\n /// Error code to classify different kinds of user and system errors:\n /// ```motoko\n /// type ErrorCode = {\n /// // Fatal error.\n /// #system_fatal;\n /// // Transient error.\n /// #system_transient;\n /// // Response unknown due to missed deadline.\n /// #system_unknown;\n /// // Destination invalid.\n /// #destination_invalid;\n /// // Explicit reject by canister code.\n /// #canister_reject;\n /// // Canister trapped.\n /// #canister_error;\n /// // Future error code (with unrecognized numeric code).\n /// #future : Nat32;\n /// // Error issuing inter-canister call\n /// // (indicating destination queue full or freezing threshold crossed).\n /// #call_error : { err_code : Nat32 }\n /// };\n /// ```\n public type ErrorCode = Prim.ErrorCode;\n\n /// Create an error from the message with the code `#canister_reject`.\n ///\n /// Example:\n /// ```motoko\n /// import Error \"mo:core/Error\";\n ///\n /// Error.reject(\"Example error\") // can be used as throw argument\n /// ```\n public let reject : (message : Text) -> Error = Prim.error;\n\n /// Returns the code of an error.\n ///\n /// Example:\n /// ```motoko\n /// import Error \"mo:core/Error\";\n ///\n /// let error = Error.reject(\"Example error\");\n /// Error.code(error) // #canister_reject\n /// ```\n public let code : (error : Error) -> ErrorCode = Prim.errorCode;\n\n /// Returns the message of an error.\n ///\n /// Example:\n /// ```motoko\n /// import Error \"mo:core/Error\";\n ///\n /// let error = Error.reject(\"Example error\");\n /// Error.message(error) // \"Example error\"\n /// ```\n public let message : (error : Error) -> Text = Prim.errorMessage;\n\n /// Returns whether retrying to send a message may result in success.\n ///\n /// Example:\n /// ```motoko\n /// import Error \"mo:core/Error\";\n /// import Debug \"mo:core/Debug\";\n ///\n /// persistent actor {\n /// type CallableActor = actor {\n /// call : () -> async ()\n /// };\n ///\n /// public func example(callableActor : CallableActor) {\n /// try {\n /// await (with timeout = 3) callableActor.call();\n /// }\n /// catch e {\n /// if (Error.isRetryPossible e) {\n /// Debug.print(Error.message e);\n /// }\n /// }\n /// }\n /// }\n ///\n /// ```\n public func isRetryPossible(error : Error) : Bool = switch (code error) {\n case (#system_unknown or #system_transient) true;\n case _ false\n };\n\n}\n"},"internal/BTreeHelper.mo":{"content":"// Implementation is courtesy of Byron Becker.\n// Source: https://github.com/canscale/StableHeapBTreeMap\n// Copyright (c) 2022 Byron Becker.\n// Distributed under Apache 2.0 license.\n// With adjustments by the Motoko team.\n\nimport VarArray \"../VarArray\";\nimport Runtime \"../Runtime\";\n\nmodule {\n /// Inserts an element into a mutable array at a specific index, shifting all other elements over\n ///\n /// Parameters:\n ///\n /// array - the array being inserted into\n /// insertElement - the element being inserted\n /// insertIndex - the index at which the element will be inserted\n /// currentLastElementIndex - the index of last **non-null** element in the array (used to start shifting elements over)\n ///\n /// Note: This assumes that there are nulls at the end of the array and that the array is not full.\n /// If the array is already full, this function will overflow the array size when attempting to\n /// insert and will cause the cansiter to trap\n public func insertAtPosition<T>(array : [var ?T], insertElement : ?T, insertIndex : Nat, currentLastElementIndex : Nat) {\n // if inserting at the end of the array, don't need to do any shifting and can just insert and return\n if (insertIndex == currentLastElementIndex + 1) {\n array[insertIndex] := insertElement;\n return\n };\n\n // otherwise, need to shift all of the elements at the end of the array over one by one until\n // the insert index is hit.\n var j = currentLastElementIndex;\n label l loop {\n array[j + 1] := array[j];\n if (j == insertIndex) {\n array[j] := insertElement;\n break l\n };\n\n j -= 1\n }\n };\n\n /// Splits the array into two halves as if the insert has occured, omitting the middle element and returning it so that it can\n /// be promoted to the parent internal node. This is used when inserting an element into an array of elements that\n /// is already full.\n ///\n /// Note: Use only when inserting an element into a FULL array & promoting the resulting midpoint element.\n /// This is NOT the same as just splitting this array!\n ///\n /// Parameters:\n ///\n /// array - the array being split\n /// insertElement - the element being inserted\n /// insertIndex - the position/index that the insertElement should be inserted\n public func insertOneAtIndexAndSplitArray<T>(array : [var ?T], insertElement : T, insertIndex : Nat) : ([var ?T], T, [var ?T]) {\n // split at the BTree order / 2\n let splitIndex = (array.size() + 1) / 2;\n // this function assumes the the splitIndex is in the middle of the kvs array - trap otherwise\n if (splitIndex > array.size()) { assert false };\n\n let leftSplit = if (insertIndex < splitIndex) {\n VarArray.tabulate<?T>(\n array.size(),\n func(i) {\n // if below the split index\n if (i < splitIndex) {\n // if below the insert index, copy over\n if (i < insertIndex) { array[i] }\n // if less than the insert index, copy over the previous element (since the inserted element has taken up 1 extra slot)\n else if (i > insertIndex) { array[i - 1] }\n // if equal to the insert index add the element to be inserted to the left split\n else { ?insertElement }\n } else { null }\n }\n )\n }\n // index >= splitIndex\n else {\n VarArray.tabulate<?T>(\n array.size(),\n func(i) {\n // right biased splitting\n if (i < splitIndex) { array[i] } else { null }\n }\n )\n };\n\n let (rightSplit, middleElement) : ([var ?T], ?T) =\n // if insert > split index, inserted element will be inserted into the right split\n if (insertIndex > splitIndex) {\n let right = VarArray.tabulate<?T>(\n array.size(),\n func(i) {\n let adjIndex = i + splitIndex + 1; // + 1 accounts for the fact that the split element was part of the original array\n if (adjIndex <= array.size()) {\n if (adjIndex < insertIndex) { array[adjIndex] } else if (adjIndex > insertIndex) {\n array[adjIndex - 1]\n } else { ?insertElement }\n } else { null }\n }\n );\n (right, array[splitIndex])\n }\n // if inserted element was placed in the left split\n else if (insertIndex < splitIndex) {\n let right = VarArray.tabulate<?T>(\n array.size(),\n func(i) {\n let adjIndex = i + splitIndex;\n if (adjIndex < array.size()) { array[adjIndex] } else { null }\n }\n );\n (right, array[splitIndex - 1])\n }\n // insertIndex == splitIndex\n else {\n let right = VarArray.tabulate<?T>(\n array.size(),\n func(i) {\n let adjIndex = i + splitIndex;\n if (adjIndex < array.size()) { array[adjIndex] } else { null }\n }\n );\n (right, ?insertElement)\n };\n\n switch (middleElement) {\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In internal/BTreeHelper: insertOneAtIndexAndSplitArray, middle element of a BTree node should never be null\")\n };\n case (?el) { (leftSplit, el, rightSplit) }\n }\n };\n\n /// Context of use: This function is used after inserting a child node into the full child of an internal node that is also full.\n /// From the insertion, the full child is rebalanced and split, and then since the internal node is full, when replacing the two\n /// halves of that rebalanced child into the internal node's children this causes a second split. This function takes in the\n /// internal node's children, and the \"rebalanced\" split child nodes, as well as the index at which the \"rebalanced\" left and right\n /// child will be inserted and replaces the original child with those two halves\n ///\n /// Note: Use when inserting two successive elements into a FULL array and splitting that array.\n /// This is NOT the same as just splitting this array!\n ///\n /// Assumptions: this function also assumes that the children array is full (no nulls)\n ///\n /// Parameters:\n ///\n /// children - the internal node's children array being split\n /// rebalancedChildIndex - the index used to mark where the rebalanced left and right children will be inserted\n /// leftChildInsert - the rebalanced left child being inserted\n /// rightChildInsert - the rebalanced right child being inserted\n public func splitArrayAndInsertTwo<T>(children : [var ?T], rebalancedChildIndex : Nat, leftChildInsert : T, rightChildInsert : T) : ([var ?T], [var ?T]) {\n let splitIndex = children.size() / 2;\n\n let leftRebalancedChildren = VarArray.tabulate<?T>(\n children.size(),\n func(i) {\n // only insert elements up to the split index and fill the rest of the children with nulls\n if (i <= splitIndex) {\n if (i < rebalancedChildIndex) { children[i] }\n // insert the left and right rebalanced child halves if the rebalancedChildIndex comes before the splitIndex\n else if (i == rebalancedChildIndex) {\n ?leftChildInsert\n } else if (i == rebalancedChildIndex + 1) { ?rightChildInsert } else {\n children[i - 1]\n } // i > rebalancedChildIndex\n } else { null }\n }\n );\n\n let rightRebalanceChildren : [var ?T] =\n // Case 1: if both left and right rebalanced halves were inserted into the left child can just go from the split index onwards\n if (rebalancedChildIndex + 1 <= splitIndex) {\n VarArray.tabulate<?T>(\n children.size(),\n func(i) {\n let adjIndex = i + splitIndex;\n if (adjIndex < children.size()) { children[adjIndex] } else { null }\n }\n )\n }\n // Case 2: if both left and right rebalanced halves will be inserted into the right child\n else if (rebalancedChildIndex > splitIndex) {\n var rebalanceOffset = 0;\n VarArray.tabulate<?T>(\n children.size(),\n func(i) {\n let adjIndex = i + splitIndex + 1;\n if (adjIndex == rebalancedChildIndex) { ?leftChildInsert } else if (adjIndex == rebalancedChildIndex + 1) {\n rebalanceOffset := 1; // after inserting both rebalanced children, any elements coming after are from the previous index\n ?rightChildInsert\n } else if (adjIndex <= children.size()) {\n children[adjIndex - rebalanceOffset]\n } else { null }\n }\n )\n }\n // Case 3: if left rebalanced half was in left child, and right rebalanced half will be in right child\n // rebalancedChildIndex == splitIndex\n else {\n VarArray.tabulate<?T>(\n children.size(),\n func(i) {\n // first element is the right rebalanced half\n if (i == 0) { ?rightChildInsert } else {\n let adjIndex = i + splitIndex;\n if (adjIndex < children.size()) { children[adjIndex] } else {\n null\n }\n }\n }\n )\n };\n\n (leftRebalancedChildren, rightRebalanceChildren)\n };\n\n /// Specific to the BTree delete implementation (assumes node ordering such that nulls come at the end of the array)\n ///\n /// Assumptions:\n /// * All nulls come at the end of the array\n /// * Assumes the delete index provided is correct and non null - will trap otherwise\n /// * deleteIndex < array.size()\n ///\n /// Deletes an element from the the array, and then shifts all non-null elements coming after that deleted element by 1\n /// to the left. Returns the element that was deleted.\n public func deleteAndShift<T>(array : [var ?T], deleteIndex : Nat) : T {\n var deleted : T = switch (array[deleteIndex]) {\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In internal/BTreeHelper: deleteAndShift, an invalid/incorrect delete index was passed\")\n };\n case (?el) { el }\n };\n\n array[deleteIndex] := null;\n\n var i = deleteIndex + 1;\n label l loop {\n if (i >= array.size()) { break l };\n\n switch (array[i]) {\n case null { break l };\n case (?_) {\n array[i - 1] := array[i]\n }\n };\n\n i += 1\n };\n\n array[i - 1] := null;\n\n deleted\n };\n\n // replaces two successive elements in the array with a single element and shifts all other elements to the left by 1\n public func replaceTwoWithElementAndShift<T>(array : [var ?T], element : T, replaceIndex : Nat) {\n array[replaceIndex] := ?element;\n\n var i = replaceIndex + 1;\n let endShiftIndex : Nat = array.size() - 1;\n while (i < endShiftIndex) {\n switch (array[i]) {\n case (?_) { array[i] := array[i + 1] };\n case null { return }\n };\n\n i += 1\n };\n\n array[endShiftIndex] := null\n };\n\n /// BTree specific implementation\n ///\n /// In a single iteration insert at one position of the array while deleting at another position of the array, shifting all\n /// elements as appropriate\n ///\n /// This is used when borrowing an element from an inorder predecessor/successor through the parent node\n public func insertAtPostionAndDeleteAtPosition<T>(array : [var ?T], insertElement : ?T, insertIndex : Nat, deleteIndex : Nat) : T {\n var deleted : T = switch (array[deleteIndex]) {\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In internal/BTreeHelper: insertAtPositionAndDeleteAtPosition, and incorrect delete index was passed\")\n }; // indicated an incorrect delete index was passed - trap\n case (?el) { el }\n };\n\n // Example of this case:\n //\n // Insert Delete\n // V V\n //[var ?10, ?20, ?30, ?40, ?50]\n if (insertIndex < deleteIndex) {\n var i = deleteIndex;\n while (i > insertIndex) {\n array[i] := array[i - 1];\n i -= 1\n };\n\n array[insertIndex] := insertElement\n }\n // Example of this case:\n //\n // Delete Insert\n // V V\n //[var ?10, ?20, ?30, ?40, ?50]\n else if (insertIndex > deleteIndex) {\n array[deleteIndex] := null;\n var i = deleteIndex + 1;\n label l loop {\n if (i >= array.size()) { assert false; break l }; // TODO: remove? this should not happen since the insertIndex should get hit first?\n\n if (i == insertIndex) {\n array[i - 1] := array[i];\n array[i] := insertElement;\n break l\n } else {\n array[i - 1] := array[i]\n };\n\n i += 1\n };\n\n }\n // insertIndex == deleteIndex, can just do a swap\n else { array[deleteIndex] := insertElement };\n\n deleted\n };\n\n // which child the deletionIndex is referring to\n public type DeletionSide = { #left; #right };\n\n // merges a middle (parent) element with the left and right child arrays while deleting the element from the correct child by the deleteIndex passed\n public func mergeParentWithChildrenAndDelete<T>(\n parentElement : ?T,\n childCount : Nat,\n leftChild : [var ?T],\n rightChild : [var ?T],\n deleteIndex : Nat,\n deletionSide : DeletionSide\n ) : ([var ?T], T) {\n let mergedArray = VarArray.repeat<?T>(null, leftChild.size());\n var i = 0;\n switch (deletionSide) {\n case (#left) {\n // BTree implementation expects the deleted element to exist - if null, traps\n let deletedElement = switch (leftChild[deleteIndex]) {\n case (?el) { el };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In internal/BTreeHelper: mergeParentWithChildrenAndDelete, an invalid delete index was passed\")\n }\n };\n\n // copy over left child until deleted element is hit, then copy all elements after the deleted element\n while (i < childCount) {\n if (i < deleteIndex) {\n mergedArray[i] := leftChild[i]\n } else {\n mergedArray[i] := leftChild[i + 1]\n };\n i += 1\n };\n\n // insert parent kv in the middle\n mergedArray[childCount - 1] := parentElement;\n\n // copy over the rest of the right child elements\n while (i < childCount * 2) {\n mergedArray[i] := rightChild[i - childCount];\n i += 1\n };\n\n (mergedArray, deletedElement)\n };\n case (#right) {\n // BTree implementation expects the deleted element to exist - if null, traps\n let deletedElement = switch (rightChild[deleteIndex]) {\n case (?el) { el };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In internal/BTreeHelper: mergeParentWithChildrenAndDelete: element at deleted index must exist\")\n }\n };\n // since deletion side is #right, can safely copy over all elements from the left child\n while (i < childCount) {\n mergedArray[i] := leftChild[i];\n i += 1\n };\n\n // insert parent kv in the middle\n mergedArray[childCount] := parentElement;\n i += 1;\n\n var j = 0;\n // copy over right child until deleted element is hit, then copy elements after the deleted element\n while (i < childCount * 2) {\n if (j < deleteIndex) {\n mergedArray[i] := rightChild[j]\n } else {\n mergedArray[i] := rightChild[j + 1]\n };\n i += 1;\n j += 1\n };\n\n (mergedArray, deletedElement)\n }\n }\n };\n\n}\n"},"Char.mo":{"content":"/// Module for working with Characters (Unicode code points).\n///\n/// Characters in Motoko represent Unicode code points\n/// in the range 0 to 0x10FFFF, excluding the surrogate code points\n/// (0xD800 through 0xDFFF).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Char \"mo:core/Char\";\n/// ```\n///\n/// Some built in features not listed in this module:\n///\n/// * You can create a `Char` literal using single quotes, e.g. 'A', '1', '漢'\n/// * You can compare characters using `<`, `<=`, `==`, `!=`, `>=`, `>` operators\n/// * You can convert a single-character `Text` to a `Char` using `:Char` type annotation\n///\n/// For example:\n/// ```motoko include=import\n/// let char : Char = 'A';\n/// let unicodeChar = '漢';\n/// let digit = '7';\n/// assert Char.isDigit(digit);\n/// assert Char.toText(char) == \"A\";\n/// ```\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Characters represented as Unicode code points.\n public type Char = Prim.Types.Char;\n\n /// Convert character `char` to a word containing its Unicode scalar value.\n ///\n /// Example:\n /// ```motoko include=import\n /// let char = 'A';\n /// let unicode = Char.toNat32(char);\n /// assert unicode == 65;\n /// ```\n public let toNat32 : (char : Char) -> Nat32 = Prim.charToNat32;\n\n /// Convert `w` to a character.\n /// Traps if `w` is not a valid Unicode scalar value.\n /// Value `w` is valid if, and only if, `w < 0xD800 or (0xE000 <= w and w <= 0x10FFFF)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let unicode : Nat32 = 65;\n /// let char = Char.fromNat32(unicode);\n /// assert char == 'A';\n /// ```\n public let fromNat32 : (nat32 : Nat32) -> Char = Prim.nat32ToChar;\n\n /// Convert character `char` to single character text.\n ///\n /// Example:\n /// ```motoko include=import\n /// let char = '漢';\n /// let text = Char.toText(char);\n /// assert text == \"漢\";\n /// ```\n public let toText : (char : Char) -> Text = Prim.charToText;\n\n // Not exposed pending multi-char implementation.\n private let _toUpper : (char : Char) -> Char = Prim.charToUpper;\n\n // Not exposed pending multi-char implementation.\n private let _toLower : (char : Char) -> Char = Prim.charToLower;\n\n /// Returns `true` when `char` is a decimal digit between `0` and `9`, otherwise `false`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.isDigit('5');\n /// assert not Char.isDigit('A');\n /// ```\n public func isDigit(char : Char) : Bool {\n Prim.charToNat32(char) -% Prim.charToNat32('0') <= (9 : Nat32)\n };\n\n /// Returns whether `char` is a whitespace character.\n /// Whitespace characters include space, tab, newline, etc.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.isWhitespace(' ');\n /// assert Char.isWhitespace('\\n');\n /// assert not Char.isWhitespace('A');\n /// ```\n public let isWhitespace : (char : Char) -> Bool = Prim.charIsWhitespace;\n\n /// Returns whether `char` is a lowercase character.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.isLower('a');\n /// assert not Char.isLower('A');\n /// ```\n public let isLower : (char : Char) -> Bool = Prim.charIsLowercase;\n\n /// Returns whether `char` is an uppercase character.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.isUpper('A');\n /// assert not Char.isUpper('a');\n /// ```\n public let isUpper : (char : Char) -> Bool = Prim.charIsUppercase;\n\n /// Returns whether `char` is an alphabetic character.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.isAlphabetic('A');\n /// assert Char.isAlphabetic('漢');\n /// assert not Char.isAlphabetic('1');\n /// ```\n public let isAlphabetic : (char : Char) -> Bool = Prim.charIsAlphabetic;\n\n /// Returns `a == b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.equal('A', 'A');\n /// assert not Char.equal('A', 'B');\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func equal(a : Char, b : Char) : Bool { a == b };\n\n /// Returns `a != b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.notEqual('A', 'B');\n /// assert not Char.notEqual('A', 'A');\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func notEqual(a : Char, b : Char) : Bool { a != b };\n\n /// Returns `a < b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.less('A', 'B');\n /// assert not Char.less('B', 'A');\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func less(a : Char, b : Char) : Bool { a < b };\n\n /// Returns `a <= b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.lessOrEqual('A', 'A');\n /// assert Char.lessOrEqual('A', 'B');\n /// assert not Char.lessOrEqual('B', 'A');\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func lessOrEqual(a : Char, b : Char) : Bool { a <= b };\n\n /// Returns `a > b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.greater('B', 'A');\n /// assert not Char.greater('A', 'B');\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func greater(a : Char, b : Char) : Bool { a > b };\n\n /// Returns `a >= b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.greaterOrEqual('B', 'A');\n /// assert Char.greaterOrEqual('A', 'A');\n /// assert not Char.greaterOrEqual('A', 'B');\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func greaterOrEqual(a : Char, b : Char) : Bool { a >= b };\n\n /// Returns the order of `a` and `b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Char.compare('A', 'B') == #less;\n /// assert Char.compare('B', 'A') == #greater;\n /// assert Char.compare('A', 'A') == #equal;\n /// ```\n public func compare(a : Char, b : Char) : { #less; #equal; #greater } {\n if (a < b) { #less } else if (a == b) { #equal } else { #greater }\n };\n\n}\n"},"Bool.mo":{"content":"/// Boolean type and operations.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Bool \"mo:core/Bool\";\n/// ```\n///\n/// While boolean operators `_ and _` and `_ or _` are short-circuiting,\n/// avoiding computation of the right argument when possible, the functions\n/// `logicalAnd(_, _)` and `logicalOr(_, _)` are *strict* and will always evaluate *both*\n/// of their arguments.\n///\n/// Example:\n/// ```motoko include=import\n/// let t = true;\n/// let f = false;\n///\n/// // Short-circuiting AND\n/// assert not (t and f);\n///\n/// // Short-circuiting OR\n/// assert t or f;\n/// ```\n\nimport Prim \"mo:⛔\";\nimport Iter \"Iter\";\nimport Order \"Order\";\n\nmodule {\n\n /// Booleans with constants `true` and `false`.\n public type Bool = Prim.Types.Bool;\n\n /// Returns `a and b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert not Bool.logicalAnd(true, false);\n /// assert Bool.logicalAnd(true, true);\n /// ```\n public func logicalAnd(a : Bool, b : Bool) : Bool = a and b;\n\n /// Returns `a or b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Bool.logicalOr(true, false);\n /// assert Bool.logicalOr(false, true);\n /// ```\n public func logicalOr(a : Bool, b : Bool) : Bool = a or b;\n\n /// Returns exclusive or of `a` and `b`, `a != b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Bool.logicalXor(true, false);\n /// assert not Bool.logicalXor(true, true);\n /// assert not Bool.logicalXor(false, false);\n /// ```\n public func logicalXor(a : Bool, b : Bool) : Bool = a != b;\n\n /// Returns `not bool`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Bool.logicalNot(false);\n /// assert not Bool.logicalNot(true);\n /// ```\n public func logicalNot(bool : Bool) : Bool = not bool;\n\n /// Returns `a == b`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Bool.equal(true, true);\n /// assert not Bool.equal(true, false);\n /// ```\n public func equal(a : Bool, b : Bool) : Bool { a == b };\n\n /// Returns the ordering of `a` compared to `b`.\n /// Returns `#less` if `a` is `false` and `b` is `true`,\n /// `#equal` if `a` equals `b`,\n /// and `#greater` if `a` is `true` and `b` is `false`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Bool.compare(true, false) == #greater;\n /// assert Bool.compare(true, true) == #equal;\n /// assert Bool.compare(false, true) == #less;\n /// ```\n public func compare(a : Bool, b : Bool) : Order.Order {\n if (a == b) #equal else if a #greater else #less\n };\n\n /// Returns a text value which is either `\"true\"` or `\"false\"` depending on the input value.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Bool.toText(true) == \"true\";\n /// assert Bool.toText(false) == \"false\";\n /// ```\n public func toText(bool : Bool) : Text {\n if bool \"true\" else \"false\"\n };\n\n /// Returns an iterator over all possible boolean values (`true` and `false`).\n ///\n /// Example:\n /// ```motoko include=import\n /// let iter = Bool.allValues();\n /// assert iter.next() == ?true;\n /// assert iter.next() == ?false;\n /// assert iter.next() == null;\n /// ```\n public func allValues() : Iter.Iter<Bool> = object {\n var state : ?Bool = ?true;\n public func next() : ?Bool {\n switch state {\n case (?true) { state := ?false; ?true };\n case (?false) { state := null; ?false };\n case null { null }\n }\n }\n };\n\n}\n"},"Int32.mo":{"content":"/// Utility functions on 32-bit signed integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Int32 \"mo:core/Int32\";\n/// ```\nimport Int \"Int\";\nimport Iter \"Iter\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// 32-bit signed integers.\n public type Int32 = Prim.Types.Int32;\n\n /// Minimum 32-bit integer value, `-2 ** 31`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.minValue == -2_147_483_648;\n /// ```\n public let minValue : Int32 = -2_147_483_648;\n\n /// Maximum 32-bit integer value, `+2 ** 31 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.maxValue == +2_147_483_647;\n /// ```\n public let maxValue : Int32 = 2_147_483_647;\n\n /// Converts a 32-bit signed integer to a signed integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.toInt(123_456) == (123_456 : Int);\n /// ```\n public let toInt : Int32 -> Int = Prim.int32ToInt;\n\n /// Converts a signed integer with infinite precision to a 32-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.fromInt(123_456) == (+123_456 : Int32);\n /// ```\n public let fromInt : Int -> Int32 = Prim.intToInt32;\n\n /// Converts a signed integer with infinite precision to a 32-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.fromIntWrap(-123_456) == (-123_456 : Int);\n /// ```\n public let fromIntWrap : Int -> Int32 = Prim.intToInt32Wrap;\n\n /// Converts a 16-bit signed integer to a 32-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.fromInt16(-123) == (-123 : Int32);\n /// ```\n public let fromInt16 : Int16 -> Int32 = Prim.int16ToInt32;\n\n /// Converts a 32-bit signed integer to a 16-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.toInt16(-123) == (-123 : Int16);\n /// ```\n public let toInt16 : Int32 -> Int16 = Prim.int32ToInt16;\n\n /// Converts a 64-bit signed integer to a 32-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.fromInt64(-123_456) == (-123_456 : Int32);\n /// ```\n public let fromInt64 : Int64 -> Int32 = Prim.int64ToInt32;\n\n /// Converts a 32-bit signed integer to a 64-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.toInt64(-123_456) == (-123_456 : Int64);\n /// ```\n public let toInt64 : Int32 -> Int64 = Prim.int32ToInt64;\n\n /// Converts an unsigned 32-bit integer to a signed 32-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.fromNat32(123_456) == (+123_456 : Int32);\n /// ```\n public let fromNat32 : Nat32 -> Int32 = Prim.nat32ToInt32;\n\n /// Converts a signed 32-bit integer to an unsigned 32-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.toNat32(-1) == (4_294_967_295 : Nat32); // underflow\n /// ```\n public let toNat32 : Int32 -> Nat32 = Prim.int32ToNat32;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.toText(-123456) == \"-123456\";\n /// ```\n public func toText(x : Int32) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Traps when `x == -2 ** 31` (the minimum `Int32` value).\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.abs(-123456) == +123_456;\n /// ```\n public func abs(x : Int32) : Int32 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.min(+2, -3) == -3;\n /// ```\n public func min(x : Int32, y : Int32) : Int32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.max(+2, -3) == +2;\n /// ```\n public func max(x : Int32, y : Int32) : Int32 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int32 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.equal(-1, -1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Int32 = -123;\n /// let b : Int32 = 123;\n /// assert not Int32.equal(a, b);\n /// ```\n public func equal(x : Int32, y : Int32) : Bool { x == y };\n\n /// Inequality function for Int32 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.notEqual(-1, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int32, y : Int32) : Bool { x != y };\n\n /// \"Less than\" function for Int32 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.less(-2, 1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int32, y : Int32) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int32 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.lessOrEqual(-2, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int32, y : Int32) : Bool { x <= y };\n\n /// \"Greater than\" function for Int32 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.greater(-2, -3);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Int32, y : Int32) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int32 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.greaterOrEqual(-2, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Int32, y : Int32) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int32`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.compare(-3, 2) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([1, -2, -3] : [Int32], Int32.compare) == [-3, -2, 1];\n /// ```\n public func compare(x : Int32, y : Int32) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n ///\n /// Traps on overflow, i.e. for `neg(-2 ** 31)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.neg(123) == -123;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int32) : Int32 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.add(100, 23) == +123;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int32, Int32>([1, -2, -3], 0, Int32.add) == -4;\n /// ```\n public func add(x : Int32, y : Int32) : Int32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.sub(1234, 123) == +1_111;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int32, Int32>([1, -2, -3], 0, Int32.sub) == 4;\n /// ```\n public func sub(x : Int32, y : Int32) : Int32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.mul(123, 100) == +12_300;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int32, Int32>([1, -2, -3], 1, Int32.mul) == 6;\n /// ```\n public func mul(x : Int32, y : Int32) : Int32 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.div(123, 10) == +12;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int32, y : Int32) : Int32 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.rem(123, 10) == +3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int32, y : Int32) : Int32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps on overflow/underflow and when `y < 0 or y >= 32`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.pow(2, 10) == +1_024;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int32, y : Int32) : Int32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitnot(-256 /* 0xffff_ff00 */) == +255 // 0xff;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Int32) : Int32 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitand(0xffff, 0x00f0) == +240 // 0xf0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Int32, y : Int32) : Int32 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitor(0xffff, 0x00f0) == +65_535 // 0xffff;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Int32, y : Int32) : Int32 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitxor(0xffff, 0x00f0) == +65_295 // 0xff0f;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Int32, y : Int32) : Int32 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n ///\n /// For `y >= 32`, the semantics is the same as for `bitshiftLeft(x, y % 32)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitshiftLeft(1, 8) == +256 // 0x100 equivalent to `2 ** 8`.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Int32, y : Int32) : Int32 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n ///\n /// For `y >= 32`, the semantics is the same as for `bitshiftRight(x, y % 32)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitshiftRight(1024, 8) == +4 // equivalent to `1024 / (2 ** 8)`;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Int32, y : Int32) : Int32 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 32`, the semantics is the same as for `bitrotLeft(x, y % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitrotLeft(0x2000_0001, 4) == +18 // 0x12.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Int32, y : Int32) : Int32 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 32`, the semantics is the same as for `bitrotRight(x, y % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitrotRight(0x0002_0001, 8) == +16_777_728 // 0x0100_0200.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Int32, y : Int32) : Int32 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 32`, the semantics is the same as for `bittest(x, p % 32)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bittest(128, 7);\n /// ```\n public func bittest(x : Int32, p : Nat) : Bool {\n Prim.btstInt32(x, Prim.intToInt32(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 32`, the semantics is the same as for `bitset(x, p % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitset(0, 7) == +128;\n /// ```\n public func bitset(x : Int32, p : Nat) : Int32 {\n x | (1 << Prim.intToInt32(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitclear(-1, 7) == -129;\n /// ```\n public func bitclear(x : Int32, p : Nat) : Int32 {\n x & ^(1 << Prim.intToInt32(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitflip(255, 7) == +127;\n /// ```\n public func bitflip(x : Int32, p : Nat) : Int32 {\n x ^ (1 << Prim.intToInt32(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitcountNonZero(0xffff) == +16;\n /// ```\n public let bitcountNonZero : (x : Int32) -> Int32 = Prim.popcntInt32;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitcountLeadingZero(0x8000) == +16;\n /// ```\n public let bitcountLeadingZero : (x : Int32) -> Int32 = Prim.clzInt32;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.bitcountTrailingZero(0x0201_0000) == +16;\n /// ```\n public let bitcountTrailingZero : (x : Int32) -> Int32 = Prim.ctzInt32;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.explode 0x66885511 == (102, 136, 85, 17);\n /// ```\n public let explode : (x : Int32) -> (msb : Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeInt32;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.addWrap(2 ** 30, 2 ** 30) == -2_147_483_648; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Int32, y : Int32) : Int32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.subWrap(-2 ** 31, 1) == +2_147_483_647; // underflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Int32, y : Int32) : Int32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.mulWrap(2 ** 16, 2 ** 16) == 0; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Int32, y : Int32) : Int32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n ///\n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 32`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int32.powWrap(2, 31) == -2_147_483_648; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Int32, y : Int32) : Int32 { x **% y };\n\n /// Returns an iterator over `Int32` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int32.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int32.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Int32, toExclusive : Int32) : Iter.Iter<Int32> {\n if (fromInclusive >= toExclusive) {\n Iter.empty()\n } else {\n object {\n var n = fromInclusive;\n public func next() : ?Int32 {\n if (n == toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over `Int32` values from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int32.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int32.rangeInclusive(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Int32, to : Int32) : Iter.Iter<Int32> {\n if (from > to) {\n Iter.empty()\n } else {\n object {\n var n = from;\n var done = false;\n public func next() : ?Int32 {\n if (done) {\n null\n } else {\n let result = n;\n if (n == to) {\n done := true\n } else {\n n += 1\n };\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over all Int32 values, from minValue to maxValue.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int32.allValues();\n /// assert iter.next() == ?-2_147_483_648;\n /// assert iter.next() == ?-2_147_483_647;\n /// assert iter.next() == ?-2_147_483_646;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Int32> {\n rangeInclusive(minValue, maxValue)\n };\n\n}\n"},"Nat16.mo":{"content":"/// Utility functions on 16-bit unsigned integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Nat16 \"mo:core/Nat16\";\n/// ```\nimport Nat \"Nat\";\nimport Iter \"Iter\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// 16-bit natural numbers.\n public type Nat16 = Prim.Types.Nat16;\n\n /// Maximum 16-bit natural number. `2 ** 16 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.maxValue == (65535 : Nat16);\n /// ```\n public let maxValue : Nat16 = 65535;\n\n /// Converts a 16-bit unsigned integer to an unsigned integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.toNat(123) == (123 : Nat);\n /// ```\n public let toNat : Nat16 -> Nat = Prim.nat16ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 16-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.fromNat(123) == (123 : Nat16);\n /// ```\n public let fromNat : Nat -> Nat16 = Prim.natToNat16;\n\n /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.fromNat8(123) == (123 : Nat16);\n /// ```\n public func fromNat8(x : Nat8) : Nat16 {\n Prim.nat8ToNat16(x)\n };\n\n /// Converts a 16-bit unsigned integer to an 8-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.toNat8(123) == (123 : Nat8);\n /// ```\n public func toNat8(x : Nat16) : Nat8 {\n Prim.nat16ToNat8(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.fromNat32(123) == (123 : Nat16);\n /// ```\n public func fromNat32(x : Nat32) : Nat16 {\n Prim.nat32ToNat16(x)\n };\n\n /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.toNat32(123) == (123 : Nat32);\n /// ```\n public func toNat32(x : Nat16) : Nat32 {\n Prim.nat16ToNat32(x)\n };\n\n /// Converts a signed integer with infinite precision to a 16-bit unsigned integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.fromIntWrap(123 : Int) == (123 : Nat16);\n /// ```\n public let fromIntWrap : Int -> Nat16 = Prim.intToNat16Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.toText(1234) == (\"1234\" : Text);\n /// ```\n public func toText(x : Nat16) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.min(123, 200) == (123 : Nat16);\n /// ```\n public func min(x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.max(123, 200) == (200 : Nat16);\n /// ```\n public func max(x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat16 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.equal(1, 1);\n /// assert (1 : Nat16) == (1 : Nat16);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Nat16 = 111;\n /// let b : Nat16 = 222;\n /// assert not Nat16.equal(a, b);\n /// ```\n public func equal(x : Nat16, y : Nat16) : Bool { x == y };\n\n /// Inequality function for Nat16 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.notEqual(1, 2);\n /// assert (1 : Nat16) != (2 : Nat16);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat16, y : Nat16) : Bool { x != y };\n\n /// \"Less than\" function for Nat16 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.less(1, 2);\n /// assert (1 : Nat16) < (2 : Nat16);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat16, y : Nat16) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat16 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.lessOrEqual(1, 2);\n /// assert (1 : Nat16) <= (2 : Nat16);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat16, y : Nat16) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat16 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.greater(2, 1);\n /// assert (2 : Nat16) > (1 : Nat16);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat16, y : Nat16) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat16 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.greaterOrEqual(2, 1);\n /// assert (2 : Nat16) >= (1 : Nat16);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat16, y : Nat16) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat16`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.compare(2, 3) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([2, 3, 1] : [Nat16], Nat16.compare) == [1, 2, 3];\n /// ```\n public func compare(x : Nat16, y : Nat16) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.add(1, 2) == 3;\n /// assert (1 : Nat16) + (2 : Nat16) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat16, Nat16>([2, 3, 1], 0, Nat16.add) == 6;\n /// ```\n public func add(x : Nat16, y : Nat16) : Nat16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.sub(2, 1) == 1;\n /// assert (2 : Nat16) - (1 : Nat16) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat16, Nat16>([2, 3, 1], 20, Nat16.sub) == 14;\n /// ```\n public func sub(x : Nat16, y : Nat16) : Nat16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.mul(2, 3) == 6;\n /// assert (2 : Nat16) * (3 : Nat16) == 6;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat16, Nat16>([2, 3, 1], 1, Nat16.mul) == 6;\n /// ```\n public func mul(x : Nat16, y : Nat16) : Nat16 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.div(6, 2) == 3;\n /// assert (6 : Nat16) / (2 : Nat16) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat16, y : Nat16) : Nat16 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.rem(6, 4) == 2;\n /// assert (6 : Nat16) % (4 : Nat16) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat16, y : Nat16) : Nat16 { x % y };\n\n /// Returns the power of `x` to `y`, `x ** y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.pow(2, 3) == 8;\n /// assert (2 : Nat16) ** (3 : Nat16) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat16, y : Nat16) : Nat16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitnot(0) == 65535;\n /// assert ^(0 : Nat16) == 65535;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Nat16) : Nat16 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitand(0, 1) == 0;\n /// assert (0 : Nat16) & (1 : Nat16) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Nat16, y : Nat16) : Nat16 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitor(0, 1) == 1;\n /// assert (0 : Nat16) | (1 : Nat16) == 1;\n /// ```\n public func bitor(x : Nat16, y : Nat16) : Nat16 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitxor(0, 1) == 1;\n /// assert (0 : Nat16) ^ (1 : Nat16) == 1;\n /// ```\n public func bitxor(x : Nat16, y : Nat16) : Nat16 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitshiftLeft(1, 3) == 8;\n /// assert (1 : Nat16) << (3 : Nat16) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Nat16, y : Nat16) : Nat16 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitshiftRight(8, 3) == 1;\n /// assert (8 : Nat16) >> (3 : Nat16) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Nat16, y : Nat16) : Nat16 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitrotLeft(2, 1) == 4;\n /// assert (2 : Nat16) <<> (1 : Nat16) == 4;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Nat16, y : Nat16) : Nat16 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitrotRight(1, 1) == 32768;\n /// assert (1 : Nat16) <>> (1 : Nat16) == 32768;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Nat16, y : Nat16) : Nat16 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bittest(5, 2);\n /// ```\n public func bittest(x : Nat16, p : Nat) : Bool {\n Prim.btstNat16(x, Prim.natToNat16(p))\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitset(0, 2) == 4;\n /// ```\n public func bitset(x : Nat16, p : Nat) : Nat16 {\n x | (1 << Prim.natToNat16(p))\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitclear(5, 2) == 1;\n /// ```\n public func bitclear(x : Nat16, p : Nat) : Nat16 {\n x & ^(1 << Prim.natToNat16(p))\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitflip(5, 2) == 1;\n /// ```\n public func bitflip(x : Nat16, p : Nat) : Nat16 {\n x ^ (1 << Prim.natToNat16(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitcountNonZero(5) == 2;\n /// ```\n public let bitcountNonZero : (x : Nat16) -> Nat16 = Prim.popcntNat16;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitcountLeadingZero(5) == 13;\n /// ```\n public let bitcountLeadingZero : (x : Nat16) -> Nat16 = Prim.clzNat16;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.bitcountTrailingZero(5) == 0;\n /// ```\n public let bitcountTrailingZero : (x : Nat16) -> Nat16 = Prim.ctzNat16;\n\n /// Returns the upper (i.e. most significant) and lower (least significant) byte of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.explode 0xaa88 == (170, 136);\n /// ```\n public let explode : (x : Nat16) -> (msb : Nat8, lsb : Nat8) = Prim.explodeNat16;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.addWrap(65532, 5) == 1;\n /// assert (65532 : Nat16) +% (5 : Nat16) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Nat16, y : Nat16) : Nat16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.subWrap(1, 2) == 65535;\n /// assert (1 : Nat16) -% (2 : Nat16) == 65535;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Nat16, y : Nat16) : Nat16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.mulWrap(655, 101) == 619;\n /// assert (655 : Nat16) *% (101 : Nat16) == 619;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Nat16, y : Nat16) : Nat16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat16.powWrap(2, 16) == 0;\n /// assert (2 : Nat16) **% (16 : Nat16) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Nat16, y : Nat16) : Nat16 { x **% y };\n\n /// Returns an iterator over `Nat16` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat16.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat16.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Nat16, toExclusive : Nat16) : Iter.Iter<Nat16> {\n if (fromInclusive >= toExclusive) {\n Iter.empty()\n } else {\n object {\n var n = fromInclusive;\n public func next() : ?Nat16 {\n if (n == toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over `Nat16` values from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat16.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat16.rangeInclusive(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Nat16, to : Nat16) : Iter.Iter<Nat16> {\n if (from > to) {\n Iter.empty()\n } else {\n object {\n var n = from;\n var done = false;\n public func next() : ?Nat16 {\n if (done) {\n null\n } else {\n let result = n;\n if (n == to) {\n done := true\n } else {\n n += 1\n };\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over all Nat16 values, from 0 to maxValue.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat16.allValues();\n /// assert iter.next() == ?0;\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Nat16> {\n rangeInclusive(0, maxValue)\n };\n\n}\n"},"Debug.mo":{"content":"/// Utility functions for debugging.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Debug \"mo:core/Debug\";\n/// ```\n\nimport Prim \"mo:⛔\";\nimport Runtime \"Runtime\";\n\nmodule {\n\n /// Prints `text` to output stream.\n ///\n /// NOTE: When running on an ICP network, all output is written to the [canister log](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/maintain/logs) with the exclusion of any output\n /// produced during the execution of non-replicated queries and composite queries.\n /// In other environments, like the interpreter and stand-alone wasm engines, the output is written to standard out.\n ///\n /// ```motoko include=import\n /// Debug.print \"Hello New World!\";\n /// Debug.print(debug_show(4)) // Often used with `debug_show` to convert values to Text\n /// ```\n public func print(text : Text) {\n Prim.debugPrint(text)\n };\n\n /// Mark incomplete code with the `todo()` function.\n ///\n /// Each have calls are well-typed in all typing contexts, which\n /// trap in all execution contexts.\n ///\n /// ```motoko include=import\n /// func doSomethingComplex() {\n /// Debug.todo()\n /// };\n /// ```\n public func todo() : None {\n Runtime.trap(\"Debug.todo()\")\n };\n\n}\n"},"Nat.mo":{"content":"/// Natural numbers with infinite precision.\n///\n/// Most operations on natural numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Nat \"mo:core/Nat\";\n/// ```\n\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\nimport Char \"Char\";\nimport Iter \"Iter\";\nimport Runtime \"Runtime\";\nimport Order \"Order\";\n\nmodule {\n\n /// Infinite precision natural numbers.\n public type Nat = Prim.Types.Nat;\n\n /// Converts a natural number to its textual representation. Textual\n /// representation _do not_ contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.toText(1234) == \"1234\";\n /// ```\n public func toText(n : Nat) : Text = Int.toText n;\n\n /// Creates a natural number from its textual representation. Returns `null`\n /// if the input is not a valid natural number.\n ///\n /// The textual representation _must not_ contain underscores.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.fromText(\"1234\") == ?1234;\n /// ```\n public func fromText(text : Text) : ?Nat {\n if (text == \"\") {\n return null\n };\n var n = 0;\n for (c in text.chars()) {\n if (Char.isDigit(c)) {\n let charAsNat = Prim.nat32ToNat(Prim.charToNat32(c) -% Prim.charToNat32('0'));\n n := n * 10 + charAsNat\n } else {\n return null\n }\n };\n ?n\n };\n\n /// Converts an integer to a natural number. Traps if the integer is negative.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.fromInt(1234) == (1234 : Nat);\n /// ```\n public func fromInt(int : Int) : Nat {\n if (int < 0) {\n Runtime.trap(\"Nat.fromInt(): negative input value\")\n } else {\n Int.abs(int)\n }\n };\n\n /// Converts a natural number to an integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.toInt(1234) == 1234;\n /// ```\n public func toInt(nat : Nat) : Int {\n nat : Int\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.min(1, 2) == 1;\n /// ```\n public func min(x : Nat, y : Nat) : Nat {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.max(1, 2) == 2;\n /// ```\n public func max(x : Nat, y : Nat) : Nat {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.equal(1, 1);\n /// assert 1 == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a = 111;\n /// let b = 222;\n /// assert not Nat.equal(a, b);\n /// ```\n public func equal(x : Nat, y : Nat) : Bool { x == y };\n\n /// Inequality function for Nat types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.notEqual(1, 2);\n /// assert 1 != 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat, y : Nat) : Bool { x != y };\n\n /// \"Less than\" function for Nat types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.less(1, 2);\n /// assert 1 < 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat, y : Nat) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.lessOrEqual(1, 2);\n /// assert 1 <= 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat, y : Nat) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.greater(2, 1);\n /// assert 2 > 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat, y : Nat) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.greaterOrEqual(2, 1);\n /// assert 2 >= 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat, y : Nat) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.compare(2, 3) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([2, 3, 1], Nat.compare) == [1, 2, 3];\n /// ```\n public func compare(x : Nat, y : Nat) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. This operator will never overflow\n /// because `Nat` is infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.add(1, 2) == 3;\n /// assert 1 + 2 == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft([2, 3, 1], 0, Nat.add) == 6;\n /// ```\n public func add(x : Nat, y : Nat) : Nat { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow below `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.sub(2, 1) == 1;\n /// // Add a type annotation to avoid a warning about the subtraction\n /// assert 2 - 1 : Nat == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft([2, 3, 1], 10, Nat.sub) == 4;\n /// ```\n public func sub(x : Nat, y : Nat) : Nat { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. This operator will never\n /// overflow because `Nat` is infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.mul(2, 3) == 6;\n /// assert 2 * 3 == 6;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft([2, 3, 1], 1, Nat.mul) == 6;\n /// ```\n public func mul(x : Nat, y : Nat) : Nat { x * y };\n\n /// Returns the unsigned integer division of `x` by `y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// The quotient is rounded down, which is equivalent to truncating the\n /// decimal places of the quotient.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.div(6, 2) == 3;\n /// assert 6 / 2 == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat, y : Nat) : Nat { x / y };\n\n /// Returns the remainder of unsigned integer division of `x` by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.rem(6, 4) == 2;\n /// assert 6 % 4 == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat, y : Nat) : Nat { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps when `y > 2^32`. This operator\n /// will never overflow because `Nat` is infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.pow(2, 3) == 8;\n /// assert 2 ** 3 == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat, y : Nat) : Nat { x ** y };\n\n /// Returns the (conceptual) bitwise shift left of `x` by `y`, `x * (2 ** y)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.bitshiftLeft(1, 3) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in absence\n /// of the `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. While `Nat` is not defined in terms\n /// of bit patterns, conceptually it can be regarded as such, and the operation\n /// is provided as a high-performance version of the corresponding arithmetic\n /// rule.\n public func bitshiftLeft(x : Nat, y : Nat32) : Nat { Prim.shiftLeft(x, y) };\n\n /// Returns the (conceptual) bitwise shift right of `x` by `y`, `x / (2 ** y)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat.bitshiftRight(8, 3) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in absence\n /// of the `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. While `Nat` is not defined in terms\n /// of bit patterns, conceptually it can be regarded as such, and the operation\n /// is provided as a high-performance version of the corresponding arithmetic\n /// rule.\n public func bitshiftRight(x : Nat, y : Nat32) : Nat { Prim.shiftRight(x, y) };\n\n /// Returns an iterator over `Nat` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Nat, toExclusive : Nat) : Iter.Iter<Nat> = object {\n var n = fromInclusive;\n public func next() : ?Nat {\n if (n >= toExclusive) {\n return null\n };\n let current = n;\n n += 1;\n ?current\n }\n };\n\n /// Returns an iterator over `Nat` values from the first to second argument with an exclusive upper bound,\n /// incrementing by the specified step size. The step can be positive or negative.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// // Positive step\n /// let iter1 = Nat.rangeBy(1, 7, 2);\n /// assert iter1.next() == ?1;\n /// assert iter1.next() == ?3;\n /// assert iter1.next() == ?5;\n /// assert iter1.next() == null;\n ///\n /// // Negative step\n /// let iter2 = Nat.rangeBy(7, 1, -2);\n /// assert iter2.next() == ?7;\n /// assert iter2.next() == ?5;\n /// assert iter2.next() == ?3;\n /// assert iter2.next() == null;\n /// ```\n ///\n /// If `step` is 0 or if the iteration would not progress towards the bound, returns an empty iterator.\n public func rangeBy(fromInclusive : Nat, toExclusive : Nat, step : Int) : Iter.Iter<Nat> {\n if (step == 0) {\n Iter.empty()\n } else if (step > 0) {\n object {\n let stepMagnitude = Int.abs(step);\n var n = fromInclusive;\n public func next() : ?Nat {\n if (n >= toExclusive) {\n return null\n };\n let current = n;\n n += stepMagnitude;\n ?current\n }\n }\n } else {\n object {\n let stepMagnitude = Int.abs(step);\n var n = fromInclusive;\n public func next() : ?Nat {\n if (n <= toExclusive) {\n return null\n };\n let current = n;\n if (stepMagnitude > n) {\n n := 0\n } else {\n n -= stepMagnitude\n };\n ?current\n }\n }\n }\n };\n\n /// Returns an iterator over the integers from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat.rangeInclusive(3, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Nat, to : Nat) : Iter.Iter<Nat> = object {\n var n = from;\n public func next() : ?Nat {\n if (n > to) {\n return null\n };\n let current = n;\n n += 1;\n ?current\n }\n };\n\n /// Returns an iterator over the integers from the first to second argument, inclusive,\n /// incrementing by the specified step size. The step can be positive or negative.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// // Positive step\n /// let iter1 = Nat.rangeByInclusive(1, 7, 2);\n /// assert iter1.next() == ?1;\n /// assert iter1.next() == ?3;\n /// assert iter1.next() == ?5;\n /// assert iter1.next() == ?7;\n /// assert iter1.next() == null;\n ///\n /// // Negative step\n /// let iter2 = Nat.rangeByInclusive(7, 1, -2);\n /// assert iter2.next() == ?7;\n /// assert iter2.next() == ?5;\n /// assert iter2.next() == ?3;\n /// assert iter2.next() == ?1;\n /// assert iter2.next() == null;\n /// ```\n ///\n /// If `from == to`, return an iterator which only\n ///\n /// Otherwise, if `step` is 0 or if the iteration would not progress towards the bound, returns an empty iterator.\n public func rangeByInclusive(from : Nat, to : Nat, step : Int) : Iter.Iter<Nat> {\n if (from == to) {\n Iter.singleton(from)\n } else if (step > 0) {\n object {\n let stepMagnitude = Int.abs(step);\n var n = from;\n public func next() : ?Nat {\n if (n >= to + 1) {\n return null\n };\n let current = n;\n n += stepMagnitude;\n ?current\n }\n }\n } else {\n object {\n let stepMagnitude = Int.abs(step);\n var n = from;\n public func next() : ?Nat {\n if (n + 1 <= to) {\n return null\n };\n let current = n;\n if (stepMagnitude > n) {\n n := 0\n } else {\n n -= stepMagnitude\n };\n ?current\n }\n }\n }\n };\n\n /// Returns an infinite iterator over all possible `Nat` values.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat.allValues();\n /// assert iter.next() == ?0;\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Nat> = object {\n var n = 0;\n public func next() : ?Nat {\n let current = n;\n n += 1;\n ?current\n }\n };\n\n}\n"},"Int8.mo":{"content":"/// Utility functions on 8-bit signed integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Int8 \"mo:core/Int8\";\n/// ```\nimport Int \"Int\";\nimport Iter \"Iter\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// 8-bit signed integers.\n public type Int8 = Prim.Types.Int8;\n\n /// Minimum 8-bit integer value, `-2 ** 7`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.minValue == -128;\n /// ```\n public let minValue : Int8 = -128;\n\n /// Maximum 8-bit integer value, `+2 ** 7 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.maxValue == +127;\n /// ```\n public let maxValue : Int8 = 127;\n\n /// Converts an 8-bit signed integer to a signed integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.toInt(123) == (123 : Int);\n /// ```\n public let toInt : Int8 -> Int = Prim.int8ToInt;\n\n /// Converts a signed integer with infinite precision to an 8-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.fromInt(123) == (+123 : Int8);\n /// ```\n public let fromInt : Int -> Int8 = Prim.intToInt8;\n\n /// Converts a signed integer with infinite precision to an 8-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.fromIntWrap(-123) == (-123 : Int8);\n /// ```\n public let fromIntWrap : Int -> Int8 = Prim.intToInt8Wrap;\n\n /// Converts a 16-bit signed integer to an 8-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.fromInt16(123) == (+123 : Int8);\n /// ```\n public let fromInt16 : Int16 -> Int8 = Prim.int16ToInt8;\n\n /// Converts an 8-bit signed integer to a 16-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.toInt16(123) == (+123 : Int16);\n /// ```\n public let toInt16 : Int8 -> Int16 = Prim.int8ToInt16;\n\n /// Converts an unsigned 8-bit integer to a signed 8-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.fromNat8(123) == (+123 : Int8);\n /// ```\n public let fromNat8 : Nat8 -> Int8 = Prim.nat8ToInt8;\n\n /// Converts a signed 8-bit integer to an unsigned 8-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.toNat8(-1) == (255 : Nat8); // underflow\n /// ```\n public let toNat8 : Int8 -> Nat8 = Prim.int8ToNat8;\n\n /// Converts an integer number to its textual representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.toText(-123) == \"-123\";\n /// ```\n public func toText(x : Int8) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Traps when `x == -2 ** 7` (the minimum `Int8` value).\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.abs(-123) == +123;\n /// ```\n public func abs(x : Int8) : Int8 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.min(+2, -3) == -3;\n /// ```\n public func min(x : Int8, y : Int8) : Int8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.max(+2, -3) == +2;\n /// ```\n public func max(x : Int8, y : Int8) : Int8 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int8 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.equal(-1, -1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Int8 = -123;\n /// let b : Int8 = 123;\n /// assert not Int8.equal(a, b);\n /// ```\n public func equal(x : Int8, y : Int8) : Bool { x == y };\n\n /// Inequality function for Int8 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.notEqual(-1, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int8, y : Int8) : Bool { x != y };\n\n /// \"Less than\" function for Int8 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.less(-2, 1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int8, y : Int8) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int8 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.lessOrEqual(-2, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int8, y : Int8) : Bool { x <= y };\n\n /// \"Greater than\" function for Int8 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.greater(-2, -3);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Int8, y : Int8) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int8 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.greaterOrEqual(-2, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Int8, y : Int8) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int8`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.compare(-3, 2) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([1, -2, -3] : [Int8], Int8.compare) == [-3, -2, 1];\n /// ```\n public func compare(x : Int8, y : Int8) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n ///\n /// Traps on overflow, i.e. for `neg(-2 ** 7)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.neg(123) == -123;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int8) : Int8 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.add(100, 23) == +123;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int8, Int8>([1, -2, -3], 0, Int8.add) == -4;\n /// ```\n public func add(x : Int8, y : Int8) : Int8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.sub(123, 23) == +100;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int8, Int8>([1, -2, -3], 0, Int8.sub) == 4;\n /// ```\n public func sub(x : Int8, y : Int8) : Int8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.mul(12, 10) == +120;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int8, Int8>([1, -2, -3], 1, Int8.mul) == 6;\n /// ```\n public func mul(x : Int8, y : Int8) : Int8 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.div(123, 10) == +12;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int8, y : Int8) : Int8 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.rem(123, 10) == +3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int8, y : Int8) : Int8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps on overflow/underflow and when `y < 0 or y >= 8`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.pow(2, 6) == +64;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int8, y : Int8) : Int8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitnot(-16 /* 0xf0 */) == +15 // 0x0f;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Int8) : Int8 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitand(0x1f, 0x70) == +16 // 0x10;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Int8, y : Int8) : Int8 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitor(0x0f, 0x70) == +127 // 0x7f;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Int8, y : Int8) : Int8 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitxor(0x70, 0x7f) == +15 // 0x0f;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Int8, y : Int8) : Int8 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n ///\n /// For `y >= 8`, the semantics is the same as for `bitshiftLeft(x, y % 8)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitshiftLeft(1, 4) == +16 // 0x10 equivalent to `2 ** 4`.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Int8, y : Int8) : Int8 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n ///\n /// For `y >= 8`, the semantics is the same as for `bitshiftRight(x, y % 8)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitshiftRight(64, 4) == +4 // equivalent to `64 / (2 ** 4)`;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Int8, y : Int8) : Int8 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 8`, the semantics is the same as for `bitrotLeft(x, y % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitrotLeft(0x11 /* 0b0001_0001 */, 2) == +68 // 0b0100_0100 == 0x44.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Int8, y : Int8) : Int8 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 8`, the semantics is the same as for `bitrotRight(x, y % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitrotRight(0x11 /* 0b0001_0001 */, 1) == -120 // 0b1000_1000 == 0x88.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Int8, y : Int8) : Int8 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 8`, the semantics is the same as for `bittest(x, p % 8)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bittest(64, 6);\n /// ```\n public func bittest(x : Int8, p : Nat) : Bool {\n Prim.btstInt8(x, Prim.intToInt8(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 8`, the semantics is the same as for `bitset(x, p % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitset(0, 6) == +64;\n /// ```\n public func bitset(x : Int8, p : Nat) : Int8 {\n x | (1 << Prim.intToInt8(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitclear(-1, 6) == -65;\n /// ```\n public func bitclear(x : Int8, p : Nat) : Int8 {\n x & ^(1 << Prim.intToInt8(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitflip(127, 6) == +63;\n /// ```\n public func bitflip(x : Int8, p : Nat) : Int8 {\n x ^ (1 << Prim.intToInt8(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitcountNonZero(0x0f) == +4;\n /// ```\n public let bitcountNonZero : (x : Int8) -> Int8 = Prim.popcntInt8;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitcountLeadingZero(0x08) == +4;\n /// ```\n public let bitcountLeadingZero : (x : Int8) -> Int8 = Prim.clzInt8;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.bitcountTrailingZero(0x10) == +4;\n /// ```\n public let bitcountTrailingZero : (x : Int8) -> Int8 = Prim.ctzInt8;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.addWrap(2 ** 6, 2 ** 6) == -128; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Int8, y : Int8) : Int8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.subWrap(-2 ** 7, 1) == +127; // underflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Int8, y : Int8) : Int8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.mulWrap(2 ** 4, 2 ** 4) == 0; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Int8, y : Int8) : Int8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n ///\n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 8`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int8.powWrap(2, 7) == -128; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Int8, y : Int8) : Int8 { x **% y };\n\n /// Returns an iterator over `Int8` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int8.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int8.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Int8, toExclusive : Int8) : Iter.Iter<Int8> {\n if (fromInclusive >= toExclusive) {\n Iter.empty()\n } else {\n object {\n var n = fromInclusive;\n public func next() : ?Int8 {\n if (n == toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over `Int8` values from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int8.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int8.rangeInclusive(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Int8, to : Int8) : Iter.Iter<Int8> {\n if (from > to) {\n Iter.empty()\n } else {\n object {\n var n = from;\n var done = false;\n public func next() : ?Int8 {\n if (done) {\n null\n } else {\n let result = n;\n if (n == to) {\n done := true\n } else {\n n += 1\n };\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over all Int8 values, from minValue to maxValue.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int8.allValues();\n /// assert iter.next() == ?-128;\n /// assert iter.next() == ?-127;\n /// assert iter.next() == ?-126;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Int8> {\n rangeInclusive(minValue, maxValue)\n };\n\n}\n"},"Iter.mo":{"content":"/// Utilities for `Iter` (iterator) values.\n///\n/// Iterators are a way to represent sequences of values that can be lazily produced.\n/// They can be used to:\n/// - Iterate over collections.\n/// - Represent collections that are too large to fit in memory or that are produced incrementally.\n/// - Transform collections without creating intermediate collections.\n///\n/// Iterators are inherently stateful. Calling `next` \"consumes\" a value from\n/// the Iterator that cannot be put back, so keep that in mind when sharing\n/// iterators between consumers.\n///\n/// ```motoko name=import\n/// import Iter \"mo:core/Iter\";\n/// ```\n///\n///\n/// An iterator can be iterated over using a `for` loop:\n/// ```motoko\n/// let iter = [1, 2, 3].values();\n/// for (x in iter) {\n/// // do something with x...\n/// }\n/// ```\n///\n/// Iterators can be:\n/// - created from other collections (e.g. using `values` or `keys` function on a `Map`) or from scratch (e.g. using `empty` or `singleton`).\n/// - transformed using `map`, `filter`, `concat`, etc. Which can be used to compose several transformations together without materializing intermediate collections.\n/// - consumed using `forEach`, `size`, `toArray`, etc.\n/// - combined using `concat`.\n\nimport Prim \"mo:prim\";\n\nimport Array \"Array\";\nimport Order \"Order\";\nimport Runtime \"Runtime\";\nimport Types \"Types\";\nimport VarArray \"VarArray\";\n\nmodule {\n\n /// An iterator that produces values of type `T`. Calling `next` returns\n /// `null` when iteration is finished.\n ///\n /// Iterators are inherently stateful. Calling `next` \"consumes\" a value from\n /// the Iterator that cannot be put back, so keep that in mind when sharing\n /// iterators between consumers.\n ///\n /// An iterator `i` can be iterated over using\n /// ```motoko\n /// let iter = [1, 2, 3].values();\n /// for (x in iter) {\n /// // do something with x...\n /// }\n /// ```\n public type Iter<T> = Types.Iter<T>;\n\n /// Creates an empty iterator.\n ///\n /// ```motoko include=import\n /// for (x in Iter.empty<Nat>())\n /// assert false; // This loop body will never run\n /// ```\n public func empty<T>() : Iter<T> {\n object {\n public func next() : ?T {\n null\n }\n }\n };\n\n /// Creates an iterator that produces a single value.\n ///\n /// ```motoko include=import\n /// var sum = 0;\n /// for (x in Iter.singleton(3))\n /// sum += x;\n /// assert sum == 3;\n /// ```\n public func singleton<T>(value : T) : Iter<T> {\n object {\n var state = ?value;\n public func next() : ?T {\n switch state {\n case null null;\n case some {\n state := null;\n some\n }\n }\n }\n }\n };\n\n /// Calls a function `f` on every value produced by an iterator and discards\n /// the results. If you're looking to keep these results use `map` instead.\n ///\n /// ```motoko include=import\n /// var sum = 0;\n /// Iter.forEach<Nat>([1, 2, 3].values(), func(x) {\n /// sum += x;\n /// });\n /// assert sum == 6;\n /// ```\n public func forEach<T>(\n iter : Iter<T>,\n f : (T) -> ()\n ) {\n label l loop {\n switch (iter.next()) {\n case (?next) {\n f(next)\n };\n case (null) {\n break l\n }\n }\n }\n };\n\n /// Takes an iterator and returns a new iterator that pairs each element with its index.\n /// The index starts at 0 and increments by 1 for each element.\n ///\n /// ```motoko include=import\n /// let iter = Iter.fromArray([\"A\", \"B\", \"C\"]);\n /// let enumerated = Iter.enumerate(iter);\n /// let result = Iter.toArray(enumerated);\n /// assert result == [(0, \"A\"), (1, \"B\"), (2, \"C\")];\n /// ```\n public func enumerate<T>(iter : Iter<T>) : Iter<(Nat, T)> {\n object {\n var i = 0;\n public func next() : ?(Nat, T) {\n switch (iter.next()) {\n case (?x) {\n let current = (i, x);\n i += 1;\n ?current\n };\n case null { null }\n }\n }\n }\n };\n\n /// Creates a new iterator that yields every nth element from the original iterator.\n /// If `interval` is 0, returns an empty iterator. If `interval` is 1, returns the original iterator.\n /// For any other positive interval, returns an iterator that skips `interval - 1` elements after each yielded element.\n ///\n /// ```motoko include=import\n /// let iter = Iter.fromArray([1, 2, 3, 4, 5, 6]);\n /// let steppedIter = Iter.step(iter, 2); // Take every 2nd element\n /// assert ?1 == steppedIter.next();\n /// assert ?3 == steppedIter.next();\n /// assert ?5 == steppedIter.next();\n /// assert null == steppedIter.next();\n /// ```\n public func step<T>(iter : Iter<T>, n : Nat) : Iter<T> {\n if (n == 0) {\n empty()\n } else if (n == 1) {\n iter\n } else {\n object {\n public func next() : ?T {\n let item = iter.next();\n var i = 1;\n while (i < n) {\n ignore iter.next();\n i += 1\n };\n item\n }\n }\n }\n };\n\n /// Consumes an iterator and counts how many elements were produced (discarding them in the process).\n /// ```motoko include=import\n /// let iter = [1, 2, 3].values();\n /// assert 3 == Iter.size(iter);\n /// ```\n public func size<T>(iter : Iter<T>) : Nat {\n var len = 0;\n forEach<T>(iter, func(x) { len += 1 });\n len\n };\n\n /// Takes a function and an iterator and returns a new iterator that lazily applies\n /// the function to every element produced by the argument iterator.\n /// ```motoko include=import\n /// let iter = [1, 2, 3].values();\n /// let mappedIter = Iter.map<Nat, Nat>(iter, func (x) = x * 2);\n /// let result = Iter.toArray(mappedIter);\n /// assert result == [2, 4, 6];\n /// ```\n public func map<T, R>(iter : Iter<T>, f : T -> R) : Iter<R> = object {\n public func next() : ?R {\n switch (iter.next()) {\n case (?next) {\n ?f(next)\n };\n case (null) {\n null\n }\n }\n }\n };\n\n /// Creates a new iterator that only includes elements from the original iterator\n /// for which the predicate function returns true.\n ///\n /// ```motoko include=import\n /// let iter = [1, 2, 3, 4, 5].values();\n /// let evenNumbers = Iter.filter<Nat>(iter, func (x) = x % 2 == 0);\n /// let result = Iter.toArray(evenNumbers);\n /// assert result == [2, 4];\n /// ```\n public func filter<T>(iter : Iter<T>, f : T -> Bool) : Iter<T> = object {\n public func next() : ?T {\n loop {\n let ?x = iter.next() else return null;\n if (f x) return ?x\n };\n null\n }\n };\n\n /// Creates a new iterator by applying a transformation function to each element\n /// of the original iterator. Elements for which the function returns null are\n /// excluded from the result.\n ///\n /// ```motoko include=import\n /// let iter = [1, 2, 3].values();\n /// let evenNumbers = Iter.filterMap<Nat, Nat>(iter, func (x) = if (x % 2 == 0) ?x else null);\n /// let result = Iter.toArray(evenNumbers);\n /// assert result == [2];\n /// ```\n public func filterMap<T, R>(iter : Iter<T>, f : T -> ?R) : Iter<R> = object {\n public func next() : ?R {\n loop {\n let ?x = iter.next() else return null;\n switch (f x) {\n case (?r) return ?r;\n case null {} // continue\n }\n }\n }\n };\n\n /// Flattens an iterator of iterators into a single iterator by concatenating the inner iterators.\n ///\n /// Possible optimization: Use `flatMap` when you need to transform elements before calling `flatten`. Example: use `flatMap(...)` instead of `flatten(map(...))`.\n /// ```motoko include=import\n /// let iter = Iter.flatten([[1, 2].values(), [3].values(), [4, 5, 6].values()].values());\n /// let result = Iter.toArray(iter);\n /// assert result == [1, 2, 3, 4, 5, 6];\n /// ```\n public func flatten<T>(iter : Iter<Iter<T>>) : Iter<T> = object {\n var current : Iter<T> = empty();\n public func next() : ?T {\n loop {\n switch (current.next()) {\n case (?x) return ?x;\n case null {\n let ?next = iter.next() else return null;\n current := next\n }\n }\n }\n }\n };\n\n /// Transforms every element of an iterator into an iterator and concatenates the results.\n /// ```motoko include=import\n /// let iter = Iter.flatMap<Nat, Nat>([1, 3, 5].values(), func (x) = [x, x + 1].values());\n /// let result = Iter.toArray(iter);\n /// assert result == [1, 2, 3, 4, 5, 6];\n /// ```\n public func flatMap<T, R>(iter : Iter<T>, f : T -> Iter<R>) : Iter<R> = object {\n var current : Iter<R> = empty();\n public func next() : ?R {\n loop {\n switch (current.next()) {\n case (?x) return ?x;\n case null {\n let ?next = iter.next() else return null;\n current := f(next)\n }\n }\n }\n }\n };\n\n /// Returns a new iterator that yields at most, first `n` elements from the original iterator.\n /// After `n` elements have been produced or the original iterator is exhausted,\n /// subsequent calls to `next()` will return `null`.\n ///\n /// ```motoko include=import\n /// let iter = Iter.fromArray([1, 2, 3, 4, 5]);\n /// let first3 = Iter.take(iter, 3);\n /// let result = Iter.toArray(first3);\n /// assert result == [1, 2, 3];\n /// ```\n ///\n /// ```motoko include=import\n /// let iter = Iter.fromArray([1, 2, 3]);\n /// let first5 = Iter.take(iter, 5);\n /// let result = Iter.toArray(first5);\n /// assert result == [1, 2, 3]; // only 3 elements in the original iterator\n /// ```\n public func take<T>(iter : Iter<T>, n : Nat) : Iter<T> = object {\n var remaining = n;\n public func next() : ?T {\n if (remaining == 0) return null;\n remaining -= 1;\n iter.next()\n }\n };\n\n /// Returns a new iterator that yields elements from the original iterator until the predicate function returns false.\n /// The first element for which the predicate returns false is not included in the result.\n ///\n /// ```motoko include=import\n /// let iter = Iter.fromArray([1, 2, 3, 4, 5, 4, 3, 2, 1]);\n /// let result = Iter.takeWhile<Nat>(iter, func (x) = x < 4);\n /// let array = Iter.toArray(result);\n /// assert array == [1, 2, 3]; // note the difference between `takeWhile` and `filter`\n /// ```\n public func takeWhile<T>(iter : Iter<T>, f : T -> Bool) : Iter<T> = object {\n var done = false;\n public func next() : ?T {\n if done return null;\n let ?x = iter.next() else return null;\n if (f x) return ?x;\n done := true;\n null\n }\n };\n\n /// Returns a new iterator that skips the first `n` elements from the original iterator.\n /// If the original iterator has fewer than `n` elements, the result will be an empty iterator.\n ///\n /// ```motoko include=import\n /// let iter = Iter.fromArray([1, 2, 3, 4, 5]);\n /// let skipped = Iter.drop(iter, 3);\n /// let result = Iter.toArray(skipped);\n /// assert result == [4, 5];\n /// ```\n public func drop<T>(iter : Iter<T>, n : Nat) : Iter<T> = object {\n var remaining = n;\n public func next() : ?T {\n while (remaining > 0) {\n let ?_ = iter.next() else return null;\n remaining -= 1\n };\n iter.next()\n }\n };\n\n /// Returns a new iterator that skips elements from the original iterator until the predicate function returns false.\n /// The first element for which the predicate returns false is the first element produced by the new iterator.\n ///\n /// ```motoko include=import\n /// let iter = Iter.fromArray([1, 2, 3, 4, 5, 4, 3, 2, 1]);\n /// let result = Iter.dropWhile<Nat>(iter, func (x) = x < 4);\n /// let array = Iter.toArray(result);\n /// assert array == [4, 5, 4, 3, 2, 1]; // notice that `takeWhile` and `dropWhile` are complementary\n /// ```\n public func dropWhile<T>(iter : Iter<T>, f : T -> Bool) : Iter<T> = object {\n var dropping = true;\n public func next() : ?T {\n while dropping {\n let ?x = iter.next() else return null;\n if (not f x) {\n dropping := false;\n return ?x\n }\n };\n iter.next()\n }\n };\n\n /// Zips two iterators into a single iterator that produces pairs of elements.\n /// The resulting iterator will stop producing elements when either of the input iterators is exhausted.\n ///\n /// ```motoko include=import\n /// let iter1 = [1, 2, 3].values();\n /// let iter2 = [\"A\", \"B\"].values();\n /// let zipped = Iter.zip(iter1, iter2);\n /// let result = Iter.toArray(zipped);\n /// assert result == [(1, \"A\"), (2, \"B\")]; // note that the third element from iter1 is not included, because iter2 is exhausted\n /// ```\n public func zip<A, B>(a : Iter<A>, b : Iter<B>) : Iter<(A, B)> = object {\n public func next() : ?(A, B) {\n let ?x = a.next() else return null;\n let ?y = b.next() else return null;\n ?(x, y)\n }\n };\n\n /// Zips three iterators into a single iterator that produces triples of elements.\n /// The resulting iterator will stop producing elements when any of the input iterators is exhausted.\n ///\n /// ```motoko include=import\n /// let iter1 = [\"A\", \"B\"].values();\n /// let iter2 = [\"1\", \"2\", \"3\"].values();\n /// let iter3 = [\"x\", \"y\", \"z\", \"xd\"].values();\n /// let zipped = Iter.zip3(iter1, iter2, iter3);\n /// let result = Iter.toArray(zipped);\n /// assert result == [(\"A\", \"1\", \"x\"), (\"B\", \"2\", \"y\")]; // note that the unmatched elements from iter2 and iter3 are not included\n /// ```\n public func zip3<A, B, C>(a : Iter<A>, b : Iter<B>, c : Iter<C>) : Iter<(A, B, C)> = object {\n public func next() : ?(A, B, C) {\n let ?x = a.next() else return null;\n let ?y = b.next() else return null;\n let ?z = c.next() else return null;\n ?(x, y, z)\n }\n };\n\n /// Zips two iterators into a single iterator by applying a function to zipped pairs of elements.\n /// The resulting iterator will stop producing elements when either of the input iterators is exhausted.\n ///\n /// ```motoko include=import\n /// let iter1 = [\"A\", \"B\"].values();\n /// let iter2 = [\"1\", \"2\", \"3\"].values();\n /// let zipped = Iter.zipWith<Text, Text, Text>(iter1, iter2, func (a, b) = a # b);\n /// let result = Iter.toArray(zipped);\n /// assert result == [\"A1\", \"B2\"]; // note that the third element from iter2 is not included, because iter1 is exhausted\n /// ```\n public func zipWith<A, B, R>(a : Iter<A>, b : Iter<B>, f : (A, B) -> R) : Iter<R> = object {\n public func next() : ?R {\n let ?x = a.next() else return null;\n let ?y = b.next() else return null;\n ?f(x, y)\n }\n };\n\n /// Zips three iterators into a single iterator by applying a function to zipped triples of elements.\n /// The resulting iterator will stop producing elements when any of the input iterators is exhausted.\n ///\n /// ```motoko include=import\n /// let iter1 = [\"A\", \"B\"].values();\n /// let iter2 = [\"1\", \"2\", \"3\"].values();\n /// let iter3 = [\"x\", \"y\", \"z\", \"xd\"].values();\n /// let zipped = Iter.zipWith3<Text, Text, Text, Text>(iter1, iter2, iter3, func (a, b, c) = a # b # c);\n /// let result = Iter.toArray(zipped);\n /// assert result == [\"A1x\", \"B2y\"]; // note that the unmatched elements from iter2 and iter3 are not included\n /// ```\n public func zipWith3<A, B, C, R>(a : Iter<A>, b : Iter<B>, c : Iter<C>, f : (A, B, C) -> R) : Iter<R> = object {\n public func next() : ?R {\n let ?x = a.next() else return null;\n let ?y = b.next() else return null;\n let ?z = c.next() else return null;\n ?f(x, y, z)\n }\n };\n\n /// Checks if a predicate function is true for all elements produced by an iterator.\n /// It stops consuming elements from the original iterator as soon as the predicate returns false.\n ///\n /// ```motoko include=import\n /// assert Iter.all<Nat>([1, 2, 3].values(), func (x) = x < 4);\n /// assert not Iter.all<Nat>([1, 2, 3].values(), func (x) = x < 3);\n /// ```\n public func all<T>(iter : Iter<T>, f : T -> Bool) : Bool {\n for (x in iter) {\n if (not f x) return false\n };\n true\n };\n\n /// Checks if a predicate function is true for any element produced by an iterator.\n /// It stops consuming elements from the original iterator as soon as the predicate returns true.\n ///\n /// ```motoko include=import\n /// assert Iter.any<Nat>([1, 2, 3].values(), func (x) = x == 2);\n /// assert not Iter.any<Nat>([1, 2, 3].values(), func (x) = x == 4);\n /// ```\n public func any<T>(iter : Iter<T>, f : T -> Bool) : Bool {\n for (x in iter) {\n if (f x) return true\n };\n false\n };\n\n /// Finds the first element produced by an iterator for which a predicate function returns true.\n /// Returns `null` if no such element is found.\n /// It stops consuming elements from the original iterator as soon as the predicate returns true.\n ///\n /// ```motoko include=import\n /// let iter = [1, 2, 3, 4].values();\n /// assert ?2 == Iter.find<Nat>(iter, func (x) = x % 2 == 0);\n /// ```\n public func find<T>(iter : Iter<T>, f : T -> Bool) : ?T {\n for (x in iter) {\n if (f x) return ?x\n };\n null\n };\n\n /// Returns the first index in `array` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let iter = ['A', 'B', 'C', 'D'].values();\n /// let found = Iter.findIndex<Char>(iter, func(x) { x == 'C' });\n /// assert found == ?2;\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func findIndex<T>(iter : Iter<T>, predicate : T -> Bool) : ?Nat {\n for ((index, element) in enumerate(iter)) {\n if (predicate element) {\n return ?index\n }\n };\n null\n };\n\n /// Checks if an element is produced by an iterator.\n /// It stops consuming elements from the original iterator as soon as the predicate returns true.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let iter = [1, 2, 3, 4].values();\n /// assert Iter.contains<Nat>(iter, Nat.equal, 2);\n /// ```\n public func contains<T>(iter : Iter<T>, equal : (T, T) -> Bool, value : T) : Bool {\n for (x in iter) {\n if (equal(x, value)) return true\n };\n false\n };\n\n /// Reduces an iterator to a single value by applying a function to each element and an accumulator.\n /// The accumulator is initialized with the `initial` value.\n /// It starts applying the `combine` function starting from the `initial` accumulator value and the first elements produced by the iterator.\n ///\n /// ```motoko include=import\n /// let iter = [\"A\", \"B\", \"C\"].values();\n /// let result = Iter.foldLeft<Text, Text>(iter, \"S\", func (acc, x) = \"(\" # acc # x # \")\");\n /// assert result == \"(((SA)B)C)\";\n /// ```\n public func foldLeft<T, R>(iter : Iter<T>, initial : R, combine : (R, T) -> R) : R {\n var acc = initial;\n for (x in iter) {\n acc := combine(acc, x)\n };\n acc\n };\n\n /// Reduces an iterator to a single value by applying a function to each element in reverse order and an accumulator.\n /// The accumulator is initialized with the `initial` value and it is first combined with the last element produced by the iterator.\n /// It starts applying the `combine` function starting from the last elements produced by the iterator.\n ///\n /// **Performance note**: Since this function needs to consume the entire iterator to reverse it,\n /// it has to materialize the entire iterator in memory to get to the last element to start applying the `combine` function.\n /// **Use `foldLeft` or `reduce` when possible to avoid the extra memory overhead**.\n ///\n /// ```motoko include=import\n /// let iter = [\"A\", \"B\", \"C\"].values();\n /// let result = Iter.foldRight<Text, Text>(iter, \"S\", func (x, acc) = \"(\" # x # acc # \")\");\n /// assert result == \"(A(B(CS)))\";\n /// ```\n public func foldRight<T, R>(iter : Iter<T>, initial : R, combine : (T, R) -> R) : R {\n foldLeft<T, R>(reverse(iter), initial, func(acc, x) = combine(x, acc))\n };\n\n /// Reduces an iterator to a single value by applying a function to each element, starting with the first elements.\n /// The accumulator is initialized with the first element produced by the iterator.\n /// When the iterator is empty, it returns `null`.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let iter = [1, 2, 3].values();\n /// assert ?6 == Iter.reduce<Nat>(iter, Nat.add);\n /// ```\n public func reduce<T>(iter : Iter<T>, combine : (T, T) -> T) : ?T {\n let ?first = iter.next() else return null;\n ?foldLeft(iter, first, combine)\n };\n\n /// Produces an iterator containing cumulative results of applying the `combine` operator going left to right, including the `initial` value.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let iter = [1, 2, 3].values();\n /// let scanned = Iter.scanLeft<Nat, Nat>(iter, 0, Nat.add);\n /// let result = Iter.toArray(scanned);\n /// assert result == [0, 1, 3, 6];\n /// ```\n public func scanLeft<T, R>(iter : Iter<T>, initial : R, combine : (R, T) -> R) : Iter<R> = object {\n var acc = initial;\n var isInitial = true;\n public func next() : ?R {\n if (isInitial) {\n isInitial := false;\n return ?acc\n };\n switch (iter.next()) {\n case (?x) {\n acc := combine(acc, x);\n ?acc\n };\n case null null\n }\n }\n };\n\n /// Produces an iterator containing cumulative results of applying the `combine` operator going right to left, including the `initial` value.\n ///\n /// **Performance note**: Since this function needs to consume the entire iterator to reverse it,\n /// it has to materialize the entire iterator in memory to get to the last element to start applying the `combine` function.\n /// **Use `scanLeft` when possible to avoid the extra memory overhead**.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let iter = [1, 2, 3].values();\n /// let scanned = Iter.scanRight<Nat, Nat>(iter, 0, Nat.add);\n /// let result = Iter.toArray(scanned);\n /// assert result == [0, 3, 5, 6];\n /// ```\n public func scanRight<T, R>(iter : Iter<T>, initial : R, combine : (T, R) -> R) : Iter<R> {\n scanLeft<T, R>(reverse(iter), initial, func(x, acc) = combine(acc, x))\n };\n\n /// Creates an iterator that produces elements using the `step` function starting from the `initial` value.\n /// The `step` function takes the current state and returns the next element and the next state, or `null` if the iteration is finished.\n ///\n /// ```motoko include=import\n /// let iter = Iter.unfold<Nat, Nat>(1, func (x) = if (x <= 3) ?(x, x + 1) else null);\n /// let result = Iter.toArray(iter);\n /// assert result == [1, 2, 3];\n /// ```\n public func unfold<T, S>(initial : S, step : S -> ?(T, S)) : Iter<T> = object {\n var state = initial;\n public func next() : ?T {\n let ?(t, next) = step(state) else return null;\n state := next;\n ?t\n }\n };\n\n // todo: unfold, iterate, cycle, range, rangeStep, rangeStepTo, rangeStepToExclusive\n\n /// Consumes an iterator and returns the first maximum element produced by the iterator.\n /// If the iterator is empty, it returns `null`.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let iter = [1, 2, 3].values();\n /// assert ?3 == Iter.max<Nat>(iter, Nat.compare);\n /// ```\n public func max<T>(iter : Iter<T>, compare : (T, T) -> Order.Order) : ?T {\n reduce<T>(\n iter,\n func(a, b) {\n switch (compare(a, b)) {\n case (#less) b;\n case _ a\n }\n }\n )\n };\n\n /// Consumes an iterator and returns the first minimum element produced by the iterator.\n /// If the iterator is empty, it returns `null`.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let iter = [1, 2, 3].values();\n /// assert ?1 == Iter.min<Nat>(iter, Nat.compare);\n /// ```\n public func min<T>(iter : Iter<T>, compare : (T, T) -> Order.Order) : ?T {\n reduce<T>(\n iter,\n func(a, b) {\n switch (compare(a, b)) {\n case (#greater) b;\n case _ a\n }\n }\n )\n };\n\n /// Creates an iterator that produces an infinite sequence of `x`.\n /// ```motoko include=import\n /// let iter = Iter.infinite(10);\n /// assert ?10 == iter.next();\n /// assert ?10 == iter.next();\n /// assert ?10 == iter.next();\n /// // ...\n /// ```\n public func infinite<T>(item : T) : Iter<T> = object {\n public func next() : ?T {\n ?item\n }\n };\n\n /// Takes two iterators and returns a new iterator that produces\n /// elements from the original iterators sequentally.\n /// ```motoko include=import\n /// let iter1 = [1, 2].values();\n /// let iter2 = [5, 6, 7].values();\n /// let concatenatedIter = Iter.concat(iter1, iter2);\n /// let result = Iter.toArray(concatenatedIter);\n /// assert result == [1, 2, 5, 6, 7];\n /// ```\n public func concat<T>(a : Iter<T>, b : Iter<T>) : Iter<T> {\n var aEnded : Bool = false;\n object {\n public func next() : ?T {\n if (aEnded) {\n return b.next()\n };\n switch (a.next()) {\n case (?x) ?x;\n case (null) {\n aEnded := true;\n b.next()\n }\n }\n }\n }\n };\n\n /// Creates an iterator that produces the elements of an Array in ascending index order.\n /// ```motoko include=import\n /// let iter = Iter.fromArray([1, 2, 3]);\n /// assert ?1 == iter.next();\n /// assert ?2 == iter.next();\n /// assert ?3 == iter.next();\n /// assert null == iter.next();\n /// ```\n public func fromArray<T>(array : [T]) : Iter<T> = array.vals();\n\n /// Like `fromArray` but for Arrays with mutable elements. Captures\n /// the elements of the Array at the time the iterator is created, so\n /// further modifications won't be reflected in the iterator.\n public func fromVarArray<T>(array : [var T]) : Iter<T> = array.vals();\n\n /// Consumes an iterator and collects its produced elements in an Array.\n /// ```motoko include=import\n /// let iter = [1, 2, 3].values();\n /// assert [1, 2, 3] == Iter.toArray(iter);\n /// ```\n public func toArray<T>(iter : Iter<T>) : [T] {\n // TODO: Replace implementation. This is just temporay.\n type Node<T> = { value : T; var next : ?Node<T> };\n var first : ?Node<T> = null;\n var last : ?Node<T> = null;\n var count = 0;\n\n func add(value : T) {\n let node : Node<T> = { value; var next = null };\n switch (last) {\n case null {\n first := ?node\n };\n case (?previous) {\n previous.next := ?node\n }\n };\n last := ?node;\n count += 1\n };\n\n for (value in iter) {\n add(value)\n };\n if (count == 0) {\n return []\n };\n var current = first;\n Prim.Array_tabulate<T>(\n count,\n func(_) {\n switch (current) {\n case null Runtime.trap(\"Iter.toArray(): node must not be null\");\n case (?node) {\n current := node.next;\n node.value\n }\n }\n }\n )\n };\n\n /// Like `toArray` but for Arrays with mutable elements.\n public func toVarArray<T>(iter : Iter<T>) : [var T] {\n Array.toVarArray<T>(toArray<T>(iter))\n };\n\n /// Sorted iterator. Will iterate over *all* elements to sort them, necessarily.\n public func sort<T>(iter : Iter<T>, compare : (T, T) -> Order.Order) : Iter<T> {\n let array = toVarArray<T>(iter);\n VarArray.sortInPlace<T>(array, compare);\n fromVarArray<T>(array)\n };\n\n /// Creates an iterator that produces a given item a specified number of times.\n /// ```motoko include=import\n /// let iter = Iter.repeat<Nat>(3, 2);\n /// assert ?3 == iter.next();\n /// assert ?3 == iter.next();\n /// assert null == iter.next();\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func repeat<T>(item : T, count : Nat) : Iter<T> = object {\n var remaining = count;\n public func next() : ?T {\n if (remaining == 0) {\n null\n } else {\n remaining -= 1;\n ?item\n }\n }\n };\n\n /// Creates a new iterator that produces elements from the original iterator in reverse order.\n /// Note: This function needs to consume the entire iterator to reverse it.\n /// ```motoko include=import\n /// let iter = Iter.fromArray([1, 2, 3]);\n /// let reversed = Iter.reverse(iter);\n /// assert ?3 == reversed.next();\n /// assert ?2 == reversed.next();\n /// assert ?1 == reversed.next();\n /// assert null == reversed.next();\n /// ```\n ///\n /// Runtime: O(n) where n is the number of elements in the iterator\n ///\n /// Space: O(n) where n is the number of elements in the iterator\n public func reverse<T>(iter : Iter<T>) : Iter<T> {\n var acc : Types.Pure.List<T> = null;\n for (x in iter) {\n acc := ?(x, acc)\n };\n object {\n public func next() : ?T {\n switch acc {\n case null null;\n case (?(h, t)) {\n acc := t;\n ?h\n }\n }\n }\n }\n };\n\n}\n"},"Func.mo":{"content":"/// Functions on functions, creating functions from simpler inputs.\n///\n/// (Most commonly used when programming in functional style using higher-order\n/// functions.)\n///\n/// Import from the core library to use this module.\n///\n/// ```motoko name=import\n/// import Func = \"mo:core/Func\";\n/// ```\n\nmodule {\n\n /// The composition of two functions `f` and `g` is a function that applies `g` and then `f`.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Text \"mo:core/Text\";\n /// import Char \"mo:core/Char\";\n ///\n /// let textFromNat32 = Func.compose(Text.fromChar, Char.fromNat32);\n /// assert textFromNat32(65) == \"A\";\n /// ```\n public func compose<A, B, C>(f : B -> C, g : A -> B) : A -> C {\n func(x : A) : C {\n f(g(x))\n }\n };\n\n /// The `identity` function returns its argument.\n /// Example:\n /// ```motoko include=import\n /// assert Func.identity(10) == 10;\n /// assert Func.identity(true) == true;\n /// ```\n public func identity<A>(x : A) : A = x;\n\n /// The const function is a _curried_ function that accepts an argument `x`,\n /// and then returns a function that discards its argument and always returns\n /// the `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Func.const<Nat, Text>(10)(\"hello\") == 10;\n /// assert Func.const(true)(20) == true;\n /// ```\n public func const<A, B>(x : A) : B -> A = func _ = x\n}\n"},"Runtime.mo":{"content":"/// Runtime utilities.\n/// These functions were originally part of the `Debug` module.\n///\n/// ```motoko name=import\n/// import Runtime \"mo:core/Runtime\";\n/// ```\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// `trap(t)` traps execution with a user-provided diagnostic message.\n ///\n /// The caller of a future whose execution called `trap(t)` will\n /// observe the trap as an `Error` value, thrown at `await`, with code\n /// `#canister_error` and message `m`. Here `m` is a more descriptive `Text`\n /// message derived from the provided `t`. See example for more details.\n ///\n /// NOTE: Other execution environments that cannot handle traps may only\n /// propagate the trap and terminate execution, with or without some\n /// descriptive message.\n ///\n /// ```motoko include=import no-validate\n /// Runtime.trap(\"An error occurred!\");\n /// ```\n public func trap(errorMessage : Text) : None {\n Prim.trap errorMessage\n };\n\n /// `unreachable()` traps execution when code that should be unreachable is reached.\n ///\n /// This function is useful for marking code paths that should never be executed,\n /// such as after exhaustive pattern matches or unreachable control flow branches.\n /// If execution reaches this function, it indicates a programming error.\n ///\n /// ```motoko include=import no-validate\n /// let number = switch (?5) {\n /// case (?n) n;\n /// case null Runtime.unreachable();\n /// };\n /// assert number == 5;\n /// ```\n public func unreachable() : None {\n trap(\"Runtime.unreachable()\")\n };\n\n}\n"},"Blob.mo":{"content":"/// Module for working with Blobs (immutable sequences of bytes).\n///\n/// Blobs represent sequences of bytes. They are immutable, iterable, but not indexable and can be empty.\n///\n/// Byte sequences are also often represented as `[Nat8]`, i.e. an array of bytes, but this representation is currently much less compact than `Blob`, taking 4 physical bytes to represent each logical byte in the sequence.\n/// If you would like to manipulate Blobs, it is recommended that you convert\n/// Blobs to `[var Nat8]` or `Buffer<Nat8>`, do the manipulation, then convert back.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Blob \"mo:core/Blob\";\n/// ```\n///\n/// Some built in features not listed in this module:\n///\n/// * You can create a `Blob` literal from a `Text` literal, provided the context expects an expression of type `Blob`.\n/// * `b.size() : Nat` returns the number of bytes in the blob `b`;\n/// * `b.values() : Iter.Iter<Nat8>` returns an iterator to enumerate the bytes of the blob `b`.\n///\n/// For example:\n/// ```motoko include=import\n/// import Debug \"mo:core/Debug\";\n/// import Nat8 \"mo:core/Nat8\";\n///\n/// let blob = \"\\00\\00\\00\\ff\" : Blob; // blob literals, where each byte is delimited by a back-slash and represented in hex\n/// let blob2 = \"charsもあり\" : Blob; // you can also use characters in the literals\n/// let numBytes = blob.size();\n/// assert numBytes == 4; // returns the number of bytes in the Blob\n/// for (byte in blob.values()) { // iterator over the Blob\n/// Debug.print(Nat8.toText(byte))\n/// }\n/// ```\n\nimport Types \"Types\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n public type Blob = Prim.Types.Blob;\n\n /// Returns an empty `Blob` (equivalent to `\"\"`).\n ///\n /// Example:\n /// ```motoko include=import\n /// let emptyBlob = Blob.empty();\n /// assert emptyBlob.size() == 0;\n /// ```\n public func empty() : Blob = \"\";\n\n /// Returns whether the given `Blob` is empty (has a size of zero).\n ///\n /// ```motoko include=import\n /// let blob1 = \"\" : Blob;\n /// let blob2 = \"\\FF\\00\" : Blob;\n /// assert Blob.isEmpty(blob1);\n /// assert not Blob.isEmpty(blob2);\n /// ```\n public func isEmpty(blob : Blob) : Bool = blob == \"\";\n\n /// Returns the number of bytes in the given `Blob`.\n /// This is equivalent to `blob.size()`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\FF\\00\\AA\" : Blob;\n /// assert Blob.size(blob) == 3;\n /// assert blob.size() == 3;\n /// ```\n public func size(blob : Blob) : Nat = blob.size();\n\n /// Creates a `Blob` from an array of bytes (`[Nat8]`), by copying each element.\n ///\n /// Example:\n /// ```motoko include=import\n /// let bytes : [Nat8] = [0, 255, 0];\n /// let blob = Blob.fromArray(bytes);\n /// assert blob == \"\\00\\FF\\00\";\n /// ```\n public func fromArray(bytes : [Nat8]) : Blob = Prim.arrayToBlob bytes;\n\n /// Creates a `Blob` from a mutable array of bytes (`[var Nat8]`), by copying each element.\n ///\n /// Example:\n /// ```motoko include=import\n /// let bytes : [var Nat8] = [var 0, 255, 0];\n /// let blob = Blob.fromVarArray(bytes);\n /// assert blob == \"\\00\\FF\\00\";\n /// ```\n public func fromVarArray(bytes : [var Nat8]) : Blob = Prim.arrayMutToBlob bytes;\n\n /// Converts a `Blob` to an array of bytes (`[Nat8]`), by copying each element.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// let bytes = Blob.toArray(blob);\n /// assert bytes == [0, 255, 0];\n /// ```\n public func toArray(blob : Blob) : [Nat8] = Prim.blobToArray blob;\n\n /// Converts a `Blob` to a mutable array of bytes (`[var Nat8]`), by copying each element.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat8 \"mo:core/Nat8\";\n /// import VarArray \"mo:core/VarArray\";\n ///\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// let bytes = Blob.toVarArray(blob);\n /// assert VarArray.equal<Nat8>(bytes, [var 0, 255, 0], Nat8.equal);\n /// ```\n public func toVarArray(blob : Blob) : [var Nat8] = Prim.blobToArrayMut blob;\n\n /// Returns the (non-cryptographic) hash of `blob`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// let h = Blob.hash(blob);\n /// assert h == 1_818_567_776;\n /// ```\n public func hash(blob : Blob) : Types.Hash = Prim.hashBlob blob;\n\n /// General purpose comparison function for `Blob` by comparing the value of\n /// the bytes. Returns the `Order` (either `#less`, `#equal`, or `#greater`)\n /// by comparing `blob1` with `blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\00\\00\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// let result = Blob.compare(blob1, blob2);\n /// assert result == #less;\n /// ```\n public func compare(b1 : Blob, b2 : Blob) : Order.Order {\n let c = Prim.blobCompare(b1, b2);\n if (c < 0) #less else if (c == 0) #equal else #greater\n };\n\n /// Equality function for `Blob` types.\n /// This is equivalent to `blob1 == blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\FF\\00\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// assert Blob.equal(blob1, blob2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import List \"mo:core/List\";\n ///\n /// let list1 = List.singleton<Blob>(\"\\00\\FF\\00\");\n /// let list2 = List.singleton<Blob>(\"\\00\\FF\\00\");\n /// assert List.equal(list1, list2, Blob.equal);\n /// ```\n public func equal(blob1 : Blob, blob2 : Blob) : Bool { blob1 == blob2 };\n\n /// Inequality function for `Blob` types.\n /// This is equivalent to `blob1 != blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// assert Blob.notEqual(blob1, blob2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func notEqual(blob1 : Blob, blob2 : Blob) : Bool { blob1 != blob2 };\n\n /// \"Less than\" function for `Blob` types.\n /// This is equivalent to `blob1 < blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// assert Blob.less(blob1, blob2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func less(blob1 : Blob, blob2 : Blob) : Bool { blob1 < blob2 };\n\n /// \"Less than or equal to\" function for `Blob` types.\n /// This is equivalent to `blob1 <= blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// assert Blob.lessOrEqual(blob1, blob2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func lessOrEqual(blob1 : Blob, blob2 : Blob) : Bool { blob1 <= blob2 };\n\n /// \"Greater than\" function for `Blob` types.\n /// This is equivalent to `blob1 > blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\BB\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\00\\00\" : Blob;\n /// assert Blob.greater(blob1, blob2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func greater(blob1 : Blob, blob2 : Blob) : Bool { blob1 > blob2 };\n\n /// \"Greater than or equal to\" function for `Blob` types.\n /// This is equivalent to `blob1 >= blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\BB\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\00\\00\" : Blob;\n /// assert Blob.greaterOrEqual(blob1, blob2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function value\n /// to pass to a higher order function.\n public func greaterOrEqual(blob1 : Blob, blob2 : Blob) : Bool {\n blob1 >= blob2\n };\n\n}\n"},"Random.mo":{"content":"/// Random number generation.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Random \"mo:core/Random\";\n/// ```\n\nimport Array \"Array\";\nimport VarArray \"VarArray\";\nimport Nat8 \"Nat8\";\nimport Nat64 \"Nat64\";\nimport Int \"Int\";\nimport Nat \"Nat\";\nimport Blob \"Blob\";\nimport Runtime \"Runtime\";\n\nmodule {\n\n public type State = {\n var bytes : [Nat8];\n var index : Nat;\n var bits : Nat8;\n var bitMask : Nat8\n };\n\n public type SeedState = {\n random : State;\n prng : PRNG.State\n };\n\n let rawRand = (actor \"aaaaa-aa\" : actor { raw_rand : () -> async Blob }).raw_rand;\n\n public let blob : shared () -> async Blob = rawRand;\n\n /// Initializes a random number generator state. This is used\n /// to create a `Random` or `AsyncRandom` instance with a specific state.\n /// The state is empty, but it can be reused after upgrading the canister.\n ///\n /// Example:\n /// ```motoko\n /// import Random \"mo:core/Random\";\n ///\n /// persistent actor {\n /// let state = Random.emptyState();\n /// transient let random = Random.cryptoFromState(state);\n ///\n /// public func main() : async () {\n /// let coin = await* random.bool(); // true or false\n /// }\n /// }\n /// ```\n public func emptyState() : State = {\n var bytes = [];\n var index = 0;\n var bits = 0x00;\n var bitMask = 0x00\n };\n\n /// Initializes a pseudo-random number generator state with a 64-bit seed.\n /// This is used to create a `Random` instance with a specific seed.\n /// The seed is used to initialize the PRNG state.\n ///\n /// Example:\n /// ```motoko\n /// import Random \"mo:core/Random\";\n ///\n /// persistent actor {\n /// let state = Random.seedState(123);\n /// transient let random = Random.seedFromState(state);\n ///\n /// public func main() : async () {\n /// let coin = random.bool(); // true or false\n /// }\n /// }\n /// ```\n public func seedState(seed : Nat64) : SeedState = {\n random = emptyState();\n prng = PRNG.init(seed)\n };\n\n /// Creates a pseudo-random number generator from a 64-bit seed.\n /// The seed is used to initialize the PRNG state.\n /// This is suitable for simulations and testing, but not for cryptographic purposes.\n ///\n /// Example:\n /// ```motoko include=import\n /// let random = Random.seed(123);\n /// let coin = random.bool(); // true or false\n /// ```\n public func seed(seed : Nat64) : Random {\n seedFromState(seedState(seed))\n };\n\n /// Creates a pseudo-random number generator with the given state.\n /// This provides statistical randomness suitable for simulations and testing,\n /// but should not be used for cryptographic purposes.\n ///\n /// Example:\n /// ```motoko\n /// import Random \"mo:core/Random\";\n ///\n /// persistent actor {\n /// let state = Random.seedState(123);\n /// transient let random = Random.seedFromState(state);\n ///\n /// public func main() : async () {\n /// let coin = random.bool(); // true or false\n /// }\n /// }\n /// ```\n public func seedFromState(state : SeedState) : Random {\n Random(\n state.random,\n func() : Blob {\n // Generate 8 bytes directly from a single 64-bit number\n let n = PRNG.next(state.prng);\n // TODO: optimize using Array.tabulate or even better: a new primitive\n let bytes = VarArray.repeat<Nat8>(0, 8);\n bytes[0] := Nat8.fromNat(Nat64.toNat(n & 0xFF));\n bytes[1] := Nat8.fromNat(Nat64.toNat((n >> 8) & 0xFF));\n bytes[2] := Nat8.fromNat(Nat64.toNat((n >> 16) & 0xFF));\n bytes[3] := Nat8.fromNat(Nat64.toNat((n >> 24) & 0xFF));\n bytes[4] := Nat8.fromNat(Nat64.toNat((n >> 32) & 0xFF));\n bytes[5] := Nat8.fromNat(Nat64.toNat((n >> 40) & 0xFF));\n bytes[6] := Nat8.fromNat(Nat64.toNat((n >> 48) & 0xFF));\n bytes[7] := Nat8.fromNat(Nat64.toNat((n >> 56) & 0xFF));\n Blob.fromArray(Array.fromVarArray(bytes))\n }\n )\n };\n\n /// Initializes a cryptographic random number generator\n /// using entropy from the ICP management canister.\n ///\n /// Example:\n /// ```motoko\n /// import Random \"mo:core/Random\";\n ///\n /// persistent actor {\n /// transient let random = Random.crypto();\n ///\n /// public func main() : async () {\n /// let coin = await* random.bool(); // true or false\n /// }\n /// }\n /// ```\n public func crypto() : AsyncRandom {\n cryptoFromState(emptyState())\n };\n\n /// Creates a random number generator suitable for cryptography\n /// using entropy from the ICP management canister. Initializing\n /// from a state makes it possible to reuse entropy after\n /// upgrading the canister.\n ///\n /// Example:\n /// ```motoko\n /// import Random \"mo:core/Random\";\n ///\n /// persistent actor {\n /// let state = Random.emptyState();\n /// transient let random = Random.cryptoFromState(state);\n ///\n /// func example() : async () {\n /// let coin = await* random.bool(); // true or false\n /// }\n /// }\n /// ```\n public func cryptoFromState(state : State) : AsyncRandom {\n AsyncRandom(state, func() : async* Blob { await rawRand() })\n };\n\n public class Random(state : State, generator : () -> Blob) {\n\n func nextBit() : Bool {\n if (0 : Nat8 == state.bitMask) {\n state.bits := nat8();\n state.bitMask := 0x40;\n 0 : Nat8 != state.bits & (0x80 : Nat8)\n } else {\n let m = state.bitMask;\n state.bitMask >>= (1 : Nat8);\n 0 : Nat8 != state.bits & m\n }\n };\n\n /// Random choice between `true` and `false`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let random = Random.seed(42);\n /// let coin = random.bool(); // true or false\n /// ```\n public func bool() : Bool {\n nextBit()\n };\n\n /// Random `Nat8` value in the range [0, 256).\n ///\n /// Example:\n /// ```motoko include=import\n /// let random = Random.seed(42);\n /// let byte = random.nat8(); // 0 to 255\n /// ```\n public func nat8() : Nat8 {\n if (state.index >= state.bytes.size()) {\n let newBytes = Blob.toArray(generator());\n if (newBytes.size() == 0) {\n Runtime.trap(\"Random: generator produced empty Blob\")\n };\n state.bytes := newBytes;\n state.index := 0\n };\n let byte = state.bytes[state.index];\n state.index += 1;\n byte\n };\n\n // Helper function which returns a uniformly sampled `Nat64` in the range `[0, max]`.\n // Uses rejection sampling to ensure uniform distribution even when the range\n // doesn't divide evenly into 2^64. This avoids modulo bias that would occur\n // from simply taking the modulo of a random 64-bit number.\n func uniform64(max : Nat64) : Nat64 {\n if (max == 0) {\n return 0\n };\n // if (max == 1) {\n // return switch (bool()) {\n // case false 0;\n // case true 1\n // }\n // };\n if (max == Nat64.maxValue) {\n return nat64()\n };\n let toExclusive = max + 1;\n // 2^64 - (2^64 % toExclusive) = (2^64-1) - (2^64-1 % toExclusive):\n let cutoff = Nat64.maxValue - (Nat64.maxValue % toExclusive);\n // 2^64 / toExclusive, with toExclusive > 1:\n let multiple = Nat64.fromNat(/* 2^64 */ 0x10000000000000000 / Nat64.toNat(toExclusive));\n loop {\n // Build up a random Nat64 from bytes\n var number = nat64();\n // If number is below cutoff, we can use it\n if (number < cutoff) {\n // Scale down to desired range\n return number / multiple\n };\n // Otherwise reject and try again\n }\n };\n\n /// Random `Nat64` value in the range [0, 2^64).\n ///\n /// Example:\n /// ```motoko include=import\n /// let random = Random.seed(42);\n /// let number = random.nat64(); // 0 to 18446744073709551615\n /// ```\n public func nat64() : Nat64 {\n (Nat64.fromNat(Nat8.toNat(nat8())) << 56) | (Nat64.fromNat(Nat8.toNat(nat8())) << 48) | (Nat64.fromNat(Nat8.toNat(nat8())) << 40) | (Nat64.fromNat(Nat8.toNat(nat8())) << 32) | (Nat64.fromNat(Nat8.toNat(nat8())) << 24) | (Nat64.fromNat(Nat8.toNat(nat8())) << 16) | (Nat64.fromNat(Nat8.toNat(nat8())) << 8) | Nat64.fromNat(Nat8.toNat(nat8()))\n };\n\n /// Random `Nat64` value in the range [fromInclusive, toExclusive).\n ///\n /// Example:\n /// ```motoko include=import\n /// let random = Random.seed(42);\n /// let dice = random.nat64Range(1, 7); // 1 to 6\n /// ```\n public func nat64Range(fromInclusive : Nat64, toExclusive : Nat64) : Nat64 {\n if (fromInclusive >= toExclusive) {\n Runtime.trap(\"Random.nat64Range(): fromInclusive >= toExclusive\")\n };\n uniform64(toExclusive - fromInclusive - 1) + fromInclusive\n };\n\n /// Random `Nat` value in the range [fromInclusive, toExclusive).\n ///\n /// Example:\n /// ```motoko include=import\n /// let random = Random.seed(42);\n /// let index = random.natRange(0, 10); // 0 to 9\n /// ```\n public func natRange(fromInclusive : Nat, toExclusive : Nat) : Nat {\n if (fromInclusive >= toExclusive) {\n Runtime.trap(\"Random.natRange(): fromInclusive >= toExclusive\")\n };\n Nat64.toNat(uniform64(Nat64.fromNat(toExclusive - fromInclusive - 1))) + fromInclusive\n };\n\n public func intRange(fromInclusive : Int, toExclusive : Int) : Int {\n let range = Nat.fromInt(toExclusive - fromInclusive - 1);\n Nat64.toNat(uniform64(Nat64.fromNat(range))) + fromInclusive\n };\n\n };\n\n public class AsyncRandom(state : State, generator : () -> async* Blob) {\n\n func nextBit() : async* Bool {\n if (0 : Nat8 == state.bitMask) {\n state.bits := await* nat8();\n state.bitMask := 0x40;\n 0 : Nat8 != state.bits & (0x80 : Nat8)\n } else {\n let m = state.bitMask;\n state.bitMask >>= (1 : Nat8);\n 0 : Nat8 != state.bits & m\n }\n };\n\n /// Random choice between `true` and `false`.\n public func bool() : async* Bool {\n await* nextBit()\n };\n\n /// Random `Nat8` value in the range [0, 256).\n public func nat8() : async* Nat8 {\n if (state.index >= state.bytes.size()) {\n let newBytes = Blob.toArray(await* generator());\n if (newBytes.size() == 0) {\n Runtime.trap(\"AsyncRandom: generator produced empty Blob\")\n };\n state.bytes := newBytes;\n state.index := 0\n };\n let byte = state.bytes[state.index];\n state.index += 1;\n byte\n };\n\n };\n\n // Derived from https://github.com/research-ag/prng\n module PRNG {\n let p : Nat64 = 24;\n let q : Nat64 = 11;\n let r : Nat64 = 3;\n\n public type State = {\n var a : Nat64;\n var b : Nat64;\n var c : Nat64;\n var d : Nat64\n };\n\n public func init(seed : Nat64) : State {\n init3(seed, seed, seed)\n };\n\n public func init3(seed1 : Nat64, seed2 : Nat64, seed3 : Nat64) : State {\n let state : State = {\n var a = seed1;\n var b = seed2;\n var c = seed3;\n var d = 1\n };\n for (_ in Nat.range(0, 11)) ignore next(state);\n state\n };\n\n public func next(state : State) : Nat64 {\n let tmp = state.a +% state.b +% state.d;\n state.a := state.b ^ (state.b >> q);\n state.b := state.c +% (state.c << r);\n state.c := (state.c <<> p) +% tmp;\n state.d +%= 1;\n tmp\n }\n }\n\n}\n"},"Cycles.mo":{"content":"/// Managing cycles within actors in the Internet Computer Protocol (ICP).\n///\n/// The usage of the Internet Computer is measured, and paid for, in _cycles_.\n/// This library provides imperative operations for observing cycles, transferring cycles, and\n/// observing refunds of cycles.\n///\n/// **NOTE:** Since cycles measure computational resources, the value of `balance()` can change from one call to the next.\n///\n/// Cycles can be transferred from the current actor to another actor with the evaluation of certain forms of expression.\n/// In particular, the expression must be a call to a shared function, a call to a local function with an `async` return type, or a simple `async` expression.\n/// To attach an amount of cycles to an expression `<exp>`, simply prefix the expression with `(with cycles = <amount>)`, that is, `(with cycles = <amount>) <exp>`.\n///\n/// **NOTE:** Attaching cycles will trap if the amount specified exceeds `2 ** 128` cycles.\n///\n/// Upon the call, but not before, the amount of cycles is deducted from `balance()`.\n/// If this total exceeds `balance()`, the caller traps, aborting the call without consuming the cycles.\n/// Note that attaching cycles to a call to a local function call or `async` expression just transfers cycles from the current actor to itself.\n///\n/// Example for use on the ICP:\n/// ```motoko no-repl\n/// import Cycles \"mo:core/Cycles\";\n///\n/// persistent actor {\n/// public func main() : async () {\n/// let initialBalance = Cycles.balance();\n/// await (with cycles = 15_000_000) operation(); // accepts 10_000_000 cycles\n/// assert Cycles.refunded() == 5_000_000;\n/// assert Cycles.balance() < initialBalance; // decreased by around 10_000_000\n/// };\n///\n/// func operation() : async () {\n/// let initialBalance = Cycles.balance();\n/// let initialAvailable = Cycles.available();\n/// let obtained = Cycles.accept<system>(10_000_000);\n/// assert obtained == 10_000_000;\n/// assert Cycles.balance() == initialBalance + 10_000_000;\n/// assert Cycles.available() == initialAvailable - 10_000_000;\n/// }\n/// }\n/// ```\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Returns the actor's current balance of cycles as `amount`.\n ///\n /// Example for use on the ICP:\n /// ```motoko no-repl\n /// import Cycles \"mo:core/Cycles\";\n ///\n /// persistent actor {\n /// public func main() : async() {\n /// let balance = Cycles.balance();\n /// assert balance > 0;\n /// }\n /// }\n /// ```\n public let balance : () -> (amount : Nat) = Prim.cyclesBalance;\n\n /// Returns the currently available `amount` of cycles.\n /// The amount available is the amount received in the current call,\n /// minus the cumulative amount `accept`ed by this call.\n /// On exit from the current shared function or async expression via `return` or `throw`,\n /// any remaining available amount is automatically refunded to the caller/context.\n ///\n /// Example for use on the ICP:\n /// ```motoko no-repl\n /// import Cycles \"mo:core/Cycles\";\n ///\n /// persistent actor {\n /// public func main() : async() {\n /// let available = Cycles.available();\n /// assert available >= 0;\n /// }\n /// }\n /// ```\n public let available : () -> (amount : Nat) = Prim.cyclesAvailable;\n\n /// Transfers up to `amount` from `available()` to `balance()`.\n /// Returns the amount actually transferred, which may be less than\n /// requested, for example, if less is available, or if canister balance limits are reached.\n ///\n /// Example for use on the ICP (for simplicity, only transferring cycles to itself):\n /// ```motoko no-repl\n /// import Cycles \"mo:core/Cycles\";\n ///\n /// persistent actor {\n /// public func main() : async() {\n /// await (with cycles = 15_000_000) operation(); // accepts 10_000_000 cycles\n /// };\n ///\n /// func operation() : async() {\n /// let obtained = Cycles.accept<system>(10_000_000);\n /// assert obtained == 10_000_000;\n /// }\n /// }\n /// ```\n public let accept : <system>(amount : Nat) -> (accepted : Nat) = Prim.cyclesAccept;\n\n /// Reports `amount` of cycles refunded in the last `await` of the current\n /// context, or zero if no await has occurred yet.\n /// Calling `refunded()` is solely informational and does not affect `balance()`.\n /// Instead, refunds are automatically added to the current balance,\n /// whether or not `refunded` is used to observe them.\n ///\n /// Example for use on the ICP (for simplicity, only transferring cycles to itself):\n /// ```motoko no-repl\n /// import Cycles \"mo:core/Cycles\";\n ///\n /// persistent actor {\n /// func operation() : async() {\n /// ignore Cycles.accept<system>(10_000_000);\n /// };\n ///\n /// public func main() : async() {\n /// await (with cycles = 15_000_000) operation(); // accepts 10_000_000 cycles\n /// assert Cycles.refunded() == 5_000_000;\n /// }\n /// }\n /// ```\n public let refunded : () -> (amount : Nat) = Prim.cyclesRefunded;\n\n /// Attempts to burn `amount` of cycles, deducting `burned` from the canister's\n /// cycle balance. The burned cycles are irrevocably lost and not available to any\n /// other principal either.\n ///\n /// Example for use on the IC:\n /// ```motoko no-repl\n /// import Cycles \"mo:core/Cycles\";\n ///\n /// actor {\n /// public func main() : async() {\n /// let burnt = Cycles.burn<system>(10_000_000);\n /// assert burnt == 10_000_000;\n /// }\n /// }\n /// ```\n public let burn : <system>(amount : Nat) -> (burned : Nat) = Prim.cyclesBurn;\n\n}\n"},"Tuples.mo":{"content":"/// Contains modules for working with tuples of different sizes.\n///\n/// Usage example:\n///\n/// ```motoko\n/// import { Tuple2; Tuple3 } \"mo:core/Tuples\";\n/// import Bool \"mo:core/Bool\";\n/// import Nat \"mo:core/Nat\";\n///\n/// let swapped = Tuple2.swap((1, \"hello\"));\n/// assert swapped == (\"hello\", 1);\n/// let text = Tuple3.toText((1, true, 3), Nat.toText, Bool.toText, Nat.toText);\n/// assert text == \"(1, true, 3)\";\n/// ```\n\nimport Types \"Types\";\n\nmodule {\n\n public module Tuple2 {\n /// Swaps the elements of a tuple.\n ///\n /// ```motoko\n /// import { Tuple2 } \"mo:core/Tuples\";\n ///\n /// assert Tuple2.swap((1, \"hello\")) == (\"hello\", 1);\n /// ```\n public func swap<A, B>((a, b) : (A, B)) : (B, A) = (b, a);\n\n /// Creates a textual representation of a tuple for debugging purposes.\n ///\n /// ```motoko\n /// import { Tuple2 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// assert Tuple2.toText((1, \"hello\"), Nat.toText, func (x: Text): Text = x) == \"(1, hello)\";\n /// ```\n public func toText<A, B>(t : (A, B), toTextA : A -> Text, toTextB : B -> Text) : Text = \"(\" # toTextA(t.0) # \", \" # toTextB(t.1) # \")\";\n\n /// Compares two tuples for equality.\n ///\n /// ```motoko\n /// import { Tuple2 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// assert Tuple2.equal((1, \"hello\"), (1, \"hello\"), Nat.equal, Text.equal);\n /// ```\n public func equal<A, B>(t1 : (A, B), t2 : (A, B), aEqual : (A, A) -> Bool, bEqual : (B, B) -> Bool) : Bool = aEqual(t1.0, t2.0) and bEqual(t1.1, t2.1);\n\n /// Compares two tuples lexicographically.\n ///\n /// ```motoko\n /// import { Tuple2 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// assert Tuple2.compare((1, \"hello\"), (1, \"world\"), Nat.compare, Text.compare) == #less;\n /// assert Tuple2.compare((1, \"hello\"), (2, \"hello\"), Nat.compare, Text.compare) == #less;\n /// assert Tuple2.compare((1, \"hello\"), (1, \"hello\"), Nat.compare, Text.compare) == #equal;\n /// assert Tuple2.compare((2, \"hello\"), (1, \"hello\"), Nat.compare, Text.compare) == #greater;\n /// assert Tuple2.compare((1, \"world\"), (1, \"hello\"), Nat.compare, Text.compare) == #greater;\n /// ```\n public func compare<A, B>(t1 : (A, B), t2 : (A, B), aCompare : (A, A) -> Types.Order, bCompare : (B, B) -> Types.Order) : Types.Order = switch (aCompare(t1.0, t2.0)) {\n case (#equal) bCompare(t1.1, t2.1);\n case order order\n };\n\n /// Creates a `toText` function for a tuple given `toText` functions for its elements.\n /// This is useful when you need to reuse the same toText conversion multiple times.\n ///\n /// ```motoko\n /// import { Tuple2 } \"mo:core/Tuples\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// let tupleToText = Tuple2.makeToText<Nat, Text>(Nat.toText, func x = x);\n /// assert tupleToText((1, \"hello\")) == \"(1, hello)\";\n /// ```\n public func makeToText<A, B>(toTextA : A -> Text, toTextB : B -> Text) : ((A, B)) -> Text = func t = toText(t, toTextA, toTextB);\n\n /// Creates an `equal` function for a tuple given `equal` functions for its elements.\n /// This is useful when you need to reuse the same equality comparison multiple times.\n ///\n /// ```motoko\n /// import { Tuple2 } \"mo:core/Tuples\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// let tupleEqual = Tuple2.makeEqual(Nat.equal, Text.equal);\n /// assert tupleEqual((1, \"hello\"), (1, \"hello\"));\n /// ```\n public func makeEqual<A, B>(aEqual : (A, A) -> Bool, bEqual : (B, B) -> Bool) : ((A, B), (A, B)) -> Bool = func(t1, t2) = equal(t1, t2, aEqual, bEqual);\n\n /// Creates a `compare` function for a tuple given `compare` functions for its elements.\n /// This is useful when you need to reuse the same comparison multiple times.\n ///\n /// ```motoko\n /// import { Tuple2 } \"mo:core/Tuples\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// let tupleCompare = Tuple2.makeCompare(Nat.compare, Text.compare);\n /// assert tupleCompare((1, \"hello\"), (1, \"world\")) == #less;\n /// ```\n public func makeCompare<A, B>(aCompare : (A, A) -> Types.Order, bCompare : (B, B) -> Types.Order) : ((A, B), (A, B)) -> Types.Order = func(t1, t2) = compare(t1, t2, aCompare, bCompare)\n };\n\n public module Tuple3 {\n /// Creates a textual representation of a 3-tuple for debugging purposes.\n ///\n /// ```motoko\n /// import { Tuple3 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// assert Tuple3.toText((1, \"hello\", 2), Nat.toText, func (x: Text): Text = x, Nat.toText) == \"(1, hello, 2)\";\n /// ```\n public func toText<A, B, C>(t : (A, B, C), toTextA : A -> Text, toTextB : B -> Text, toTextC : C -> Text) : Text = \"(\" # toTextA(t.0) # \", \" # toTextB(t.1) # \", \" # toTextC(t.2) # \")\";\n\n /// Compares two 3-tuples for equality.\n ///\n /// ```motoko\n /// import { Tuple3 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// assert Tuple3.equal((1, \"hello\", 2), (1, \"hello\", 2), Nat.equal, Text.equal, Nat.equal);\n /// ```\n public func equal<A, B, C>(t1 : (A, B, C), t2 : (A, B, C), aEqual : (A, A) -> Bool, bEqual : (B, B) -> Bool, cEqual : (C, C) -> Bool) : Bool = aEqual(t1.0, t2.0) and bEqual(t1.1, t2.1) and cEqual(t1.2, t2.2);\n\n /// Compares two 3-tuples lexicographically.\n ///\n /// ```motoko\n /// import { Tuple3 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// assert Tuple3.compare((1, \"hello\", 2), (1, \"world\", 1), Nat.compare, Text.compare, Nat.compare) == #less;\n /// assert Tuple3.compare((1, \"hello\", 2), (2, \"hello\", 2), Nat.compare, Text.compare, Nat.compare) == #less;\n /// assert Tuple3.compare((1, \"hello\", 2), (1, \"hello\", 2), Nat.compare, Text.compare, Nat.compare) == #equal;\n /// assert Tuple3.compare((2, \"hello\", 2), (1, \"hello\", 2), Nat.compare, Text.compare, Nat.compare) == #greater;\n /// ```\n public func compare<A, B, C>(t1 : (A, B, C), t2 : (A, B, C), aCompare : (A, A) -> Types.Order, bCompare : (B, B) -> Types.Order, cCompare : (C, C) -> Types.Order) : Types.Order = switch (aCompare(t1.0, t2.0)) {\n case (#equal) {\n switch (bCompare(t1.1, t2.1)) {\n case (#equal) cCompare(t1.2, t2.2);\n case order order\n }\n };\n case order order\n };\n\n /// Creates a `toText` function for a 3-tuple given `toText` functions for its elements.\n /// This is useful when you need to reuse the same toText conversion multiple times.\n ///\n /// ```motoko\n /// import { Tuple3 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// let toText = Tuple3.makeToText<Nat, Text, Nat>(Nat.toText, func x = x, Nat.toText);\n /// assert toText((1, \"hello\", 2)) == \"(1, hello, 2)\";\n /// ```\n public func makeToText<A, B, C>(toTextA : A -> Text, toTextB : B -> Text, toTextC : C -> Text) : ((A, B, C)) -> Text = func t = toText(t, toTextA, toTextB, toTextC);\n\n /// Creates an `equal` function for a 3-tuple given `equal` functions for its elements.\n /// This is useful when you need to reuse the same equality comparison multiple times.\n ///\n /// ```motoko\n /// import { Tuple3 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// let equal = Tuple3.makeEqual(Nat.equal, Text.equal, Nat.equal);\n /// assert equal((1, \"hello\", 2), (1, \"hello\", 2));\n /// ```\n public func makeEqual<A, B, C>(aEqual : (A, A) -> Bool, bEqual : (B, B) -> Bool, cEqual : (C, C) -> Bool) : ((A, B, C), (A, B, C)) -> Bool = func(t1, t2) = equal(t1, t2, aEqual, bEqual, cEqual);\n\n /// Creates a `compare` function for a 3-tuple given `compare` functions for its elements.\n /// This is useful when you need to reuse the same comparison multiple times.\n ///\n /// ```motoko\n /// import { Tuple3 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// let compare = Tuple3.makeCompare(Nat.compare, Text.compare, Nat.compare);\n /// assert compare((1, \"hello\", 2), (1, \"world\", 1)) == #less;\n /// ```\n public func makeCompare<A, B, C>(aCompare : (A, A) -> Types.Order, bCompare : (B, B) -> Types.Order, cCompare : (C, C) -> Types.Order) : ((A, B, C), (A, B, C)) -> Types.Order = func(t1, t2) = compare(t1, t2, aCompare, bCompare, cCompare)\n };\n\n public module Tuple4 {\n /// Creates a textual representation of a 4-tuple for debugging purposes.\n ///\n /// ```motoko\n /// import { Tuple4 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// assert Tuple4.toText((1, \"hello\", 2, 3), Nat.toText, func (x: Text): Text = x, Nat.toText, Nat.toText) == \"(1, hello, 2, 3)\";\n /// ```\n public func toText<A, B, C, D>(t : (A, B, C, D), toTextA : A -> Text, toTextB : B -> Text, toTextC : C -> Text, toTextD : D -> Text) : Text = \"(\" # toTextA(t.0) # \", \" # toTextB(t.1) # \", \" # toTextC(t.2) # \", \" # toTextD(t.3) # \")\";\n\n /// Compares two 4-tuples for equality.\n ///\n /// ```motoko\n /// import { Tuple4 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// assert Tuple4.equal((1, \"hello\", 2, 3), (1, \"hello\", 2, 3), Nat.equal, Text.equal, Nat.equal, Nat.equal);\n /// ```\n public func equal<A, B, C, D>(t1 : (A, B, C, D), t2 : (A, B, C, D), aEqual : (A, A) -> Bool, bEqual : (B, B) -> Bool, cEqual : (C, C) -> Bool, dEqual : (D, D) -> Bool) : Bool = aEqual(t1.0, t2.0) and bEqual(t1.1, t2.1) and cEqual(t1.2, t2.2) and dEqual(t1.3, t2.3);\n\n /// Compares two 4-tuples lexicographically.\n ///\n /// ```motoko\n /// import { Tuple4 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// assert Tuple4.compare((1, \"hello\", 2, 3), (1, \"world\", 1, 3), Nat.compare, Text.compare, Nat.compare, Nat.compare) == #less;\n /// assert Tuple4.compare((1, \"hello\", 2, 3), (2, \"hello\", 2, 3), Nat.compare, Text.compare, Nat.compare, Nat.compare) == #less;\n /// assert Tuple4.compare((1, \"hello\", 2, 3), (1, \"hello\", 2, 3), Nat.compare, Text.compare, Nat.compare, Nat.compare) == #equal;\n /// assert Tuple4.compare((2, \"hello\", 2, 3), (1, \"hello\", 2, 3), Nat.compare, Text.compare, Nat.compare, Nat.compare) == #greater;\n /// ```\n public func compare<A, B, C, D>(t1 : (A, B, C, D), t2 : (A, B, C, D), aCompare : (A, A) -> Types.Order, bCompare : (B, B) -> Types.Order, cCompare : (C, C) -> Types.Order, dCompare : (D, D) -> Types.Order) : Types.Order = switch (aCompare(t1.0, t2.0)) {\n case (#equal) {\n switch (bCompare(t1.1, t2.1)) {\n case (#equal) {\n switch (cCompare(t1.2, t2.2)) {\n case (#equal) dCompare(t1.3, t2.3);\n case order order\n }\n };\n case order order\n }\n };\n case order order\n };\n\n /// Creates a `toText` function for a 4-tuple given `toText` functions for its elements.\n /// This is useful when you need to reuse the same toText conversion multiple times.\n ///\n /// ```motoko\n /// import { Tuple4 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// let toText = Tuple4.makeToText(Nat.toText, func (x: Text): Text = x, Nat.toText, Nat.toText);\n /// assert toText((1, \"hello\", 2, 3)) == \"(1, hello, 2, 3)\";\n /// ```\n public func makeToText<A, B, C, D>(toTextA : A -> Text, toTextB : B -> Text, toTextC : C -> Text, toTextD : D -> Text) : ((A, B, C, D)) -> Text = func t = toText(t, toTextA, toTextB, toTextC, toTextD);\n\n /// Creates an `equal` function for a 4-tuple given `equal` functions for its elements.\n /// This is useful when you need to reuse the same equality comparison multiple times.\n ///\n /// ```motoko\n /// import { Tuple4 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// let equal = Tuple4.makeEqual(Nat.equal, Text.equal, Nat.equal, Nat.equal);\n /// assert equal((1, \"hello\", 2, 3), (1, \"hello\", 2, 3));\n /// ```\n public func makeEqual<A, B, C, D>(aEqual : (A, A) -> Bool, bEqual : (B, B) -> Bool, cEqual : (C, C) -> Bool, dEqual : (D, D) -> Bool) : ((A, B, C, D), (A, B, C, D)) -> Bool = func(t1, t2) = equal(t1, t2, aEqual, bEqual, cEqual, dEqual);\n\n /// Creates a `compare` function for a 4-tuple given `compare` functions for its elements.\n /// This is useful when you need to reuse the same comparison multiple times.\n ///\n /// ```motoko\n /// import { Tuple4 } \"mo:core/Tuples\";\n ///\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// let compare = Tuple4.makeCompare(Nat.compare, Text.compare, Nat.compare, Nat.compare);\n /// assert compare((1, \"hello\", 2, 3), (1, \"world\", 1, 3)) == #less;\n /// ```\n public func makeCompare<A, B, C, D>(aCompare : (A, A) -> Types.Order, bCompare : (B, B) -> Types.Order, cCompare : (C, C) -> Types.Order, dCompare : (D, D) -> Types.Order) : ((A, B, C, D), (A, B, C, D)) -> Types.Order = func(t1, t2) = compare(t1, t2, aCompare, bCompare, cCompare, dCompare)\n }\n}\n"},"pure/List.mo":{"content":"/// Purely-functional, singly-linked lists.\n\n/// A list of type `List<T>` is either `null` or an optional pair of a value of type `T` and a tail, itself of type `List<T>`.\n///\n/// To use this library, import it using:\n///\n/// ```motoko name=import\n/// import List \"mo:core/pure/List\";\n/// ```\n\nimport { Array_tabulate } \"mo:⛔\";\nimport Array \"../Array\";\nimport Iter \"../Iter\";\nimport Order \"../Order\";\nimport Result \"../Result\";\nimport { trap } \"../Runtime\";\nimport Types \"../Types\";\nimport Runtime \"../Runtime\";\n\nmodule {\n\n public type List<T> = Types.Pure.List<T>;\n\n /// Create an empty list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// assert List.empty<Nat>() == null;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func empty<T>() : List<T> = null;\n\n /// Check whether a list is empty and return true if the list is empty.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// assert List.isEmpty(null);\n /// assert not List.isEmpty(?(1, null));\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func isEmpty<T>(list : List<T>) : Bool = switch list {\n case null true;\n case _ false\n };\n\n /// Return the length of the list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, null));\n /// assert List.size(list) == 2;\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func size<T>(list : List<T>) : Nat = (\n func go(n : Nat, list : List<T>) : Nat = switch list {\n case (?(_, t)) go(n + 1, t);\n case null n\n }\n )(0, list);\n\n /// Check whether the list contains a given value. Uses the provided equality function to compare values.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert List.contains(list, Nat.equal, 2);\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func contains<T>(list : List<T>, equal : (T, T) -> Bool, item : T) : Bool = switch list {\n case (?(h, t)) equal(h, item) or contains(t, equal, item);\n case _ false\n };\n\n /// Access any item in a list, zero-based.\n ///\n /// NOTE: Indexing into a list is a linear operation, and usually an\n /// indication that a list might not be the best data structure\n /// to use.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, null));\n /// assert List.get(list, 1) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func get<T>(list : List<T>, n : Nat) : ?T = switch list {\n case (?(h, t)) if (n == 0) ?h else get(t, n - 1 : Nat);\n case null null\n };\n\n /// Add `item` to the head of `list`, and return the new list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// assert List.pushFront(null, 0) == ?(0, null);\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func pushFront<T>(list : List<T>, item : T) : List<T> = ?(item, list);\n\n /// Return the last element of the list, if present.\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, null));\n /// assert List.last(list) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func last<T>(list : List<T>) : ?T = switch list {\n case (?(h, null)) ?h;\n case null null;\n case (?(_, t)) last t\n };\n\n /// Remove the head of the list, returning the optioned head and the tail of the list in a pair.\n /// Returns `(null, null)` if the list is empty.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, null));\n /// assert List.popFront(list) == (?0, ?(1, null));\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func popFront<T>(list : List<T>) : (?T, List<T>) = switch list {\n case null (null, null);\n case (?(h, t)) (?h, t)\n };\n\n /// Reverses the list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, null)));\n /// assert List.reverse(list) == ?(2, ?(1, ?(0, null)));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func reverse<T>(list : List<T>) : List<T> = (\n func go(acc : List<T>, list : List<T>) : List<T> = switch list {\n case (?(h, t)) go(?(h, acc), t);\n case null acc\n }\n )(null, list);\n\n /// Call the given function for its side effect, with each list element in turn.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, null)));\n /// var sum = 0;\n /// List.forEach<Nat>(list, func n = sum += n);\n /// assert sum == 3;\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func forEach<T>(list : List<T>, f : T -> ()) = switch list {\n case (?(h, t)) { f h; forEach(t, f) };\n case null ()\n };\n\n /// Call the given function `f` on each list element and collect the results\n /// in a new list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, null)));\n /// assert List.map(list, Nat.toText) == ?(\"0\", ?(\"1\", ?(\"2\", null)));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<T1, T2>(list : List<T1>, f : T1 -> T2) : List<T2> = (\n func go(list : List<T1>, f : T1 -> T2, acc : List<T2>) : List<T2> = switch list {\n case (?(h, t)) go(t, f, ?(f h, acc));\n case null reverse acc\n }\n )(list, f, null);\n\n /// Create a new list with only those elements of the original list for which\n /// the given function (often called the _predicate_) returns true.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, null)));\n /// assert List.filter<Nat>(list, func n = n != 1) == ?(0, ?(2, null));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func filter<T>(list : List<T>, f : T -> Bool) : List<T> = (\n func go(list : List<T>, f : T -> Bool, acc : List<T>) : List<T> = switch list {\n case (?(h, t)) if (f h) go(t, f, ?(h, acc)) else go(t, f, acc);\n case null reverse acc\n }\n )(list, f, null);\n\n /// Call the given function on each list element, and collect the non-null results\n /// in a new list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert List.filterMap<Nat, Nat>(\n /// list,\n /// func n = if (n > 1) ?(n * 2) else null\n /// ) == ?(4, ?(6, null));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func filterMap<T, R>(list : List<T>, f : T -> ?R) : List<R> = (\n func go(list : List<T>, f : T -> ?R, acc : List<R>) : List<R> = switch list {\n case (?(h, t)) switch (f h) {\n case null go(t, f, acc);\n case (?r) go(t, f, ?(r, acc))\n };\n case null reverse acc\n }\n )(list, f, null);\n\n /// Maps a `Result`-returning function `f` over a `List` and returns either\n /// the first error or a list of successful values.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert List.mapResult<Nat, Nat, Text>(\n /// list,\n /// func n = if (n > 0) #ok(n * 2) else #err \"Some element is zero\"\n /// ) == #ok(?(2, ?(4, ?(6, null))));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapResult<T, R, E>(list : List<T>, f : T -> Result.Result<R, E>) : Result.Result<List<R>, E> = (\n func rev(acc : List<R>, list : List<T>, f : T -> Result.Result<R, E>) : Result.Result<List<R>, E> = switch list {\n case (?(h, t)) switch (f h) {\n case (#ok fh) rev(?(fh, acc), t, f);\n case (#err e) #err e\n };\n case null #ok(reverse acc)\n }\n )(null, list, f);\n\n /// Create two new lists from the results of a given function (`f`).\n /// The first list only includes the elements for which the given\n /// function `f` returns true and the second list only includes\n /// the elements for which the function returns false.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, null)));\n /// assert List.partition<Nat>(list, func n = n != 1) == (?(0, ?(2, null)), ?(1, null));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func partition<T>(list : List<T>, f : T -> Bool) : (List<T>, List<T>) = (\n func go(list : List<T>, f : T -> Bool, acc1 : List<T>, acc2 : List<T>) : (List<T>, List<T>) = switch list {\n case (?(h, t)) if (f h) go(t, f, ?(h, acc1), acc2) else go(t, f, acc1, ?(h, acc2));\n case null (reverse acc1, reverse acc2)\n }\n )(list, f, null, null);\n\n /// Append the elements from one list to another list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list1 = ?(0, ?(1, ?(2, null)));\n /// let list2 = ?(3, ?(4, ?(5, null)));\n /// assert List.concat(list1, list2) == ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))));\n /// }\n /// ```\n ///\n /// Runtime: O(size(l))\n ///\n /// Space: O(size(l))\n public func concat<T>(list1 : List<T>, list2 : List<T>) : List<T> = revAppend(reverse list1, list2);\n\n /// Flatten, or repatedly concatenate, an iterator of lists as a list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let lists = [ ?(0, ?(1, ?(2, null))),\n /// ?(3, ?(4, ?(5, null))) ];\n /// assert List.join(lists |> Iter.fromArray(_)) == ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))));\n /// }\n /// ```\n ///\n /// Runtime: O(size*size)\n ///\n /// Space: O(size*size)\n public func join<T>(iter : Iter.Iter<List<T>>) : List<T> {\n var acc : List<T> = null;\n for (list in iter) {\n acc := revAppend(list, acc)\n };\n reverse acc\n };\n\n /// Flatten, or repatedly concatenate, a list of lists as a list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let lists = ?(?(0, ?(1, ?(2, null))),\n /// ?(?(3, ?(4, ?(5, null))),\n /// null));\n /// assert List.flatten(lists) == ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))));\n /// }\n /// ```\n ///\n /// Runtime: O(size*size)\n ///\n /// Space: O(size*size)\n public func flatten<T>(list : List<List<T>>) : List<T> = (\n func go(lists : List<List<T>>, acc : List<T>) : List<T> = switch lists {\n case (?(list, t)) go(t, revAppend(list, acc));\n case null reverse acc\n }\n )(list, null);\n\n /// Returns the first `n` elements of the given list.\n /// If the given list has fewer than `n` elements, this function returns\n /// a copy of the full input list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, null)));\n /// assert List.take(list, 2) == ?(0, ?(1, null));\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(n)\n public func take<T>(list : List<T>, n : Nat) : List<T> = (\n func go(n : Nat, list : List<T>, acc : List<T>) : List<T> = if (n == 0) reverse acc else switch list {\n case (?(h, t)) go(n - 1 : Nat, t, ?(h, acc));\n case null reverse acc\n }\n )(n, list, null);\n\n /// Drop the first `n` elements from the given list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, null)));\n /// assert List.drop(list, 2) == ?(2, null);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(1)\n public func drop<T>(list : List<T>, n : Nat) : List<T> = if (n == 0) list else switch list {\n case (?(_, t)) drop(t, n - 1 : Nat);\n case null null\n };\n\n /// Collapses the elements in `list` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert List.foldLeft<Nat, Text>(\n /// list,\n /// \"\",\n /// func (acc, x) = acc # Nat.toText(x)\n /// ) == \"123\";\n /// }\n /// ```\n ///\n /// Runtime: O(size(list))\n ///\n /// Space: O(1) heap, O(1) stack\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldLeft<T, A>(list : List<T>, base : A, combine : (A, T) -> A) : A = switch list {\n case null base;\n case (?(h, t)) foldLeft(t, combine(base, h), combine)\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert List.foldRight<Nat, Text>(\n /// list,\n /// \"\",\n /// func (x, acc) = Nat.toText(x) # acc\n /// ) == \"123\";\n /// }\n /// ```\n ///\n /// Runtime: O(size(list))\n ///\n /// Space: O(1) heap, O(size(list)) stack\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldRight<T, A>(list : List<T>, base : A, combine : (T, A) -> A) : A = (\n func go(list : List<T>, base : A, combine : (T, A) -> A) : A = switch list {\n case null base;\n case (?(h, t)) go(t, combine(h, base), combine)\n }\n )(reverse list, base, combine);\n\n /// Return the first element for which the given predicate `f` is true,\n /// if such an element exists.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert List.find<Nat>(list, func n = n > 1) == ?2;\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func find<T>(list : List<T>, f : T -> Bool) : ?T = switch list {\n case null null;\n case (?(h, t)) if (f h) ?h else find(t, f)\n };\n\n /// Return the first index for which the given predicate `f` is true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = List.fromArray(['A', 'B', 'C', 'D']);\n /// let found = List.findIndex<Char>(list, func(x) { x == 'C' });\n /// assert found == ?2;\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func findIndex<T>(list : List<T>, f : T -> Bool) : ?Nat {\n findIndex_(list, 0, f)\n };\n\n private func findIndex_<T>(list : List<T>, index : Nat, f : T -> Bool) : ?Nat = switch list {\n case null null;\n case (?(h, t)) if (f h) ?index else findIndex_(t, index + 1, f)\n };\n\n /// Return true if the given predicate `f` is true for all list\n /// elements.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert not List.all<Nat>(list, func n = n > 1);\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func all<T>(list : List<T>, f : T -> Bool) : Bool = switch list {\n case null true;\n case (?(h, t)) f h and all(t, f)\n };\n\n /// Return true if there exists a list element for which\n /// the given predicate `f` is true.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert List.any<Nat>(list, func n = n > 1);\n /// }\n /// ```\n ///\n /// Runtime: O(size(list))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func any<T>(list : List<T>, f : T -> Bool) : Bool = switch list {\n case null false;\n case (?(h, t)) f h or any(t, f)\n };\n\n /// Merge two ordered lists into a single ordered list.\n /// This function requires both list to be ordered as specified\n /// by the given relation `compare`.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list1 = ?(1, ?(2, ?(4, null)));\n /// let list2 = ?(2, ?(4, ?(6, null)));\n /// assert List.merge(list1, list2, Nat.compare) == ?(1, ?(2, ?(2, ?(4, ?(4, ?(6, null))))));\n /// }\n /// ```\n ///\n /// Runtime: O(size(l1) + size(l2))\n ///\n /// Space: O(size(l1) + size(l2))\n ///\n /// *Runtime and space assumes that `lessThanOrEqual` runs in O(1) time and space.\n public func merge<T>(list1 : List<T>, list2 : List<T>, compare : (T, T) -> Order.Order) : List<T> = (\n func go(list1 : List<T>, list2 : List<T>, compare : (T, T) -> Order.Order, acc : List<T>) : List<T> = switch (list1, list2) {\n case ((null, l) or (l, null)) reverse(revAppend(l, acc));\n case (?(h1, t1), ?(h2, t2)) switch (compare(h1, h2)) {\n case (#less or #equal) go(t1, list2, compare, ?(h1, acc));\n case (#greater) go(list1, t2, compare, ?(h2, acc))\n }\n }\n )(list1, list2, compare, null);\n\n /// Check if two lists are equal using the given equality function to compare elements.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list1 = ?(1, ?(2, null));\n /// let list2 = ?(1, ?(2, null));\n /// assert List.equal(list1, list2, Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equalItem` runs in O(1) time and space.\n public func equal<T>(list1 : List<T>, list2 : List<T>, equalItem : (T, T) -> Bool) : Bool = switch (list1, list2) {\n case (null, null) true;\n case (?(h1, t1), ?(h2, t2)) equalItem(h1, h2) and equal(t1, t2, equalItem);\n case _ false\n };\n\n /// Compare two lists using lexicographic ordering specified by argument function `compareItem`.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list1 = ?(1, ?(2, null));\n /// let list2 = ?(3, ?(4, null));\n /// assert List.compare(list1, list2, Nat.compare) == #less;\n /// }\n /// ```\n ///\n /// Runtime: O(size(l1))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that argument `compare` runs in O(1) time and space.\n public func compare<T>(list1 : List<T>, list2 : List<T>, compareItem : (T, T) -> Order.Order) : Order.Order = switch (list1, list2) {\n case (?(h1, t1), ?(h2, t2)) switch (compareItem(h1, h2)) {\n case (#equal) compare(t1, t2, compareItem);\n case o o\n };\n case (null, null) #equal;\n case (null, _) #less;\n case _ #greater\n };\n\n /// Generate a list based on a length and a function that maps from\n /// a list index to a list element.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = List.tabulate<Nat>(3, func n = n * 2);\n /// assert list == ?(0, ?(2, ?(4, null)));\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(n)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func tabulate<T>(n : Nat, f : Nat -> T) : List<T> {\n var i = 0;\n var l : List<T> = null;\n while (i < n) {\n l := ?(f i, l);\n i += 1\n };\n reverse l\n };\n\n /// Create a list with exactly one element.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// assert List.singleton(0) == ?(0, null);\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func singleton<T>(item : T) : List<T> = ?(item, null);\n\n /// Create a list of the given length with the same value in each position.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = List.repeat('a', 3);\n /// assert list == ?('a', ?('a', ?('a', null)));\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(n)\n public func repeat<T>(item : T, n : Nat) : List<T> {\n var res : List<T> = null;\n var i : Int = n;\n while (i != 0) {\n i -= 1;\n res := ?(item, res)\n };\n res\n };\n\n /// Create a list of pairs from a pair of lists.\n ///\n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list1 = ?(0, ?(1, ?(2, null)));\n /// let list2 = ?(\"0\", ?(\"1\", null));\n /// assert List.zip(list1, list2) == ?((0, \"0\"), ?((1, \"1\"), null));\n /// }\n /// ```\n ///\n /// Runtime: O(min(size(xs), size(ys)))\n ///\n /// Space: O(min(size(xs), size(ys)))\n public func zip<T, U>(list1 : List<T>, list2 : List<U>) : List<(T, U)> = zipWith<T, U, (T, U)>(list1, list2, func(x, y) = (x, y));\n\n /// Create a list in which elements are created by applying function `f` to each pair `(x, y)` of elements\n /// occuring at the same position in list `xs` and list `ys`.\n ///\n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n /// import Char \"mo:core/Char\";\n ///\n /// persistent actor {\n /// let list1 = ?(0, ?(1, ?(2, null)));\n /// let list2 = ?('a', ?('b', null));\n /// assert List.zipWith<Nat, Char, Text>(\n /// list1,\n /// list2,\n /// func (n, c) = Nat.toText(n) # Char.toText(c)\n /// ) == ?(\"0a\", ?(\"1b\", null));\n /// }\n /// ```\n ///\n /// Runtime: O(min(size(xs), size(ys)))\n ///\n /// Space: O(min(size(xs), size(ys)))\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func zipWith<T, U, V>(list1 : List<T>, list2 : List<U>, f : (T, U) -> V) : List<V> = (\n func go(list1 : List<T>, list2 : List<U>, f : (T, U) -> V, acc : List<V>) : List<V> = switch (list1, list2) {\n case ((null, _) or (_, null)) reverse acc;\n case (?(h1, t1), ?(h2, t2)) go(t1, t2, f, ?(f(h1, h2), acc))\n }\n )(list1, list2, f, null);\n\n /// Split the given list at the given zero-based index.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, null)));\n /// assert List.split(list, 2) == (?(0, ?(1, null)), ?(2, null));\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(n)\n public func split<T>(list : List<T>, n : Nat) : (List<T>, List<T>) {\n func go(n : Nat, list : List<T>, acc : List<T>) : (List<T>, List<T>) = if (n == 0) (reverse acc, list) else switch list {\n case (?(h, t)) go(n - 1 : Nat, t, ?(h, acc));\n case null (reverse acc, null)\n };\n go(n, list, null)\n };\n\n /// Split the given list into chunks of length `n`.\n /// The last chunk will be shorter if the length of the given list\n /// does not divide by `n` evenly. Traps if `n` = 0.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = ?(0, ?(1, ?(2, ?(3, ?(4, null)))));\n /// assert List.chunks(list, 2) == ?(?(0, ?(1, null)), ?(?(2, ?(3, null)), ?(?(4, null), null)));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func chunks<T>(list : List<T>, n : Nat) : List<List<T>> {\n if (n == 0) trap \"pure/List.chunks()\";\n func go(list : List<T>, n : Nat, acc : List<List<T>>) : List<List<T>> = switch (split(list, n)) {\n case (null, _) reverse acc;\n case (pre, null) reverse(?(pre, acc));\n case (pre, post) go(post, n, ?(pre, acc))\n };\n go(list, n, null)\n };\n\n /// Returns an iterator to the elements in the list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list = List.fromArray([3, 1, 4]);\n /// var text = \"\";\n /// for (item in List.values(list)) {\n /// text #= Nat.toText(item);\n /// };\n /// assert text == \"314\";\n /// }\n /// ```\n public func values<T>(list : List<T>) : Iter.Iter<T> = object {\n var l = list;\n public func next() : ?T = switch l {\n case null null;\n case (?(h, t)) {\n l := t;\n ?h\n }\n }\n };\n\n /// Returns an iterator to the `(index, element)` pairs in the list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list = List.fromArray([3, 1, 4]);\n /// var text = \"\";\n /// for ((index, element) in List.enumerate(list)) {\n /// text #= Nat.toText(index);\n /// };\n /// assert text == \"012\";\n /// }\n /// ```\n public func enumerate<T>(list : List<T>) : Iter.Iter<(Nat, T)> = object {\n var i = 0;\n var l = list;\n public func next() : ?(Nat, T) = switch l {\n case null null;\n case (?(h, t)) {\n l := t;\n let index = i;\n i += 1;\n ?(index, h)\n }\n }\n };\n\n /// Convert an array into a list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = List.fromArray([0, 1, 2, 3, 4]);\n /// assert list == ?(0, ?(1, ?(2, ?(3, ?(4, null)))));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromArray<T>(array : [T]) : List<T> {\n func go(from : Nat) : List<T> = if (from < array.size()) ?(array.get from, go(from + 1)) else null;\n go 0\n };\n\n /// Convert a mutable array into a list.\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = List.fromVarArray([var 0, 1, 2, 3, 4]);\n /// assert list == ?(0, ?(1, ?(2, ?(3, ?(4, null)))));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromVarArray<T>(array : [var T]) : List<T> = fromArray<T>(Array.fromVarArray<T>(array));\n\n /// Create an array from a list.\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Array \"mo:core/Array\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let array = List.toArray(?(0, ?(1, ?(2, ?(3, ?(4, null))))));\n /// assert Array.equal(array, [0, 1, 2, 3, 4], Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toArray<T>(list : List<T>) : [T] {\n var l = list;\n Array_tabulate<T>(size list, func _ { let ?(h, t) = l else Runtime.trap(\"List.toArray(): unreachable\"); l := t; h })\n };\n\n /// Create a mutable array from a list.\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Array \"mo:core/Array\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let array = List.toVarArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))));\n /// assert Array.equal(Array.fromVarArray(array), [0, 1, 2, 3, 4], Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toVarArray<T>(list : List<T>) : [var T] = Array.toVarArray<T>(toArray<T>(list));\n\n /// Turn an iterator into a list, consuming it.\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n ///\n /// persistent actor {\n /// let list = List.fromIter([0, 1, 2, 3, 4].vals());\n /// assert list == ?(0, ?(1, ?(2, ?(3, ?(4, null)))));\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromIter<T>(iter : Iter.Iter<T>) : List<T> {\n var result : List<T> = null;\n for (x in iter) {\n result := ?(x, result)\n };\n reverse result\n };\n\n /// Convert a list to a text representation using the provided function to convert each element to text.\n /// The resulting text will be in the format \"[element1, element2, ...]\".\n ///\n /// Example:\n /// ```motoko\n /// import List \"mo:core/pure/List\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let list = ?(1, ?(2, ?(3, null)));\n /// assert List.toText(list, Nat.toText) == \"PureList[1, 2, 3]\";\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toText<T>(list : List<T>, f : T -> Text) : Text {\n var text = \"PureList[\";\n var first = true;\n forEach(\n list,\n func(item : T) {\n if first {\n first := false\n } else {\n text #= \", \"\n };\n text #= f item\n }\n );\n text # \"]\"\n };\n\n // revAppend([x1 .. xn], [y1 .. ym]) = [xn .. x1, y1 .. ym]\n func revAppend<T>(l : List<T>, m : List<T>) : List<T> = switch l {\n case (?(h, t)) revAppend(t, ?(h, m));\n case null m\n }\n}\n"},"Queue.mo":{"content":"/// A mutable double-ended queue of elements.\n/// The queue has two ends, front and back.\n/// Elements can be added and removed at the two ends.\n///\n/// This can be used for different use cases, such as:\n/// * Queue (FIFO) by using `pushBack()` and `popFront()`\n/// * Stack (LIFO) by using `pushFront()` and `popFront()`.\n///\n/// Example:\n/// ```motoko\n/// import Queue \"mo:core/Queue\";\n///\n/// persistent actor {\n/// let orders = Queue.empty<Text>();\n/// Queue.pushBack(orders, \"Motoko\");\n/// Queue.pushBack(orders, \"Mops\");\n/// Queue.pushBack(orders, \"IC\");\n/// assert Queue.popFront(orders) == ?\"Motoko\";\n/// assert Queue.popFront(orders) == ?\"Mops\";\n/// assert Queue.popFront(orders) == ?\"IC\";\n/// assert Queue.popFront(orders) == null;\n/// }\n/// ```\n///\n/// The internal implementation is a doubly-linked list.\n///\n/// Performance:\n/// * Runtime: `O(1)` for push, pop, and peek operations.\n/// * Space: `O(n)`.\n/// `n` denotes the number of elements stored in the queue.\n\nimport PureQueue \"pure/Queue\";\nimport Iter \"Iter\";\nimport Order \"Order\";\nimport Types \"Types\";\nimport Array \"Array\";\nimport Prim \"mo:⛔\";\n\nmodule {\n public type Queue<T> = Types.Queue.Queue<T>;\n\n type Node<T> = Types.Queue.Node<T>;\n\n /// Converts a mutable queue to an immutable, purely functional queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let pureQueue = Queue.toPure<Nat>(queue);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func toPure<T>(queue : Queue<T>) : PureQueue.Queue<T> {\n let pureQueue = PureQueue.empty<T>();\n let iter = values(queue);\n var current = pureQueue;\n loop {\n switch (iter.next()) {\n case null { return current };\n case (?val) { current := PureQueue.pushBack(current, val) }\n }\n }\n };\n\n /// Converts an immutable, purely functional queue to a mutable queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n /// import PureQueue \"mo:core/pure/Queue\";\n ///\n /// persistent actor {\n /// let pureQueue = PureQueue.fromIter<Nat>([1, 2, 3].values());\n /// let queue = Queue.fromPure<Nat>(pureQueue);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func fromPure<T>(pureQueue : PureQueue.Queue<T>) : Queue<T> {\n let queue = empty<T>();\n let iter = PureQueue.values(pureQueue);\n loop {\n switch (iter.next()) {\n case null { return queue };\n case (?val) { pushBack(queue, val) }\n }\n }\n };\n\n /// Create a new empty mutable double-ended queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.empty<Text>();\n /// assert Queue.size(queue) == 0;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func empty<T>() : Queue<T> {\n { var front = null; var back = null; var size = 0 }\n };\n\n /// Creates a new queue with a single element.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.singleton<Nat>(123);\n /// assert Queue.size(queue) == 1;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func singleton<T>(element : T) : Queue<T> {\n let queue = empty<T>();\n pushBack(queue, element);\n queue\n };\n\n /// Removes all elements from the queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// Queue.clear(queue);\n /// assert Queue.isEmpty(queue);\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func clear<T>(queue : Queue<T>) {\n queue.front := null;\n queue.back := null;\n queue.size := 0\n };\n\n /// Creates a deep copy of the queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let original = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let copy = Queue.clone(original);\n /// Queue.clear(original);\n /// assert Queue.size(original) == 0;\n /// assert Queue.size(copy) == 3;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func clone<T>(queue : Queue<T>) : Queue<T> {\n let copy = empty<T>();\n for (element in values(queue)) {\n pushBack(copy, element)\n };\n copy\n };\n\n /// Returns the number of elements in the queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Text>([\"A\", \"B\", \"C\"].values());\n /// assert Queue.size(queue) == 3;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func size<T>(queue : Queue<T>) : Nat {\n queue.size\n };\n\n /// Returns `true` if the queue contains no elements.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.empty<Nat>();\n /// assert Queue.isEmpty(queue);\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func isEmpty<T>(queue : Queue<T>) : Bool {\n queue.size == 0\n };\n\n /// Checks if an element exists in the queue using the provided equality function.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.contains(queue, Nat.equal, 2);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// `n` denotes the number of elements stored in the queue.\n public func contains<T>(queue : Queue<T>, equal : (T, T) -> Bool, element : T) : Bool {\n for (existing in values(queue)) {\n if (equal(existing, element)) {\n return true\n }\n };\n false\n };\n\n /// Returns the first element in the queue without removing it.\n /// Returns null if the queue is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.peekFront(queue) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func peekFront<T>(queue : Queue<T>) : ?T {\n switch (queue.front) {\n case null null;\n case (?node) ?node.value\n }\n };\n\n /// Returns the last element in the queue without removing it.\n /// Returns null if the queue is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.peekBack(queue) == ?3;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func peekBack<T>(queue : Queue<T>) : ?T {\n switch (queue.back) {\n case null null;\n case (?node) ?node.value\n }\n };\n\n /// Adds an element to the front of the queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.empty<Nat>();\n /// Queue.pushFront(queue, 1);\n /// assert Queue.peekFront(queue) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func pushFront<T>(queue : Queue<T>, element : T) {\n let node : Node<T> = {\n value = element;\n var next = queue.front;\n var previous = null\n };\n switch (queue.front) {\n case null {};\n case (?first) first.previous := ?node\n };\n queue.front := ?node;\n switch (queue.back) {\n case null queue.back := ?node;\n case (?_) {}\n };\n queue.size += 1\n };\n\n /// Adds an element to the back of the queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.empty<Nat>();\n /// Queue.pushBack(queue, 1);\n /// assert Queue.peekBack(queue) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func pushBack<T>(queue : Queue<T>, element : T) {\n let node : Node<T> = {\n value = element;\n var next = null;\n var previous = queue.back\n };\n switch (queue.back) {\n case null {};\n case (?last) last.next := ?node\n };\n queue.back := ?node;\n switch (queue.front) {\n case null queue.front := ?node;\n case (?_) {}\n };\n queue.size += 1\n };\n\n /// Removes and returns the first element in the queue.\n /// Returns null if the queue is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.popFront(queue) == ?1;\n /// assert Queue.size(queue) == 2;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func popFront<T>(queue : Queue<T>) : ?T {\n switch (queue.front) {\n case null null;\n case (?first) {\n queue.front := first.next;\n switch (queue.front) {\n case null { queue.back := null };\n case (?newFirst) { newFirst.previous := null }\n };\n queue.size -= 1;\n ?first.value\n }\n }\n };\n\n /// Removes and returns the last element in the queue.\n /// Returns null if the queue is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.popBack(queue) == ?3;\n /// assert Queue.size(queue) == 2;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func popBack<T>(queue : Queue<T>) : ?T {\n switch (queue.back) {\n case null null;\n case (?last) {\n queue.back := last.previous;\n switch (queue.back) {\n case null { queue.front := null };\n case (?newLast) { newLast.next := null }\n };\n queue.size -= 1;\n ?last.value\n }\n }\n };\n\n /// Creates a new queue from an iterator.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Text>([\"A\", \"B\", \"C\"].values());\n /// assert Queue.size(queue) == 3;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func fromIter<T>(iter : Iter.Iter<T>) : Queue<T> {\n let queue = empty<T>();\n for (element in iter) {\n pushBack(queue, element)\n };\n queue\n };\n\n /// Creates a new queue from an array.\n /// Elements appear in the same order as in the array.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromArray<Text>([\"A\", \"B\", \"C\"]);\n /// assert Queue.size(queue) == 3;\n /// assert Queue.peekFront(queue) == ?\"A\";\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the array.\n public func fromArray<T>(array : [T]) : Queue<T> {\n let queue = empty<T>();\n for (element in array.vals()) {\n pushBack(queue, element)\n };\n queue\n };\n\n /// Creates a new immutable array containing all elements from the queue.\n /// Elements appear in the same order as in the queue (front to back).\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n /// import Array \"mo:core/Array\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromArray<Text>([\"A\", \"B\", \"C\"]);\n /// let array = Queue.toArray(queue);\n /// assert array == [\"A\", \"B\", \"C\"];\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func toArray<T>(queue : Queue<T>) : [T] {\n let iter = values(queue);\n Array.tabulate<T>(\n queue.size,\n func(i) {\n switch (iter.next()) {\n case null { Prim.trap(\"Queue.toArray(): unexpected end of iterator\") };\n case (?value) { value }\n }\n }\n )\n };\n\n /// Returns an iterator over the elements in the queue.\n /// Iterates from front to back.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n /// persistent actor {\n /// let queue = Queue.fromIter<Text>([\"A\", \"B\", \"C\"].values());\n /// transient let iter = Queue.values(queue);\n /// assert iter.next() == ?\"A\";\n /// assert iter.next() == ?\"B\";\n /// assert iter.next() == ?\"C\";\n /// assert iter.next() == null;\n /// }\n /// ```\n ///\n /// Runtime: O(1) for iterator creation, O(n) for full iteration\n /// Space: O(1)\n public func values<T>(queue : Queue<T>) : Iter.Iter<T> {\n object {\n var current = queue.front;\n\n public func next() : ?T {\n switch (current) {\n case null null;\n case (?node) {\n current := node.next;\n ?node.value\n }\n }\n }\n }\n };\n\n /// Tests whether all elements in the queue satisfy the given predicate.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([2, 4, 6].values());\n /// assert Queue.all<Nat>(queue, func(x) { x % 2 == 0 });\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n public func all<T>(queue : Queue<T>, predicate : T -> Bool) : Bool {\n for (element in values(queue)) {\n if (not predicate(element)) {\n return false\n }\n };\n true\n };\n\n /// Tests whether any element in the queue satisfies the given predicate.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.any<Nat>(queue, func (x) { x > 2 });\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// `n` denotes the number of elements stored in the queue.\n public func any<T>(queue : Queue<T>, predicate : T -> Bool) : Bool {\n for (element in values(queue)) {\n if (predicate(element)) {\n return true\n }\n };\n false\n };\n\n /// Applies the given operation to all elements in the queue.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// var sum = 0;\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// Queue.forEach<Nat>(queue, func(x) { sum += x });\n /// assert sum == 6;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// `n` denotes the number of elements stored in the queue.\n public func forEach<T>(queue : Queue<T>, operation : T -> ()) {\n for (element in values(queue)) {\n operation(element)\n }\n };\n\n /// Creates a new queue by applying the given function to all elements.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let doubled = Queue.map<Nat, Nat>(queue, func(x) { x * 2 });\n /// assert Queue.peekFront(doubled) == ?2;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func map<T, U>(queue : Queue<T>, project : T -> U) : Queue<U> {\n let result = empty<U>();\n for (element in values(queue)) {\n pushBack(result, project(element))\n };\n result\n };\n\n /// Creates a new queue containing only elements that satisfy the given predicate.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3, 4].values());\n /// let evens = Queue.filter<Nat>(queue, func(x) { x % 2 == 0 });\n /// assert Queue.size(evens) == 2;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func filter<T>(queue : Queue<T>, criterion : T -> Bool) : Queue<T> {\n let result = empty<T>();\n for (element in values(queue)) {\n if (criterion(element)) {\n pushBack(result, element)\n }\n };\n result\n };\n\n /// Creates a new queue by applying the given function to all elements\n /// and keeping only the non-null results.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3, 4].values());\n /// let evenDoubled = Queue.filterMap<Nat, Nat>(\n /// queue,\n /// func(x) {\n /// if (x % 2 == 0) { ?(x * 2) } else { null }\n /// }\n /// );\n /// assert Queue.size(evenDoubled) == 2;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func filterMap<T, U>(queue : Queue<T>, project : T -> ?U) : Queue<U> {\n let result = empty<U>();\n for (element in values(queue)) {\n switch (project(element)) {\n case null {};\n case (?newElement) pushBack(result, newElement)\n }\n };\n result\n };\n\n /// Compares two queues for equality using the provided equality function.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue1 = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let queue2 = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.equal(queue1, queue2, Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// `n` denotes the number of elements stored in the queue.\n public func equal<T>(queue1 : Queue<T>, queue2 : Queue<T>, equal : (T, T) -> Bool) : Bool {\n if (size(queue1) != size(queue2)) {\n return false\n };\n let iterator1 = values(queue1);\n let iterator2 = values(queue2);\n loop {\n let element1 = iterator1.next();\n let element2 = iterator2.next();\n switch (element1, element2) {\n case (null, null) {\n return true\n };\n case (?element1, ?element2) {\n if (not equal(element1, element2)) {\n return false\n }\n };\n case _ { return false }\n }\n }\n };\n\n /// Converts a queue to its string representation using the provided element formatter.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.toText(queue, Nat.toText) == \"Queue[1, 2, 3]\";\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// `n` denotes the number of elements stored in the queue.\n public func toText<T>(queue : Queue<T>, format : T -> Text) : Text {\n var text = \"Queue[\";\n var sep = \"\";\n for (element in values(queue)) {\n text #= sep # format(element);\n sep := \", \"\n };\n text #= \"]\";\n text\n };\n\n /// Compares two queues using the provided comparison function.\n /// Returns #less, #equal, or #greater.\n ///\n /// Example:\n /// ```motoko\n /// import Queue \"mo:core/Queue\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue1 = Queue.fromIter<Nat>([1, 2].values());\n /// let queue2 = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.compare(queue1, queue2, Nat.compare) == #less;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// `n` denotes the number of elements stored in the queue.\n public func compare<T>(queue1 : Queue<T>, queue2 : Queue<T>, compareItem : (T, T) -> Order.Order) : Order.Order {\n let iterator1 = values(queue1);\n let iterator2 = values(queue2);\n loop {\n switch (iterator1.next(), iterator2.next()) {\n case (null, null) return #equal;\n case (null, _) return #less;\n case (_, null) return #greater;\n case (?element1, ?element2) {\n let comparison = compareItem(element1, element2);\n if (comparison != #equal) {\n return comparison\n }\n }\n }\n }\n }\n}\n"},"Int.mo":{"content":"/// Signed integer numbers with infinite precision (also called big integers).\n///\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `-1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Int \"mo:core/Int\";\n/// ```\n\nimport Prim \"mo:⛔\";\nimport Char \"Char\";\nimport Runtime \"Runtime\";\nimport Iter \"Iter\";\nimport Order \"Order\";\n\nmodule {\n\n /// Infinite precision signed integers.\n public type Int = Prim.Types.Int;\n\n /// Returns the absolute value of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.abs(-12) == 12;\n /// ```\n public func abs(x : Int) : Nat {\n Prim.abs(x)\n };\n\n /// Converts an integer number to its textual representation. Textual\n /// representation _do not_ contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.toText(-1234) == \"-1234\";\n /// ```\n public func toText(x : Int) : Text {\n if (x == 0) {\n return \"0\"\n };\n\n let isNegative = x < 0;\n var int = if isNegative { -x } else { x };\n\n var text = \"\";\n let base = 10;\n\n while (int > 0) {\n let rem = int % base;\n text := (\n switch (rem) {\n case 0 { \"0\" };\n case 1 { \"1\" };\n case 2 { \"2\" };\n case 3 { \"3\" };\n case 4 { \"4\" };\n case 5 { \"5\" };\n case 6 { \"6\" };\n case 7 { \"7\" };\n case 8 { \"8\" };\n case 9 { \"9\" };\n case _ { Runtime.unreachable() }\n }\n ) # text;\n int := int / base\n };\n\n return if isNegative { \"-\" # text } else { text }\n };\n\n /// Creates a integer from its textual representation. Returns `null`\n /// if the input is not a valid integer.\n ///\n /// The textual representation _must not_ contain underscores but may\n /// begin with a '+' or '-' character.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.fromText(\"-1234\") == ?-1234;\n /// ```\n public func fromText(text : Text) : ?Int {\n if (text == \"\") {\n return null\n };\n var n = 0;\n var isFirst = true;\n var isNegative = false;\n for (c in text.chars()) {\n if (isFirst and c == '+') {\n // Skip character\n } else if (isFirst and c == '-') {\n isNegative := true\n } else if (Char.isDigit(c)) {\n let charAsNat = Prim.nat32ToNat(Prim.charToNat32(c) -% Prim.charToNat32('0'));\n n := n * 10 + charAsNat\n } else {\n return null\n };\n isFirst := false\n };\n ?(if (isNegative) { -n } else { n })\n };\n\n /// Converts an integer to a natural number. Traps if the integer is negative.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Debug \"mo:core/Debug\";\n /// assert Int.toNat(1234 : Int) == (1234 : Nat);\n /// ```\n public func toNat(int : Int) : Nat {\n if (int < 0) {\n Runtime.trap(\"Int.toNat(): negative input value\")\n } else {\n abs(int)\n }\n };\n\n /// Converts a natural number to an integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.fromNat(1234 : Nat) == (1234 : Int);\n /// ```\n public func fromNat(nat : Nat) : Int {\n nat : Int\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.min(2, -3) == -3;\n /// ```\n public func min(x : Int, y : Int) : Int {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.max(2, -3) == 2;\n /// ```\n public func max(x : Int, y : Int) : Int {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.equal(-1, -1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Int = 1;\n /// let b : Int = -1;\n /// assert not Int.equal(a, b);\n /// ```\n public func equal(x : Int, y : Int) : Bool { x == y };\n\n /// Inequality function for Int types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.notEqual(-1, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int, y : Int) : Bool { x != y };\n\n /// \"Less than\" function for Int types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.less(-2, 1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int, y : Int) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.lessOrEqual(-2, 1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int, y : Int) : Bool { x <= y };\n\n /// \"Greater than\" function for Int types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.greater(1, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Int, y : Int) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.greaterOrEqual(1, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Int, y : Int) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.compare(-3, 2) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([1, -2, -3], Int.compare) == [-3, -2, 1];\n /// ```\n public func compare(x : Int, y : Int) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x` .\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.neg(123) == -123;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int) : Int { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// No overflow since `Int` has infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.add(1, -2) == -1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft([1, -2, -3], 0, Int.add) == -4;\n /// ```\n public func add(x : Int, y : Int) : Int { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// No overflow since `Int` has infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.sub(1, 2) == -1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft([1, -2, -3], 0, Int.sub) == 4;\n /// ```\n public func sub(x : Int, y : Int) : Int { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// No overflow since `Int` has infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.mul(-2, 3) == -6;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft([1, -2, -3], 1, Int.mul) == 6;\n /// ```\n public func mul(x : Int, y : Int) : Int { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.div(6, -2) == -3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int, y : Int) : Int { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.rem(6, -4) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int, y : Int) : Int { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps when `y` is negative or `y > 2 ** 32 - 1`.\n /// No overflow since `Int` has infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int.pow(-2, 3) == -8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int, y : Int) : Int { x ** y };\n\n /// Returns an iterator over the integers from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Int, toExclusive : Int) : Iter.Iter<Int> {\n object {\n var n = fromInclusive;\n public func next() : ?Int {\n if (n >= toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n };\n\n /// Returns an iterator over `Int` values from the first to second argument with an exclusive upper bound,\n /// incrementing by the specified step size.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// // Positive step\n /// let iter1 = Int.rangeBy(1, 7, 2);\n /// assert iter1.next() == ?1;\n /// assert iter1.next() == ?3;\n /// assert iter1.next() == ?5;\n /// assert iter1.next() == null;\n ///\n /// // Negative step\n /// let iter2 = Int.rangeBy(7, 1, -2);\n /// assert iter2.next() == ?7;\n /// assert iter2.next() == ?5;\n /// assert iter2.next() == ?3;\n /// assert iter2.next() == null;\n /// ```\n ///\n /// If `step` is 0 or if the iteration would not progress towards the bound, returns an empty iterator.\n public func rangeBy(fromInclusive : Int, toExclusive : Int, step : Int) : Iter.Iter<Int> {\n if (step == 0) {\n Iter.empty()\n } else if (step > 0 and fromInclusive < toExclusive) {\n object {\n var n = fromInclusive;\n public func next() : ?Int {\n if (n >= toExclusive) {\n null\n } else {\n let current = n;\n n += step;\n ?current\n }\n }\n }\n } else if (step < 0 and fromInclusive > toExclusive) {\n object {\n var n = fromInclusive;\n public func next() : ?Int {\n if (n <= toExclusive) {\n null\n } else {\n let current = n;\n n += step;\n ?current\n }\n }\n }\n } else {\n Iter.empty()\n }\n };\n\n /// Returns an iterator over the integers from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int.rangeInclusive(3, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Int, to : Int) : Iter.Iter<Int> {\n object {\n var n = from;\n public func next() : ?Int {\n if (n > to) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n };\n\n /// Returns an iterator over the integers from the first to second argument, inclusive,\n /// incrementing by the specified step size.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// // Positive step\n /// let iter1 = Int.rangeByInclusive(1, 7, 2);\n /// assert iter1.next() == ?1;\n /// assert iter1.next() == ?3;\n /// assert iter1.next() == ?5;\n /// assert iter1.next() == ?7;\n /// assert iter1.next() == null;\n ///\n /// // Negative step\n /// let iter2 = Int.rangeByInclusive(7, 1, -2);\n /// assert iter2.next() == ?7;\n /// assert iter2.next() == ?5;\n /// assert iter2.next() == ?3;\n /// assert iter2.next() == ?1;\n /// assert iter2.next() == null;\n /// ```\n ///\n /// If `from == to`, return an iterator which only returns that value.\n ///\n /// Otherwise, if `step` is 0 or if the iteration would not progress towards the bound, returns an empty iterator.\n public func rangeByInclusive(from : Int, to : Int, step : Int) : Iter.Iter<Int> {\n if (from == to) {\n Iter.singleton(from)\n } else if (step == 0) {\n Iter.empty()\n } else if (step > 0 and from < to) {\n object {\n var n = from;\n public func next() : ?Int {\n if (n >= to + 1) {\n null\n } else {\n let current = n;\n n += step;\n ?current\n }\n }\n }\n } else if (step < 0 and from > to) {\n object {\n var n = from;\n public func next() : ?Int {\n if (n + 1 <= to) {\n null\n } else {\n let current = n;\n n += step;\n ?current\n }\n }\n }\n } else {\n Iter.empty()\n }\n };\n\n}\n"},"Time.mo":{"content":"/// System time utilities and timers.\n///\n/// The following example illustrates using the system time:\n///\n/// ```motoko\n/// import Int = \"mo:core/Int\";\n/// import Time = \"mo:core/Time\";\n///\n/// persistent actor {\n/// var lastTime = Time.now();\n///\n/// public func greet(name : Text) : async Text {\n/// let now = Time.now();\n/// let elapsedSeconds = (now - lastTime) / 1000_000_000;\n/// lastTime := now;\n/// return \"Hello, \" # name # \"!\" #\n/// \" I was last called \" # Int.toText(elapsedSeconds) # \" seconds ago\";\n/// };\n/// };\n/// ```\n///\n/// Note: If `moc` is invoked with `-no-timer`, the importing will fail.\n/// Note: The resolution of the timers is in the order of the block rate,\n/// so durations should be chosen well above that. For frequent\n/// canister wake-ups the heartbeat mechanism should be considered.\n\nimport Types \"Types\";\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// System time is represent as nanoseconds since 1970-01-01.\n public type Time = Types.Time;\n\n /// Quantity of time expressed in `#days`, `#hours`, `#minutes`, `#seconds`, `#milliseconds`, or `#nanoseconds`.\n public type Duration = Types.Duration;\n\n /// Current system time given as nanoseconds since 1970-01-01. The system guarantees that:\n ///\n /// * the time, as observed by the canister smart contract, is monotonically increasing, even across canister upgrades.\n /// * within an invocation of one entry point, the time is constant.\n ///\n /// The system times of different canisters are unrelated, and calls from one canister to another may appear to travel \"backwards in time\"\n ///\n /// Note: While an implementation will likely try to keep the system time close to the real time, this is not formally guaranteed.\n public let now : () -> Time = func() : Int = Prim.nat64ToNat(Prim.time());\n\n public type TimerId = Nat;\n\n public func toNanoseconds(duration : Duration) : Nat {\n switch duration {\n case (#days n) n * 86_400_000_000_000;\n case (#hours n) n * 3_600_000_000_000;\n case (#minutes n) n * 60_000_000_000;\n case (#seconds n) n * 1_000_000_000;\n case (#milliseconds n) n * 1_000_000;\n case (#nanoseconds n) n\n }\n };\n\n}\n"},"Types.mo":{"content":"import Prim \"mo:⛔\";\n\nmodule {\n public type Blob = Prim.Types.Blob;\n public type Bool = Prim.Types.Bool;\n public type Char = Prim.Types.Char;\n public type Error = Prim.Types.Error;\n public type ErrorCode = Prim.ErrorCode;\n public type Float = Prim.Types.Float;\n public type Int = Prim.Types.Int;\n public type Int8 = Prim.Types.Int8;\n public type Int16 = Prim.Types.Int16;\n public type Int32 = Prim.Types.Int32;\n public type Int64 = Prim.Types.Int64;\n public type Nat = Prim.Types.Nat;\n public type Nat8 = Prim.Types.Nat8;\n public type Nat16 = Prim.Types.Nat16;\n public type Nat32 = Prim.Types.Nat32;\n public type Nat64 = Prim.Types.Nat64;\n public type Principal = Prim.Types.Principal;\n public type Region = Prim.Types.Region;\n public type Text = Prim.Types.Text;\n\n public type Hash = Nat32;\n public type Iter<T> = { next : () -> ?T };\n public type Order = { #less; #equal; #greater };\n public type Result<T, E> = { #ok : T; #err : E };\n public type Pattern = {\n #char : Char;\n #text : Text;\n #predicate : (Char -> Bool)\n };\n public type Time = Int;\n public type Duration = {\n #days : Nat;\n #hours : Nat;\n #minutes : Nat;\n #seconds : Nat;\n #milliseconds : Nat;\n #nanoseconds : Nat\n };\n public type TimerId = Nat;\n\n public type List<T> = {\n var blocks : [var [var ?T]];\n var blockIndex : Nat;\n var elementIndex : Nat\n };\n\n public module Queue {\n public type Queue<T> = {\n var front : ?Node<T>;\n var back : ?Node<T>;\n var size : Nat\n };\n\n public type Node<T> = {\n value : T;\n var next : ?Node<T>;\n var previous : ?Node<T>\n }\n };\n public type Queue<T> = Queue.Queue<T>;\n\n public module Set {\n public type Node<T> = {\n #leaf : Leaf<T>;\n #internal : Internal<T>\n };\n\n public type Data<T> = {\n elements : [var ?T];\n var count : Nat\n };\n\n public type Internal<T> = {\n data : Data<T>;\n children : [var ?Node<T>]\n };\n\n public type Leaf<T> = {\n data : Data<T>\n };\n\n public type Set<T> = {\n var root : Node<T>;\n var size : Nat\n }\n };\n public type Set<T> = Set.Set<T>;\n\n public module Map {\n public type Node<K, V> = {\n #leaf : Leaf<K, V>;\n #internal : Internal<K, V>\n };\n\n public type Data<K, V> = {\n kvs : [var ?(K, V)];\n var count : Nat\n };\n\n public type Internal<K, V> = {\n data : Data<K, V>;\n children : [var ?Node<K, V>]\n };\n\n public type Leaf<K, V> = {\n // why the extra indirection?\n data : Data<K, V>\n };\n\n public type Map<K, V> = {\n var root : Node<K, V>;\n var size : Nat\n }\n };\n\n public type Map<K, V> = Map.Map<K, V>;\n\n public module Stack {\n public type Stack<T> = {\n var top : Pure.List<T>;\n var size : Nat\n }\n };\n public type Stack<T> = Stack.Stack<T>;\n\n public module Pure {\n public type List<T> = ?(T, List<T>);\n\n public module Map {\n public type Map<K, V> = {\n size : Nat;\n root : Tree<K, V>\n };\n public type Tree<K, V> = {\n #red : (Tree<K, V>, K, V, Tree<K, V>);\n #black : (Tree<K, V>, K, V, Tree<K, V>);\n #leaf\n };\n\n };\n public type Map<K, V> = Map.Map<K, V>;\n\n public type Queue<T> = (List<T>, Nat, List<T>);\n\n public module Set {\n public type Tree<T> = {\n #red : (Tree<T>, T, Tree<T>);\n #black : (Tree<T>, T, Tree<T>);\n #leaf\n };\n\n public type Set<T> = { size : Nat; root : Tree<T> }\n };\n\n public type Set<T> = Set.Set<T>;\n\n }\n}\n"},"Float.mo":{"content":"/// Double precision (64-bit) floating-point numbers in IEEE 754 representation.\n///\n/// This module contains common floating-point constants and utility functions.\n///\n/// ```motoko name=import\n/// import Float \"mo:core/Float\";\n/// ```\n///\n/// Notation for special values in the documentation below:\n/// `+inf`: Positive infinity\n/// `-inf`: Negative infinity\n/// `NaN`: \"not a number\" (can have different sign bit values, but `NaN != NaN` regardless of the sign).\n///\n/// Note:\n/// Floating point numbers have limited precision and operations may inherently result in numerical errors.\n///\n/// Examples of numerical errors:\n/// ```motoko\n/// assert 0.1 + 0.1 + 0.1 != 0.3;\n/// ```\n///\n/// ```motoko\n/// assert not (1e16 + 1.0 != 1e16);\n/// ```\n///\n/// (and many more cases)\n///\n/// Advice:\n/// * Floating point number comparisons by `==` or `!=` are discouraged. Instead, it is better to compare\n/// floating-point numbers with a numerical tolerance, called epsilon.\n///\n/// Example:\n/// ```motoko\n/// import Float \"mo:core/Float\";\n/// let x = 0.1 + 0.1 + 0.1;\n/// let y = 0.3;\n///\n/// let epsilon = 1e-6; // This depends on the application case (needs a numerical error analysis).\n/// assert Float.equal(x, y, epsilon);\n/// ```\n///\n/// * For absolute precision, it is recommened to encode the fraction number as a pair of a Nat for the base\n/// and a Nat for the exponent (decimal point).\n///\n/// NaN sign:\n/// * The NaN sign is only applied by `abs`, `neg`, and `copySign`. Other operations can have an arbitrary\n/// sign bit for NaN results.\n\nimport Prim \"mo:⛔\";\nimport Int \"Int\";\nimport Order \"Order\";\n\nmodule {\n\n /// 64-bit floating point number type.\n public type Float = Prim.Types.Float;\n\n /// Ratio of the circumference of a circle to its diameter.\n /// Note: Limited precision.\n public let pi : Float = 3.14159265358979323846; // taken from musl math.h\n\n /// Base of the natural logarithm.\n /// Note: Limited precision.\n public let e : Float = 2.7182818284590452354; // taken from musl math.h\n\n /// Determines whether the `number` is a `NaN` (\"not a number\" in the floating point representation).\n /// Notes:\n /// * Equality test of `NaN` with itself or another number is always `false`.\n /// * There exist many internal `NaN` value representations, such as positive and negative NaN,\n /// signalling and quiet NaNs, each with many different bit representations.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.isNaN(0.0/0.0);\n /// ```\n public func isNaN(number : Float) : Bool {\n number != number\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Special cases:\n /// ```\n /// abs(+inf) => +inf\n /// abs(-inf) => +inf\n /// abs(-NaN) => +NaN\n /// abs(-0.0) => 0.0\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.abs(-1.2), 1.2, epsilon);\n /// ```\n public let abs : (x : Float) -> Float = Prim.floatAbs;\n\n /// Returns the square root of `x`.\n ///\n /// Special cases:\n /// ```\n /// sqrt(+inf) => +inf\n /// sqrt(-0.0) => -0.0\n /// sqrt(x) => NaN if x < 0.0\n /// sqrt(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.sqrt(6.25), 2.5, epsilon);\n /// ```\n public let sqrt : (x : Float) -> Float = Prim.floatSqrt;\n\n /// Returns the smallest integral float greater than or equal to `x`.\n ///\n /// Special cases:\n /// ```\n /// ceil(+inf) => +inf\n /// ceil(-inf) => -inf\n /// ceil(NaN) => NaN\n /// ceil(0.0) => 0.0\n /// ceil(-0.0) => -0.0\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.ceil(1.2), 2.0, epsilon);\n /// ```\n public let ceil : (x : Float) -> Float = Prim.floatCeil;\n\n /// Returns the largest integral float less than or equal to `x`.\n ///\n /// Special cases:\n /// ```\n /// floor(+inf) => +inf\n /// floor(-inf) => -inf\n /// floor(NaN) => NaN\n /// floor(0.0) => 0.0\n /// floor(-0.0) => -0.0\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.floor(1.2), 1.0, epsilon);\n /// ```\n public let floor : (x : Float) -> Float = Prim.floatFloor;\n\n /// Returns the nearest integral float not greater in magnitude than `x`.\n /// This is equivalent to returning `x` with truncating its decimal places.\n ///\n /// Special cases:\n /// ```\n /// trunc(+inf) => +inf\n /// trunc(-inf) => -inf\n /// trunc(NaN) => NaN\n /// trunc(0.0) => 0.0\n /// trunc(-0.0) => -0.0\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.trunc(2.75), 2.0, epsilon);\n /// ```\n public let trunc : (x : Float) -> Float = Prim.floatTrunc;\n\n /// Returns the nearest integral float to `x`.\n /// A decimal place of exactly .5 is rounded up for `x > 0`\n /// and rounded down for `x < 0`\n ///\n /// Special cases:\n /// ```\n /// nearest(+inf) => +inf\n /// nearest(-inf) => -inf\n /// nearest(NaN) => NaN\n /// nearest(0.0) => 0.0\n /// nearest(-0.0) => -0.0\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.nearest(2.75) == 3.0\n /// ```\n public let nearest : (x : Float) -> Float = Prim.floatNearest;\n\n /// Returns `x` if `x` and `y` have same sign, otherwise `x` with negated sign.\n ///\n /// The sign bit of zero, infinity, and `NaN` is considered.\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.copySign(1.2, -2.3), -1.2, epsilon);\n /// ```\n public let copySign : (x : Float, y : Float) -> Float = Prim.floatCopySign;\n\n /// Returns the smaller value of `x` and `y`.\n ///\n /// Special cases:\n /// ```\n /// min(NaN, y) => NaN for any Float y\n /// min(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.min(1.2, -2.3) == -2.3; // with numerical imprecision\n /// ```\n public let min : (x : Float, y : Float) -> Float = Prim.floatMin;\n\n /// Returns the larger value of `x` and `y`.\n ///\n /// Special cases:\n /// ```\n /// max(NaN, y) => NaN for any Float y\n /// max(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.max(1.2, -2.3) == 1.2;\n /// ```\n public let max : (x : Float, y : Float) -> Float = Prim.floatMax;\n\n /// Returns the sine of the radian angle `x`.\n ///\n /// Special cases:\n /// ```\n /// sin(+inf) => NaN\n /// sin(-inf) => NaN\n /// sin(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.sin(Float.pi / 2), 1.0, epsilon);\n /// ```\n public let sin : (x : Float) -> Float = Prim.sin;\n\n /// Returns the cosine of the radian angle `x`.\n ///\n /// Special cases:\n /// ```\n /// cos(+inf) => NaN\n /// cos(-inf) => NaN\n /// cos(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.cos(Float.pi / 2), 0.0, epsilon);\n /// ```\n public let cos : (x : Float) -> Float = Prim.cos;\n\n /// Returns the tangent of the radian angle `x`.\n ///\n /// Special cases:\n /// ```\n /// tan(+inf) => NaN\n /// tan(-inf) => NaN\n /// tan(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.tan(Float.pi / 4), 1.0, epsilon);\n /// ```\n public let tan : (x : Float) -> Float = Prim.tan;\n\n /// Returns the arc sine of `x` in radians.\n ///\n /// Special cases:\n /// ```\n /// arcsin(x) => NaN if x > 1.0\n /// arcsin(x) => NaN if x < -1.0\n /// arcsin(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.arcsin(1.0), Float.pi / 2, epsilon);\n /// ```\n public let arcsin : (x : Float) -> Float = Prim.arcsin;\n\n /// Returns the arc cosine of `x` in radians.\n ///\n /// Special cases:\n /// ```\n /// arccos(x) => NaN if x > 1.0\n /// arccos(x) => NaN if x < -1.0\n /// arcos(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.arccos(1.0), 0.0, epsilon);\n /// ```\n public let arccos : (x : Float) -> Float = Prim.arccos;\n\n /// Returns the arc tangent of `x` in radians.\n ///\n /// Special cases:\n /// ```\n /// arctan(+inf) => pi / 2\n /// arctan(-inf) => -pi / 2\n /// arctan(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.arctan(1.0), Float.pi / 4, epsilon);\n /// ```\n public let arctan : (x : Float) -> Float = Prim.arctan;\n\n /// Given `(y,x)`, returns the arc tangent in radians of `y/x` based on the signs of both values to determine the correct quadrant.\n ///\n /// Special cases:\n /// ```\n /// arctan2(0.0, 0.0) => 0.0\n /// arctan2(-0.0, 0.0) => -0.0\n /// arctan2(0.0, -0.0) => pi\n /// arctan2(-0.0, -0.0) => -pi\n /// arctan2(+inf, +inf) => pi / 4\n /// arctan2(+inf, -inf) => 3 * pi / 4\n /// arctan2(-inf, +inf) => -pi / 4\n /// arctan2(-inf, -inf) => -3 * pi / 4\n /// arctan2(NaN, x) => NaN for any Float x\n /// arctan2(y, NaN) => NaN for any Float y\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let sqrt2over2 = Float.sqrt(2) / 2;\n /// assert Float.arctan2(sqrt2over2, sqrt2over2) == Float.pi / 4;\n /// ```\n public let arctan2 : (y : Float, x : Float) -> Float = Prim.arctan2;\n\n /// Returns the value of `e` raised to the `x`-th power.\n ///\n /// Special cases:\n /// ```\n /// exp(+inf) => +inf\n /// exp(-inf) => 0.0\n /// exp(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.exp(1.0), Float.e, epsilon);\n /// ```\n public let exp : (x : Float) -> Float = Prim.exp;\n\n /// Returns the natural logarithm (base-`e`) of `x`.\n ///\n /// Special cases:\n /// ```\n /// log(0.0) => -inf\n /// log(-0.0) => -inf\n /// log(x) => NaN if x < 0.0\n /// log(+inf) => +inf\n /// log(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.log(Float.e), 1.0, epsilon);\n /// ```\n public let log : (x : Float) -> Float = Prim.log;\n\n /// Formatting. `format(fmt, x)` formats `x` to `Text` according to the\n /// formatting directive `fmt`, which can take one of the following forms:\n ///\n /// * `#fix prec` as fixed-point format with `prec` digits\n /// * `#exp prec` as exponential format with `prec` digits\n /// * `#gen prec` as generic format with `prec` digits\n /// * `#exact` as exact format that can be decoded without loss.\n ///\n /// `-0.0` is formatted with negative sign bit.\n /// Positive infinity is formatted as \"inf\".\n /// Negative infinity is formatted as \"-inf\".\n ///\n /// The numerical precision and the text format can vary between\n /// Motoko versions and runtime configuration. Moreover, `NaN` can be printed\n /// differently, i.e. \"NaN\" or \"nan\", potentially omitting the `NaN` sign.\n ///\n /// Example:\n /// ```motoko include=import no-validate\n /// assert Float.format(#exp 3, 123.0) == \"1.230e+02\";\n /// ```\n public func format(fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #exact }, x : Float) : Text = switch fmt {\n case (#fix(prec)) { Prim.floatToFormattedText(x, prec, 0) };\n case (#exp(prec)) { Prim.floatToFormattedText(x, prec, 1) };\n case (#gen(prec)) { Prim.floatToFormattedText(x, prec, 2) };\n case (#exact) { Prim.floatToFormattedText(x, 17, 2) }\n };\n\n /// Conversion to Text. Use `format(fmt, x)` for more detailed control.\n ///\n /// `-0.0` is formatted with negative sign bit.\n /// Positive infinity is formatted as `inf`.\n /// Negative infinity is formatted as `-inf`.\n /// `NaN` is formatted as `NaN` or `-NaN` depending on its sign bit.\n ///\n /// The numerical precision and the text format can vary between\n /// Motoko versions and runtime configuration. Moreover, `NaN` can be printed\n /// differently, i.e. \"NaN\" or \"nan\", potentially omitting the `NaN` sign.\n ///\n /// Example:\n /// ```motoko include=import no-validate\n /// assert Float.toText(1.2) == \"1.2\";\n /// ```\n public let toText : Float -> Text = Prim.floatToText;\n\n /// Conversion to Int64 by truncating Float, equivalent to `toInt64(trunc(f))`\n ///\n /// Traps if the floating point number is larger or smaller than the representable Int64.\n /// Also traps for `inf`, `-inf`, and `NaN`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.toInt64(-12.3) == -12;\n /// ```\n public let toInt64 : Float -> Int64 = Prim.floatToInt64;\n\n /// Conversion from Int64.\n ///\n /// Note: The floating point number may be imprecise for large or small Int64.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.fromInt64(-42) == -42.0;\n /// ```\n public let fromInt64 : Int64 -> Float = Prim.int64ToFloat;\n\n /// Conversion to Int.\n ///\n /// Traps for `inf`, `-inf`, and `NaN`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.toInt(1.2e6) == +1_200_000;\n /// ```\n public let toInt : Float -> Int = Prim.floatToInt;\n\n /// Conversion from Int. May result in `Inf`.\n ///\n /// Note: The floating point number may be imprecise for large or small Int values.\n /// Returns `inf` if the integer is greater than the maximum floating point number.\n /// Returns `-inf` if the integer is less than the minimum floating point number.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.fromInt(-123) == -123.0;\n /// ```\n public let fromInt : Int -> Float = Prim.intToFloat;\n\n /// Determines whether `x` is equal to `y` within the defined tolerance of `epsilon`.\n /// The `epsilon` considers numerical erros, see comment above.\n /// Equivalent to `Float.abs(x - y) <= epsilon` for a non-negative epsilon.\n ///\n /// Traps if `epsilon` is negative or `NaN`.\n ///\n /// Special cases:\n /// ```\n /// equal(+0.0, -0.0, epsilon) => true for any `epsilon >= 0.0`\n /// equal(-0.0, +0.0, epsilon) => true for any `epsilon >= 0.0`\n /// equal(+inf, +inf, epsilon) => true for any `epsilon >= 0.0`\n /// equal(-inf, -inf, epsilon) => true for any `epsilon >= 0.0`\n /// equal(x, NaN, epsilon) => false for any x and `epsilon >= 0.0`\n /// equal(NaN, y, epsilon) => false for any y and `epsilon >= 0.0`\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(-12.3, -1.23e1, epsilon);\n /// ```\n public func equal(x : Float, y : Float, epsilon : Float) : Bool {\n if (not (epsilon >= 0.0)) {\n // also considers NaN, not identical to `epsilon < 0.0`\n Prim.trap(\"Float.equal(): epsilon must be greater or equal 0.0\")\n };\n x == y or abs(x - y) <= epsilon // `x == y` to also consider infinity equal\n };\n\n /// Determines whether `x` is not equal to `y` within the defined tolerance of `epsilon`.\n /// The `epsilon` considers numerical erros, see comment above.\n /// Equivalent to `not equal(x, y, epsilon)`.\n ///\n /// Traps if `epsilon` is negative or `NaN`.\n ///\n /// Special cases:\n /// ```\n /// notEqual(+0.0, -0.0, epsilon) => false for any `epsilon >= 0.0`\n /// notEqual(-0.0, +0.0, epsilon) => false for any `epsilon >= 0.0`\n /// notEqual(+inf, +inf, epsilon) => false for any `epsilon >= 0.0`\n /// notEqual(-inf, -inf, epsilon) => false for any `epsilon >= 0.0`\n /// notEqual(x, NaN, epsilon) => true for any x and `epsilon >= 0.0`\n /// notEqual(NaN, y, epsilon) => true for any y and `epsilon >= 0.0`\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert not Float.notEqual(-12.3, -1.23e1, epsilon);\n /// ```\n public func notEqual(x : Float, y : Float, epsilon : Float) : Bool {\n if (not (epsilon >= 0.0)) {\n // also considers NaN, not identical to `epsilon < 0.0`\n Prim.trap(\"Float.notEqual(): epsilon must be greater or equal 0.0\")\n };\n not (x == y or abs(x - y) <= epsilon)\n };\n\n /// Returns `x < y`.\n ///\n /// Special cases:\n /// ```\n /// less(+0.0, -0.0) => false\n /// less(-0.0, +0.0) => false\n /// less(NaN, y) => false for any Float y\n /// less(x, NaN) => false for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.less(Float.e, Float.pi);\n /// ```\n public func less(x : Float, y : Float) : Bool { x < y };\n\n /// Returns `x <= y`.\n ///\n /// Special cases:\n /// ```\n /// lessOrEqual(+0.0, -0.0) => true\n /// lessOrEqual(-0.0, +0.0) => true\n /// lessOrEqual(NaN, y) => false for any Float y\n /// lessOrEqual(x, NaN) => false for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.lessOrEqual(0.123, 0.1234);\n /// ```\n public func lessOrEqual(x : Float, y : Float) : Bool { x <= y };\n\n /// Returns `x > y`.\n ///\n /// Special cases:\n /// ```\n /// greater(+0.0, -0.0) => false\n /// greater(-0.0, +0.0) => false\n /// greater(NaN, y) => false for any Float y\n /// greater(x, NaN) => false for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.greater(Float.pi, Float.e);\n /// ```\n public func greater(x : Float, y : Float) : Bool { x > y };\n\n /// Returns `x >= y`.\n ///\n /// Special cases:\n /// ```\n /// greaterOrEqual(+0.0, -0.0) => true\n /// greaterOrEqual(-0.0, +0.0) => true\n /// greaterOrEqual(NaN, y) => false for any Float y\n /// greaterOrEqual(x, NaN) => false for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.greaterOrEqual(0.1234, 0.123);\n /// ```\n public func greaterOrEqual(x : Float, y : Float) : Bool { x >= y };\n\n /// Defines a total order of `x` and `y` for use in sorting.\n ///\n /// Note: Using this operation to determine equality or inequality is discouraged for two reasons:\n /// * It does not consider numerical errors, see comment above. Use `equal(x, y, espilon)` or\n /// `notEqual(x, y, epsilon)` to test for equality or inequality, respectively.\n /// * `NaN` are here considered equal if their sign matches, which is different to the standard equality\n /// by `==` or when using `equal()` or `notEqual()`.\n ///\n /// Total order:\n /// * negative NaN (no distinction between signalling and quiet negative NaN)\n /// * negative infinity\n /// * negative numbers (including negative subnormal numbers in standard order)\n /// * negative zero (`-0.0`)\n /// * positive zero (`+0.0`)\n /// * positive numbers (including positive subnormal numbers in standard order)\n /// * positive infinity\n /// * positive NaN (no distinction between signalling and quiet positive NaN)\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Float.compare(0.123, 0.1234) == #less;\n /// ```\n public func compare(x : Float, y : Float) : Order.Order {\n if (isNaN(x)) {\n if (isNegative(x)) {\n if (isNaN(y) and isNegative(y)) { #equal } else { #less }\n } else {\n if (isNaN(y) and not isNegative(y)) { #equal } else { #greater }\n }\n } else if (isNaN(y)) {\n if (isNegative(y)) {\n #greater\n } else {\n #less\n }\n } else {\n if (x == y) { #equal } else if (x < y) { #less } else { #greater }\n }\n };\n\n func isNegative(number : Float) : Bool {\n copySign(1.0, number) < 0.0\n };\n\n /// Returns the negation of `x`, `-x` .\n ///\n /// Changes the sign bit for infinity.\n ///\n /// Special cases:\n /// ```\n /// neg(+inf) => -inf\n /// neg(-inf) => +inf\n /// neg(+NaN) => -NaN\n /// neg(-NaN) => +NaN\n /// neg(+0.0) => -0.0\n /// neg(-0.0) => +0.0\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.neg(1.23), -1.23, epsilon);\n /// ```\n public func neg(x : Float) : Float { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// add(+inf, y) => +inf if y is any Float except -inf and NaN\n /// add(-inf, y) => -inf if y is any Float except +inf and NaN\n /// add(+inf, -inf) => NaN\n /// add(NaN, y) => NaN for any Float y\n /// ```\n /// The same cases apply commutatively, i.e. for `add(y, x)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.add(1.23, 0.123), 1.353, epsilon);\n /// ```\n public func add(x : Float, y : Float) : Float { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// sub(+inf, y) => +inf if y is any Float except +inf or NaN\n /// sub(-inf, y) => -inf if y is any Float except -inf and NaN\n /// sub(x, +inf) => -inf if x is any Float except +inf and NaN\n /// sub(x, -inf) => +inf if x is any Float except -inf and NaN\n /// sub(+inf, +inf) => NaN\n /// sub(-inf, -inf) => NaN\n /// sub(NaN, y) => NaN for any Float y\n /// sub(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.sub(1.23, 0.123), 1.107, epsilon);\n /// ```\n public func sub(x : Float, y : Float) : Float { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// mul(+inf, y) => +inf if y > 0.0\n /// mul(-inf, y) => -inf if y > 0.0\n /// mul(+inf, y) => -inf if y < 0.0\n /// mul(-inf, y) => +inf if y < 0.0\n /// mul(+inf, 0.0) => NaN\n /// mul(-inf, 0.0) => NaN\n /// mul(NaN, y) => NaN for any Float y\n /// ```\n /// The same cases apply commutatively, i.e. for `mul(y, x)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.mul(1.23, 1e2), 123.0, epsilon);\n /// ```\n public func mul(x : Float, y : Float) : Float { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// div(0.0, 0.0) => NaN\n /// div(x, 0.0) => +inf for x > 0.0\n /// div(x, 0.0) => -inf for x < 0.0\n /// div(x, +inf) => 0.0 for any x except +inf, -inf, and NaN\n /// div(x, -inf) => 0.0 for any x except +inf, -inf, and NaN\n /// div(+inf, y) => +inf if y >= 0.0\n /// div(+inf, y) => -inf if y < 0.0\n /// div(-inf, y) => -inf if y >= 0.0\n /// div(-inf, y) => +inf if y < 0.0\n /// div(NaN, y) => NaN for any Float y\n /// div(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.div(1.23, 1e2), 0.0123, epsilon);\n /// ```\n public func div(x : Float, y : Float) : Float { x / y };\n\n /// Returns the floating point division remainder `x % y`,\n /// which is defined as `x - trunc(x / y) * y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// rem(0.0, 0.0) => NaN\n /// rem(x, y) => +inf if sign(x) == sign(y) for any x and y not being +inf, -inf, or NaN\n /// rem(x, y) => -inf if sign(x) != sign(y) for any x and y not being +inf, -inf, or NaN\n /// rem(x, +inf) => x for any x except +inf, -inf, and NaN\n /// rem(x, -inf) => x for any x except +inf, -inf, and NaN\n /// rem(+inf, y) => NaN for any Float y\n /// rem(-inf, y) => NaN for any Float y\n /// rem(NaN, y) => NaN for any Float y\n /// rem(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.rem(7.2, 2.3), 0.3, epsilon);\n /// ```\n public func rem(x : Float, y : Float) : Float { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// pow(+inf, y) => +inf for any y > 0.0 including +inf\n /// pow(+inf, 0.0) => 1.0\n /// pow(+inf, y) => 0.0 for any y < 0.0 including -inf\n /// pow(x, +inf) => +inf if x > 0.0 or x < 0.0\n /// pow(0.0, +inf) => 0.0\n /// pow(x, -inf) => 0.0 if x > 0.0 or x < 0.0\n /// pow(0.0, -inf) => +inf\n /// pow(x, y) => NaN if x < 0.0 and y is a non-integral Float\n /// pow(-inf, y) => +inf if y > 0.0 and y is a non-integral or an even integral Float\n /// pow(-inf, y) => -inf if y > 0.0 and y is an odd integral Float\n /// pow(-inf, 0.0) => 1.0\n /// pow(-inf, y) => 0.0 if y < 0.0\n /// pow(-inf, +inf) => +inf\n /// pow(-inf, -inf) => 1.0\n /// pow(NaN, y) => NaN if y != 0.0\n /// pow(NaN, 0.0) => 1.0\n /// pow(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko include=import\n /// let epsilon = 1e-6;\n /// assert Float.equal(Float.pow(2.5, 2.0), 6.25, epsilon);\n /// ```\n public func pow(x : Float, y : Float) : Float { x ** y };\n\n}\n"},"Option.mo":{"content":"/// Typesafe nullable values.\n///\n/// Optional values can be seen as a typesafe `null`. A value of type `?Int` can\n/// be constructed with either `null` or `?42`. The simplest way to get at the\n/// contents of an optional is to use pattern matching:\n///\n/// ```motoko\n/// let optionalInt1 : ?Int = ?42;\n/// let optionalInt2 : ?Int = null;\n///\n/// let int1orZero : Int = switch optionalInt1 {\n/// case null 0;\n/// case (?int) int;\n/// };\n/// assert int1orZero == 42;\n///\n/// let int2orZero : Int = switch optionalInt2 {\n/// case null 0;\n/// case (?int) int;\n/// };\n/// assert int2orZero == 0;\n/// ```\n///\n/// The functions in this module capture some common operations when working\n/// with optionals that can be more succinct than using pattern matching.\n\nimport Runtime \"Runtime\";\nimport Types \"Types\";\n\nmodule {\n\n /// Unwraps an optional value, with a default value, i.e. `get(?x, d) = x` and\n /// `get(null, d) = d`.\n public func get<T>(x : ?T, default : T) : T = switch x {\n case null { default };\n case (?x_) { x_ }\n };\n\n /// Unwraps an optional value using a function, or returns the default, i.e.\n /// `option(?x, f, d) = f x` and `option(null, f, d) = d`.\n public func getMapped<A, B>(x : ?A, f : A -> B, default : B) : B = switch x {\n case null { default };\n case (?x_) { f(x_) }\n };\n\n /// Applies a function to the wrapped value. `null`'s are left untouched.\n /// ```motoko\n /// import Option \"mo:core/Option\";\n /// assert Option.map<Nat, Nat>(?42, func x = x + 1) == ?43;\n /// assert Option.map<Nat, Nat>(null, func x = x + 1) == null;\n /// ```\n public func map<A, B>(x : ?A, f : A -> B) : ?B = switch x {\n case null { null };\n case (?x_) { ?f(x_) }\n };\n\n /// Applies a function to the wrapped value, but discards the result. Use\n /// `forEach` if you're only interested in the side effect `f` produces.\n ///\n /// ```motoko\n /// import Option \"mo:core/Option\";\n /// var counter : Nat = 0;\n /// Option.forEach(?5, func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// Option.forEach(null, func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// ```\n public func forEach<A>(x : ?A, f : A -> ()) = switch x {\n case null {};\n case (?x_) { f(x_) }\n };\n\n /// Applies an optional function to an optional value. Returns `null` if at\n /// least one of the arguments is `null`.\n public func apply<A, B>(x : ?A, f : ?(A -> B)) : ?B {\n switch (f, x) {\n case (?f_, ?x_) { ?f_(x_) };\n case (_, _) { null }\n }\n };\n\n /// Applies a function to an optional value. Returns `null` if the argument is\n /// `null`, or the function returns `null`.\n public func chain<A, B>(x : ?A, f : A -> ?B) : ?B {\n switch (x) {\n case (?x_) { f(x_) };\n case (null) { null }\n }\n };\n\n /// Given an optional optional value, removes one layer of optionality.\n /// ```motoko\n /// import Option \"mo:core/Option\";\n /// assert Option.flatten(?(?(42))) == ?42;\n /// assert Option.flatten(?(null)) == null;\n /// assert Option.flatten(null) == null;\n /// ```\n public func flatten<A>(x : ??A) : ?A {\n chain<?A, A>(x, func(x_ : ?A) : ?A = x_)\n };\n\n /// Creates an optional value from a definite value.\n /// ```motoko\n /// import Option \"mo:core/Option\";\n /// assert Option.some(42) == ?42;\n /// ```\n public func some<A>(x : A) : ?A = ?x;\n\n /// Returns true if the argument is not `null`, otherwise returns false.\n public func isSome(x : ?Any) : Bool {\n x != null\n };\n\n /// Returns true if the argument is `null`, otherwise returns false.\n public func isNull(x : ?Any) : Bool {\n x == null\n };\n\n /// Returns true if the optional arguments are equal according to the equality function provided, otherwise returns false.\n public func equal<A>(x : ?A, y : ?A, eq : (A, A) -> Bool) : Bool = switch (x, y) {\n case (null, null) { true };\n case (?x_, ?y_) { eq(x_, y_) };\n case (_, _) { false }\n };\n\n /// Compares two optional values using the provided comparison function.\n ///\n /// Returns:\n /// - `#equal` if both values are `null`,\n /// - `#less` if the first value is `null` and the second is not,\n /// - `#greater` if the first value is not `null` and the second is,\n /// - the result of the comparison function when both values are not `null`.\n public func compare<A>(x : ?A, y : ?A, cmp : (A, A) -> Types.Order) : Types.Order = switch (x, y) {\n case (null, null) #equal;\n case (null, _) #less;\n case (_, null) #greater;\n case (?x_, ?y_) { cmp(x_, y_) }\n };\n\n /// Unwraps an optional value, i.e. `unwrap(?x) = x`.\n ///\n /// `Option.unwrap()` fails if the argument is null. Consider using a `switch` or `do?` expression instead.\n public func unwrap<T>(x : ?T) : T = switch x {\n case null { Runtime.trap(\"Option.unwrap()\") };\n case (?x_) { x_ }\n };\n\n /// Returns the textural representation of an optional value for debugging purposes.\n public func toText<A>(x : ?A, toText : A -> Text) : Text = switch x {\n case null { \"null\" };\n case (?x_) { \"?\" # toText(x_) }\n };\n\n}\n"},"Timer.mo":{"content":"/// Timers for one-off or periodic tasks. Applicable as part of the default mechanism.\n/// If `moc` is invoked with `-no-timer`, the importing will fail. Furthermore, if passed `--trap-on-call-error`, a congested canister send queue may prevent timer expirations to execute at runtime. It may also deactivate the global timer.\n///\n/// ```motoko name=import\n/// import Timer \"mo:core/Timer\";\n/// ```\n///\n/// The resolution of the timers is similar to the block rate,\n/// so durations should be chosen well above that. For frequent\n/// canister wake-ups, consider using the [heartbeat](https://internetcomputer.org/docs/current/motoko/main/writing-motoko/heartbeats) mechanism; however, when possible, canisters should prefer timers.\n///\n/// The functionality described below is enabled only when the actor does not override it by declaring an explicit `system func timer`.\n///\n/// Timers are _not_ persisted across upgrades. One possible strategy\n/// to re-establish timers after an upgrade is to use stable variables\n/// in the `post_upgrade` hook and distill necessary timer information\n/// from there.\n///\n/// Using timers for security (e.g., access control) is strongly discouraged.\n/// Make sure to inform yourself about state-of-the-art dapp security.\n/// If you must use timers for security controls, be sure\n/// to consider reentrancy issues as well as the vanishing of timers on upgrades\n/// and reinstalls.\n///\n/// For further usage information for timers on the IC, please consult\n/// [the documentation](https://internetcomputer.org/docs/current/developer-docs/backend/periodic-tasks#timers-library-limitations).\nimport { setTimer = setTimerNano; cancelTimer = cancel } = \"mo:⛔\";\nimport Nat64 = \"Nat64\";\nimport Time \"Time\";\n\nmodule {\n\n public type TimerId = Nat;\n\n /// Installs a one-off timer that upon expiration after given duration `d`\n /// executes the future `job()`.\n ///\n /// ```motoko include=import no-repl\n /// import Int \"mo:core/Int\";\n ///\n /// func runIn30Minutes() : async () {\n /// // ...\n /// };\n /// let timerId = Timer.setTimer<system>(#minutes 30, runIn30Minutes);\n /// ```\n public func setTimer<system>(duration : Time.Duration, job : () -> async ()) : TimerId {\n setTimerNano<system>(Nat64.fromNat(Time.toNanoseconds duration), false, job)\n };\n\n /// Installs a recurring timer that upon expiration after given duration `d`\n /// executes the future `job()` and reinserts itself for another expiration.\n ///\n /// Note: A duration of 0 will only expire once.\n ///\n /// ```motoko include=import no-repl\n /// func runEvery30Minutes() : async () {\n /// // ...\n /// };\n /// let timerId = Timer.recurringTimer<system>(#minutes 30, runEvery30Minutes);\n /// ```\n public func recurringTimer<system>(duration : Time.Duration, job : () -> async ()) : TimerId {\n setTimerNano<system>(Nat64.fromNat(Time.toNanoseconds duration), true, job)\n };\n\n /// Cancels a still active timer with `(id : TimerId)`. For expired timers\n /// and not recognised `id`s nothing happens.\n ///\n /// ```motoko include=import no-repl\n /// var counter = 0;\n /// var timerId : ?Timer.TimerId = null;\n /// func runFiveTimes() : async () {\n /// counter += 1;\n /// if (counter == 5) {\n /// switch (timerId) {\n /// case (?id) { Timer.cancelTimer(id) };\n /// case null { assert false /* timer already cancelled */ };\n /// };\n /// }\n /// };\n /// timerId := ?Timer.recurringTimer<system>(#minutes 30, runFiveTimes);\n /// ```\n public let cancelTimer : TimerId -> () = cancel;\n\n}\n"},"Result.mo":{"content":"/// Module for error handling with the Result type.\n///\n/// The Result type is used for returning and propagating errors. It has two variants:\n/// `#ok(Ok)`, representing success and containing a value, and `#err(Err)`, representing\n/// error and containing an error value.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Result \"mo:core/Result\";\n/// ```\n\nimport Order \"Order\";\nimport Types \"Types\";\n\nmodule {\n\n /// The Result type used for returning and propagating errors.\n ///\n /// The simplest way of working with Results is to pattern match on them.\n /// For example:\n /// ```motoko include=import\n /// import Text \"mo:core/Text\";\n ///\n /// type Email = Text;\n /// type ErrorMessage = Text;\n ///\n /// func validateEmail(email : Text) : Result.Result<Email, ErrorMessage> {\n /// let parts = Text.split(email, #char '@');\n /// let beforeAt = parts.next();\n /// let afterAt = parts.next();\n /// switch (beforeAt, afterAt) {\n /// case (?local, ?domain) {\n /// if (local == \"\") return #err(\"Username cannot be empty\");\n /// if (not Text.contains(domain, #char '.')) return #err(\"Invalid domain format\");\n /// #ok(email)\n /// };\n /// case _ #err(\"Email must contain exactly one @ symbol\")\n /// }\n /// };\n ///\n /// assert validateEmail(\"user@example.com\") == #ok(\"user@example.com\");\n /// assert validateEmail(\"invalid.email\") == #err(\"Email must contain exactly one @ symbol\");\n /// assert validateEmail(\"@domain.com\") == #err(\"Username cannot be empty\");\n /// assert validateEmail(\"user@invalid\") == #err(\"Invalid domain format\");\n /// ```\n public type Result<Ok, Err> = Types.Result<Ok, Err>;\n\n /// Compares two Results for equality.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// let result1 = #ok 10;\n /// let result2 = #ok 10;\n /// let result3 = #err \"error\";\n ///\n /// assert Result.equal<Nat, Text>(result1, result2, Nat.equal, Text.equal);\n /// assert not Result.equal<Nat, Text>(result1, result3, Nat.equal, Text.equal);\n /// ```\n public func equal<Ok, Err>(\n result1 : Result<Ok, Err>,\n result2 : Result<Ok, Err>,\n equalOk : (Ok, Ok) -> Bool,\n equalErr : (Err, Err) -> Bool\n ) : Bool {\n switch (result1, result2) {\n case (#ok(ok1), #ok(ok2)) {\n equalOk(ok1, ok2)\n };\n case (#err(err1), #err(err2)) {\n equalErr(err1, err2)\n };\n case _ { false }\n }\n };\n\n /// Compares two Result values. `#ok` is larger than `#err`. This ordering is\n /// arbitrary, but it lets you for example use Results as keys in ordered maps.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// let result1 = #ok 5;\n /// let result2 = #ok 10;\n /// let result3 = #err \"error\";\n ///\n /// assert Result.compare<Nat, Text>(result1, result2, Nat.compare, Text.compare) == #less;\n /// assert Result.compare<Nat, Text>(result2, result1, Nat.compare, Text.compare) == #greater;\n /// assert Result.compare<Nat, Text>(result1, result3, Nat.compare, Text.compare) == #greater;\n /// ```\n public func compare<Ok, Err>(\n result1 : Result<Ok, Err>,\n result2 : Result<Ok, Err>,\n compareOk : (Ok, Ok) -> Order.Order,\n compareErr : (Err, Err) -> Order.Order\n ) : Order.Order {\n switch (result1, result2) {\n case (#ok(ok1), #ok(ok2)) {\n compareOk(ok1, ok2)\n };\n case (#err(err1), #err(err2)) {\n compareErr(err1, err2)\n };\n case (#ok(_), _) { #greater };\n case (#err(_), _) { #less }\n }\n };\n\n /// Allows sequencing of Result values and functions that return\n /// Results themselves.\n /// ```motoko include=import\n /// type Result<Ok,Err> = Result.Result<Ok, Err>;\n /// func largerThan10(x : Nat) : Result<Nat, Text> =\n /// if (x > 10) { #ok(x) } else { #err(\"Not larger than 10.\") };\n ///\n /// func smallerThan20(x : Nat) : Result<Nat, Text> =\n /// if (x < 20) { #ok(x) } else { #err(\"Not smaller than 20.\") };\n ///\n /// func between10And20(x : Nat) : Result<Nat, Text> =\n /// Result.chain(largerThan10(x), smallerThan20);\n ///\n /// assert between10And20(15) == #ok(15);\n /// assert between10And20(9) == #err(\"Not larger than 10.\");\n /// assert between10And20(21) == #err(\"Not smaller than 20.\");\n /// ```\n public func chain<Ok1, Ok2, Err>(\n result : Result<Ok1, Err>,\n f : Ok1 -> Result<Ok2, Err>\n ) : Result<Ok2, Err> {\n switch result {\n case (#err(e)) { #err(e) };\n case (#ok(r)) { f(r) }\n }\n };\n\n /// Flattens a nested Result.\n ///\n /// ```motoko include=import\n /// assert Result.flatten<Nat, Text>(#ok(#ok(10))) == #ok(10);\n /// assert Result.flatten<Nat, Text>(#err(\"Wrong\")) == #err(\"Wrong\");\n /// assert Result.flatten<Nat, Text>(#ok(#err(\"Wrong\"))) == #err(\"Wrong\");\n /// ```\n public func flatten<Ok, Err>(\n result : Result<Result<Ok, Err>, Err>\n ) : Result<Ok, Err> {\n switch result {\n case (#ok(ok)) { ok };\n case (#err(err)) { #err(err) }\n }\n };\n\n /// Maps the `Ok` type/value, leaving any `Err` type/value unchanged.\n ///\n /// Example:\n /// ```motoko include=import\n /// let result1 = #ok(42);\n /// let result2 = #err(\"error\");\n ///\n /// let doubled1 = Result.mapOk<Nat, Nat, Text>(result1, func x = x * 2);\n /// assert doubled1 == #ok(84);\n ///\n /// let doubled2 = Result.mapOk<Nat, Nat, Text>(result2, func x = x * 2);\n /// assert doubled2 == #err(\"error\");\n /// ```\n public func mapOk<Ok1, Ok2, Err>(\n result : Result<Ok1, Err>,\n f : Ok1 -> Ok2\n ) : Result<Ok2, Err> {\n switch result {\n case (#err(e)) { #err(e) };\n case (#ok(r)) { #ok(f(r)) }\n }\n };\n\n /// Maps the `Err` type/value, leaving any `Ok` type/value unchanged.\n ///\n /// Example:\n /// ```motoko include=import\n /// let result1 = #ok(42);\n /// let result2 = #err(\"error\");\n ///\n /// let mapped1 = Result.mapErr<Nat, Text, Text>(result1, func x = x # \"!\");\n /// assert mapped1 == #ok(42);\n ///\n /// let mapped2 = Result.mapErr<Nat, Text, Text>(result2, func x = x # \"!\");\n /// assert mapped2 == #err(\"error!\");\n /// ```\n public func mapErr<Ok, Err1, Err2>(\n result : Result<Ok, Err1>,\n f : Err1 -> Err2\n ) : Result<Ok, Err2> {\n switch result {\n case (#err(e)) { #err(f(e)) };\n case (#ok(r)) { #ok(r) }\n }\n };\n\n /// Create a result from an option, including an error value to handle the `null` case.\n /// ```motoko include=import\n /// assert Result.fromOption(?42, \"err\") == #ok(42);\n /// assert Result.fromOption(null, \"err\") == #err(\"err\");\n /// ```\n public func fromOption<Ok, Err>(x : ?Ok, err : Err) : Result<Ok, Err> {\n switch x {\n case (?x) { #ok(x) };\n case null { #err(err) }\n }\n };\n\n /// Create an option from a result, turning all #err into `null`.\n /// ```motoko include=import\n /// assert Result.toOption(#ok(42)) == ?42;\n /// assert Result.toOption(#err(\"err\")) == null;\n /// ```\n public func toOption<Ok, Err>(result : Result<Ok, Err>) : ?Ok {\n switch result {\n case (#ok(x)) { ?x };\n case (#err(_)) { null }\n }\n };\n\n /// Applies a function to a successful value and discards the result. Use\n /// `forOk` if you're only interested in the side effect `f` produces.\n ///\n /// ```motoko include=import\n /// var counter : Nat = 0;\n /// Result.forOk<Nat, Text>(#ok(5), func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// Result.forOk<Nat, Text>(#err(\"Error\"), func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// ```\n public func forOk<Ok, Err>(result : Result<Ok, Err>, f : Ok -> ()) {\n switch result {\n case (#ok(ok)) { f(ok) };\n case _ {}\n }\n };\n\n /// Applies a function to an error value and discards the result. Use\n /// `forErr` if you're only interested in the side effect `f` produces.\n ///\n /// ```motoko include=import\n /// var counter : Nat = 0;\n /// Result.forErr<Nat, Text>(#err(\"Error\"), func (x : Text) { counter += 1 });\n /// assert counter == 1;\n /// Result.forErr<Nat, Text>(#ok(5), func (x : Text) { counter += 1 });\n /// assert counter == 1;\n /// ```\n public func forErr<Ok, Err>(result : Result<Ok, Err>, f : Err -> ()) {\n switch result {\n case (#err(err)) { f(err) };\n case _ {}\n }\n };\n\n /// Whether this Result is an `#ok`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Result.isOk(#ok(42));\n /// assert not Result.isOk(#err(\"error\"));\n /// ```\n public func isOk(result : Result<Any, Any>) : Bool {\n switch result {\n case (#ok(_)) { true };\n case (#err(_)) { false }\n }\n };\n\n /// Whether this Result is an `#err`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Result.isErr(#err(\"error\"));\n /// assert not Result.isErr(#ok(42));\n /// ```\n public func isErr(result : Result<Any, Any>) : Bool {\n switch result {\n case (#ok(_)) { false };\n case (#err(_)) { true }\n }\n };\n\n /// Asserts that its argument is an `#ok` result, traps otherwise.\n ///\n /// Example:\n /// ```motoko include=import\n /// Result.assertOk(#ok(42)); // succeeds\n /// // Result.assertOk(#err(\"error\")); // would trap\n /// ```\n public func assertOk(result : Result<Any, Any>) {\n switch result {\n case (#err(_)) { assert false };\n case (#ok(_)) {}\n }\n };\n\n /// Asserts that its argument is an `#err` result, traps otherwise.\n ///\n /// Example:\n /// ```motoko include=import\n /// Result.assertErr(#err(\"error\")); // succeeds\n /// // Result.assertErr(#ok(42)); // would trap\n /// ```\n public func assertErr(result : Result<Any, Any>) {\n switch result {\n case (#err(_)) {};\n case (#ok(_)) assert false\n }\n };\n\n /// Converts an upper cased `#Ok`, `#Err` result type into a lowercased `#ok`, `#err` result type.\n /// On the IC, a common convention is to use `#Ok` and `#Err` as the variants of a result type,\n /// but in Motoko, we use `#ok` and `#err` instead.\n ///\n /// Example:\n /// ```motoko include=import\n /// let upper = #Ok(42);\n /// let lower = Result.fromUpper(upper);\n /// assert lower == #ok(42);\n /// ```\n public func fromUpper<Ok, Err>(\n result : { #Ok : Ok; #Err : Err }\n ) : Result<Ok, Err> {\n switch result {\n case (#Ok(ok)) { #ok(ok) };\n case (#Err(err)) { #err(err) }\n }\n };\n\n /// Converts a lower cased `#ok`, `#err` result type into an upper cased `#Ok`, `#Err` result type.\n /// On the IC, a common convention is to use `#Ok` and `#Err` as the variants of a result type,\n /// but in Motoko, we use `#ok` and `#err` instead.\n ///\n /// Example:\n /// ```motoko include=import\n /// let lower = #ok(42);\n /// let upper = Result.toUpper(lower);\n /// assert upper == #Ok(42);\n /// ```\n public func toUpper<Ok, Err>(\n result : Result<Ok, Err>\n ) : { #Ok : Ok; #Err : Err } {\n switch result {\n case (#ok(ok)) { #Ok(ok) };\n case (#err(err)) { #Err(err) }\n }\n };\n\n}\n"},"Nat8.mo":{"content":"/// Utility functions on 8-bit unsigned integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Nat8 \"mo:core/Nat8\";\n/// ```\nimport Nat \"Nat\";\nimport Iter \"Iter\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// 8-bit natural numbers.\n public type Nat8 = Prim.Types.Nat8;\n\n /// Maximum 8-bit natural number. `2 ** 8 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.maxValue == (255 : Nat8);\n /// ```\n public let maxValue : Nat8 = 255;\n\n /// Converts an 8-bit unsigned integer to an unsigned integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.toNat(123) == (123 : Nat);\n /// ```\n public let toNat : Nat8 -> Nat = Prim.nat8ToNat;\n\n /// Converts an unsigned integer with infinite precision to an 8-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.fromNat(123) == (123 : Nat8);\n /// ```\n public let fromNat : Nat -> Nat8 = Prim.natToNat8;\n\n /// Converts a 16-bit unsigned integer to a 8-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.fromNat16(123) == (123 : Nat8);\n /// ```\n public let fromNat16 : Nat16 -> Nat8 = Prim.nat16ToNat8;\n\n /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.toNat16(123) == (123 : Nat16);\n /// ```\n public let toNat16 : Nat8 -> Nat16 = Prim.nat8ToNat16;\n\n /// Converts a signed integer with infinite precision to an 8-bit unsigned integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.fromIntWrap(123) == (123 : Nat8);\n /// ```\n public let fromIntWrap : Int -> Nat8 = Prim.intToNat8Wrap;\n\n /// Converts `x` to its textual representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.toText(123) == (\"123\" : Text);\n /// ```\n public func toText(x : Nat8) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.min(123, 200) == (123 : Nat8);\n /// ```\n public func min(x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.max(123, 200) == (200 : Nat8);\n /// ```\n public func max(x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat8 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.equal(1, 1);\n /// assert (1 : Nat8) == (1 : Nat8);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Nat8 = 111;\n /// let b : Nat8 = 222;\n /// assert not Nat8.equal(a, b);\n /// ```\n public func equal(x : Nat8, y : Nat8) : Bool { x == y };\n\n /// Inequality function for Nat8 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.notEqual(1, 2);\n /// assert (1 : Nat8) != (2 : Nat8);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat8, y : Nat8) : Bool { x != y };\n\n /// \"Less than\" function for Nat8 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.less(1, 2);\n /// assert (1 : Nat8) < (2 : Nat8);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat8, y : Nat8) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat8 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.lessOrEqual(1, 2);\n /// assert 1 <= 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat8, y : Nat8) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat8 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.greater(2, 1);\n /// assert (2 : Nat8) > (1 : Nat8);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat8, y : Nat8) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat8 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.greaterOrEqual(2, 1);\n /// assert (2 : Nat8) >= (1 : Nat8);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat8, y : Nat8) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat8`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.compare(2, 3) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([2, 3, 1] : [Nat8], Nat8.compare) == [1, 2, 3];\n /// ```\n public func compare(x : Nat8, y : Nat8) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.add(1, 2) == 3;\n /// assert (1 : Nat8) + (2 : Nat8) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat8, Nat8>([2, 3, 1], 0, Nat8.add) == 6;\n /// ```\n public func add(x : Nat8, y : Nat8) : Nat8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.sub(2, 1) == 1;\n /// assert (2 : Nat8) - (1 : Nat8) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat8, Nat8>([2, 3, 1], 20, Nat8.sub) == 14;\n /// ```\n public func sub(x : Nat8, y : Nat8) : Nat8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.mul(2, 3) == 6;\n /// assert (2 : Nat8) * (3 : Nat8) == 6;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Nat8, Nat8>([2, 3, 1], 1, Nat8.mul) == 6;\n /// ```\n public func mul(x : Nat8, y : Nat8) : Nat8 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.div(6, 2) == 3;\n /// assert (6 : Nat8) / (2 : Nat8) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat8, y : Nat8) : Nat8 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.rem(6, 4) == 2;\n /// assert (6 : Nat8) % (4 : Nat8) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat8, y : Nat8) : Nat8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.pow(2, 3) == 8;\n /// assert (2 : Nat8) ** (3 : Nat8) == 8;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat8, y : Nat8) : Nat8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitnot(0) == 255;\n /// assert ^(0 : Nat8) == 255;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Nat8) : Nat8 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitand(3, 2) == 2;\n /// assert (3 : Nat8) & (2 : Nat8) == 2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Nat8, y : Nat8) : Nat8 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitor(3, 2) == 3;\n /// assert (3 : Nat8) | (2 : Nat8) == 3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Nat8, y : Nat8) : Nat8 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitxor(3, 2) == 1;\n /// assert (3 : Nat8) ^ (2 : Nat8) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Nat8, y : Nat8) : Nat8 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitshiftLeft(1, 2) == 4;\n /// assert (1 : Nat8) << (2 : Nat8) == 4;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Nat8, y : Nat8) : Nat8 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitshiftRight(4, 2) == 1;\n /// assert (4 : Nat8) >> (2 : Nat8) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Nat8, y : Nat8) : Nat8 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitrotLeft(128, 1) == 1;\n /// assert (128 : Nat8) <<> (1 : Nat8) == 1;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Nat8, y : Nat8) : Nat8 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitrotRight(1, 1) == 128;\n /// assert (1 : Nat8) <>> (1 : Nat8) == 128;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Nat8, y : Nat8) : Nat8 { x <>> y };\n\n /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bittest(5, 2);\n /// ```\n public func bittest(x : Nat8, p : Nat) : Bool {\n Prim.btstNat8(x, Prim.natToNat8(p))\n };\n\n /// Returns the value of setting bit `p mod 8` in `x` to `1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitset(5, 1) == 7;\n /// ```\n public func bitset(x : Nat8, p : Nat) : Nat8 {\n x | (1 << Prim.natToNat8(p))\n };\n\n /// Returns the value of clearing bit `p mod 8` in `x` to `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitclear(5, 2) == 1;\n /// ```\n public func bitclear(x : Nat8, p : Nat) : Nat8 {\n x & ^(1 << Prim.natToNat8(p))\n };\n\n /// Returns the value of flipping bit `p mod 8` in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitflip(5, 2) == 1;\n /// ```\n public func bitflip(x : Nat8, p : Nat) : Nat8 {\n x ^ (1 << Prim.natToNat8(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitcountNonZero(5) == 2;\n /// ```\n public let bitcountNonZero : (x : Nat8) -> Nat8 = Prim.popcntNat8;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitcountLeadingZero(5) == 5;\n /// ```\n public let bitcountLeadingZero : (x : Nat8) -> Nat8 = Prim.clzNat8;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.bitcountTrailingZero(6) == 1;\n /// ```\n public let bitcountTrailingZero : (x : Nat8) -> Nat8 = Prim.ctzNat8;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.addWrap(230, 26) == 0;\n /// assert (230 : Nat8) +% (26 : Nat8) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Nat8, y : Nat8) : Nat8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.subWrap(0, 1) == 255;\n /// assert (0 : Nat8) -% (1 : Nat8) == 255;\n /// ```\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Nat8, y : Nat8) : Nat8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.mulWrap(230, 26) == 92;\n /// assert (230 : Nat8) *% (26 : Nat8) == 92;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Nat8, y : Nat8) : Nat8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Nat8.powWrap(2, 8) == 0;\n /// assert (2 : Nat8) **% (8 : Nat8) == 0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Nat8, y : Nat8) : Nat8 { x **% y };\n\n /// Returns an iterator over `Nat8` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat8.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat8.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Nat8, toExclusive : Nat8) : Iter.Iter<Nat8> {\n if (fromInclusive >= toExclusive) {\n Iter.empty()\n } else {\n object {\n var n = fromInclusive;\n public func next() : ?Nat8 {\n if (n == toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over `Nat8` values from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat8.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat8.rangeInclusive(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Nat8, to : Nat8) : Iter.Iter<Nat8> {\n if (from > to) {\n Iter.empty()\n } else {\n object {\n var n = from;\n var done = false;\n public func next() : ?Nat8 {\n if (done) {\n null\n } else {\n let result = n;\n if (n == to) {\n done := true\n } else {\n n += 1\n };\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over all Nat8 values, from 0 to maxValue.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Nat8.allValues();\n /// assert iter.next() == ?0;\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Nat8> {\n rangeInclusive(0, maxValue)\n };\n\n}\n"},"Stack.mo":{"content":"/// A mutable stack data structure.\n/// Elements can be pushed on top of the stack\n/// and removed from top of the stack (LIFO).\n///\n/// Example:\n/// ```motoko\n/// import Stack \"mo:core/Stack\";\n/// import Debug \"mo:core/Debug\";\n///\n/// persistent actor {\n/// let levels = Stack.empty<Text>();\n/// Stack.push(levels, \"Inner\");\n/// Stack.push(levels, \"Middle\");\n/// Stack.push(levels, \"Outer\");\n/// assert Stack.pop(levels) == ?\"Outer\";\n/// assert Stack.pop(levels) == ?\"Middle\";\n/// assert Stack.pop(levels) == ?\"Inner\";\n/// assert Stack.pop(levels) == null;\n/// }\n/// ```\n///\n/// The internal implementation is a singly-linked list.\n///\n/// Performance:\n/// * Runtime: `O(1)` for push, pop, and peek operation.\n/// * Space: `O(n)`.\n/// `n` denotes the number of elements stored on the stack.\n\n// TODO: optimize or re-use pure/List operations (e.g. for `any` etc)\n\nimport Order \"Order\";\nimport Types \"Types\";\nimport PureList \"pure/List\";\n\nmodule {\n type List<T> = Types.Pure.List<T>;\n public type Stack<T> = Types.Stack<T>;\n\n /// Convert a mutable stack to an immutable, purely functional list.\n /// Please note that functional lists are ordered like stacks (FIFO).\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import PureList \"mo:core/pure/List\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let mutableStack = Stack.empty<Nat>();\n /// Stack.push(mutableStack, 3);\n /// Stack.push(mutableStack, 2);\n /// Stack.push(mutableStack, 1);\n /// let immutableList = Stack.toPure(mutableStack);\n /// assert Iter.toArray(PureList.values(immutableList)) == [1, 2, 3];\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements stored in the stack.\n public func toPure<T>(stack : Stack<T>) : PureList.List<T> {\n stack.top\n };\n\n /// Convert an immutable, purely functional list to a mutable stack.\n /// Please note that functional lists are ordered like stacks (FIFO).\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import PureList \"mo:core/pure/List\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let immutableList = PureList.fromIter<Nat>([1, 2, 3].values());\n /// let mutableStack = Stack.fromPure<Nat>(immutableList);\n /// assert Iter.toArray(Stack.values(mutableStack)) == [1, 2, 3];\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of elements stored in the queue.\n public func fromPure<T>(list : PureList.List<T>) : Stack<T> {\n var size = 0;\n var cur = list;\n loop {\n switch cur {\n case (?(_, next)) {\n size += 1;\n cur := next\n };\n case null {\n return { var top = list; var size }\n }\n }\n }\n };\n\n /// Create a new empty mutable stack.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Text>();\n /// assert Stack.size(stack) == 0;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func empty<T>() : Stack<T> {\n {\n var top = null;\n var size = 0\n }\n };\n\n /// Creates a new stack with `size` elements by applying the `generator` function to indices `[0..size-1]`.\n /// Elements are pushed in ascending index order.\n /// Which means that the generated element with the index `0` will be at the bottom of the stack.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let stack = Stack.tabulate<Nat>(3, func(i) { 2 * i });\n /// assert Iter.toArray(Stack.values(stack)) == [4, 2, 0];\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming that `generator` has O(1) costs.\n public func tabulate<T>(size : Nat, generator : Nat -> T) : Stack<T> {\n let stack = empty<T>();\n var index = 0;\n while (index < size) {\n let element = generator(index);\n push(stack, element);\n index += 1\n };\n stack\n };\n\n /// Creates a new stack containing a single element.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.singleton<Text>(\"motoko\");\n /// assert Stack.peek(stack) == ?\"motoko\";\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func singleton<T>(element : T) : Stack<T> {\n let stack = empty<T>();\n push(stack, element);\n stack\n };\n\n /// Removes all elements from the stack.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.fromIter<Nat>([3, 2, 1].values());\n /// Stack.clear(stack);\n /// assert Stack.isEmpty(stack);\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func clear<T>(stack : Stack<T>) {\n stack.top := null;\n stack.size := 0\n };\n\n /// Creates a deep copy of the stack with the same elements in the same order.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let original = Stack.fromIter<Nat>([3, 2, 1].values());\n /// let copy = Stack.clone(original);\n /// assert Stack.equal(copy, original, Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// where `n` denotes the number of elements stored on the stack.\n public func clone<T>(stack : Stack<T>) : Stack<T> {\n let copy = empty<T>();\n for (element in values(stack)) {\n push(copy, element)\n };\n reverse(copy);\n copy\n };\n\n /// Returns true if the stack contains no elements.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// assert Stack.isEmpty(stack);\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func isEmpty<T>(stack : Stack<T>) : Bool {\n stack.size == 0\n };\n\n /// Returns the number of elements on the stack.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.fromIter<Nat>([3, 2, 1].values());\n /// assert Stack.size(stack) == 3;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func size<T>(stack : Stack<T>) : Nat {\n stack.size\n };\n\n /// Returns true if the stack contains the specified element.\n /// Uses the provided equality function to compare elements.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let stack = Stack.fromIter<Nat>([3, 2, 1].values());\n /// assert Stack.contains(stack, 2, Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// where `n` denotes the number of elements stored on the stack and assuming\n /// that `equal` has O(1) costs.\n public func contains<T>(stack : Stack<T>, element : T, equal : (T, T) -> Bool) : Bool {\n for (existing in values(stack)) {\n if (equal(existing, element)) {\n return true\n }\n };\n false\n };\n\n /// Pushes a new element onto the top of the stack.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 42);\n /// assert Stack.peek(stack) == ?42;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func push<T>(stack : Stack<T>, value : T) {\n stack.top := ?(value, stack.top);\n stack.size += 1\n };\n\n /// Returns the top element of the stack without removing it.\n /// Returns null if the stack is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 3);\n /// Stack.push(stack, 2);\n /// Stack.push(stack, 1);\n /// assert Stack.peek(stack) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func peek<T>(stack : Stack<T>) : ?T {\n switch (stack.top) {\n case null null;\n case (?(value, _)) ?value\n }\n };\n\n /// Removes and returns the top element of the stack.\n /// Returns null if the stack is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 3);\n /// Stack.push(stack, 2);\n /// Stack.push(stack, 1);\n /// assert Stack.pop(stack) == ?1;\n /// assert Stack.pop(stack) == ?2;\n /// assert Stack.pop(stack) == ?3;\n /// assert Stack.pop(stack) == null;\n /// }\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func pop<T>(stack : Stack<T>) : ?T {\n switch (stack.top) {\n case null null;\n case (?(value, next)) {\n stack.top := next;\n stack.size -= 1;\n ?value\n }\n }\n };\n\n /// Returns the element at the specified position from the top of the stack.\n /// Returns null if position is out of bounds.\n /// Position 0 is the top of the stack.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Char>();\n /// Stack.push(stack, 'c');\n /// Stack.push(stack, 'b');\n /// Stack.push(stack, 'a');\n /// assert Stack.get(stack, 0) == ?'a';\n /// assert Stack.get(stack, 1) == ?'b';\n /// assert Stack.get(stack, 2) == ?'c';\n /// assert Stack.get(stack, 3) == null;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// where `n` denotes the number of elements stored on the stack.\n public func get<T>(stack : Stack<T>, position : Nat) : ?T {\n var index = 0;\n var current = stack.top;\n while (index < position) {\n switch (current) {\n case null return null;\n case (?(_, next)) {\n current := next\n }\n };\n index += 1\n };\n switch (current) {\n case null null;\n case (?(value, _)) ?value\n }\n };\n\n /// Reverses the order of elements in the stack.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 3);\n /// Stack.push(stack, 2);\n /// Stack.push(stack, 1);\n /// Stack.reverse(stack);\n /// assert Stack.pop(stack) == ?3;\n /// assert Stack.pop(stack) == ?2;\n /// assert Stack.pop(stack) == ?1;\n /// assert Stack.pop(stack) == null;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// where `n` denotes the number of elements stored on the stack.\n public func reverse<T>(stack : Stack<T>) {\n var last : List<T> = null;\n for (element in values(stack)) {\n last := ?(element, last)\n };\n stack.top := last\n };\n\n /// Returns an iterator over the elements in the stack, from top to bottom.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 3);\n /// Stack.push(stack, 2);\n /// Stack.push(stack, 1);\n /// assert Iter.toArray(Stack.values(stack)) == [1, 2, 3];\n /// }\n /// ```\n ///\n /// Runtime: O(1) for iterator creation, O(n) for full traversal\n /// Space: O(1)\n /// where `n` denotes the number of elements stored on the stack.\n public func values<T>(stack : Stack<T>) : Types.Iter<T> {\n object {\n var current = stack.top;\n\n public func next() : ?T {\n switch (current) {\n case null null;\n case (?(value, next)) {\n current := next;\n ?value\n }\n }\n }\n }\n };\n\n /// Returns true if all elements in the stack satisfy the predicate.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.fromIter<Nat>([2, 4, 6].values());\n /// assert Stack.all<Nat>(stack, func(n) = n % 2 == 0);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming that `predicate` has O(1) costs.\n public func all<T>(stack : Stack<T>, predicate : T -> Bool) : Bool {\n for (element in values(stack)) {\n if (not predicate(element)) {\n return false\n }\n };\n true\n };\n\n /// Returns true if any element in the stack satisfies the predicate.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.fromIter<Nat>([3, 2, 1].values());\n /// assert Stack.any<Nat>(stack, func(n) = n == 2);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming `predicate` has O(1) costs.\n public func any<T>(stack : Stack<T>, predicate : T -> Bool) : Bool {\n for (element in values(stack)) {\n if (predicate(element)) {\n return true\n }\n };\n false\n };\n\n /// Applies the operation to each element in the stack, from top to bottom.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Nat \"mo:core/Nat\";\n /// import Debug \"mo:core/Debug\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 3);\n /// Stack.push(stack, 2);\n /// Stack.push(stack, 1);\n /// var text = \"\";\n /// Stack.forEach<Nat>(stack, func(n) = text #= Nat.toText(n));\n /// assert text == \"123\";\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming that `operation` has O(1) costs.\n public func forEach<T>(stack : Stack<T>, operation : T -> ()) {\n for (element in values(stack)) {\n operation(element)\n }\n };\n\n /// Creates a new stack by applying the projection function to each element.\n /// Maintains the original order of elements.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 3);\n /// Stack.push(stack, 2);\n /// Stack.push(stack, 1);\n /// let doubled = Stack.map<Nat, Nat>(stack, func(n) { 2 * n });\n /// assert Stack.get(doubled, 0) == ?2;\n /// assert Stack.get(doubled, 1) == ?4;\n /// assert Stack.get(doubled, 2) == ?6;\n /// assert Stack.get(doubled, 3) == null;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming that `project` has O(1) costs.\n public func map<T, U>(stack : Stack<T>, project : T -> U) : Stack<U> {\n let result = empty<U>();\n for (element in values(stack)) {\n push(result, project(element))\n };\n reverse(result);\n result\n };\n\n /// Creates a new stack containing only elements that satisfy the predicate.\n /// Maintains the relative order of elements.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 4);\n /// Stack.push(stack, 3);\n /// Stack.push(stack, 2);\n /// Stack.push(stack, 1);\n /// let evens = Stack.filter<Nat>(stack, func(n) { n % 2 == 0 });\n /// assert Stack.pop(evens) == ?2;\n /// assert Stack.pop(evens) == ?4;\n /// assert Stack.pop(evens) == null;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming `predicate` has O(1) costs.\n public func filter<T>(stack : Stack<T>, predicate : T -> Bool) : Stack<T> {\n let result = empty<T>();\n for (element in values(stack)) {\n if (predicate(element)) {\n push(result, element)\n }\n };\n reverse(result);\n result\n };\n\n /// Creates a new stack by applying the projection function to each element\n /// and keeping only the successful results (where project returns ?value).\n /// Maintains the relative order of elements.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n ///\n /// persistent actor {\n /// let stack = Stack.empty<Nat>();\n /// Stack.push(stack, 4);\n /// Stack.push(stack, 3);\n /// Stack.push(stack, 2);\n /// Stack.push(stack, 1);\n /// let evenDoubled = Stack.filterMap<Nat, Nat>(stack, func(n) {\n /// if (n % 2 == 0) {\n /// ?(n * 2)\n /// } else {\n /// null\n /// }\n /// });\n /// assert Stack.pop(evenDoubled) == ?4;\n /// assert Stack.pop(evenDoubled) == ?8;\n /// assert Stack.pop(evenDoubled) == null;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming that `project` has O(1) costs.\n public func filterMap<T, U>(stack : Stack<T>, project : T -> ?U) : Stack<U> {\n let result = empty<U>();\n for (element in values(stack)) {\n switch (project(element)) {\n case null {};\n case (?newElement) {\n push(result, newElement)\n }\n }\n };\n reverse(result);\n result\n };\n\n /// Compares two stacks for equality using the provided equality function.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let stack1 = Stack.fromIter<Nat>([3, 2, 1].values());\n /// let stack2 = Stack.fromIter<Nat>([3, 2, 1].values());\n /// assert Stack.equal(stack1, stack2, Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming that `equal` has O(1) costs.\n public func equal<T>(stack1 : Stack<T>, stack2 : Stack<T>, equal : (T, T) -> Bool) : Bool {\n if (size(stack1) != size(stack2)) {\n return false\n };\n let iterator1 = values(stack1);\n let iterator2 = values(stack2);\n loop {\n let element1 = iterator1.next();\n let element2 = iterator2.next();\n switch (element1, element2) {\n case (null, null) {\n return true\n };\n case (?element1, ?element2) {\n if (not equal(element1, element2)) {\n return false\n }\n };\n case _ { return false }\n }\n }\n };\n\n /// Creates a new stack from an iterator.\n /// Elements are pushed in iteration order. Which means that the last element\n /// of the iterator will be the first element on top of the stack.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let stack = Stack.fromIter<Nat>([3, 2, 1].values());\n /// assert Iter.toArray(Stack.values(stack)) == [1, 2, 3];\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// where `n` denotes the number of iterated elements.\n public func fromIter<T>(iter : Types.Iter<T>) : Stack<T> {\n let stack = empty<T>();\n for (element in iter) {\n push(stack, element)\n };\n stack\n };\n\n /// Converts the stack to its string representation using the provided\n /// element formatting function.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let stack = Stack.fromIter<Nat>([3, 2, 1].values());\n /// assert Stack.toText(stack, Nat.toText) == \"Stack[1, 2, 3]\";\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(n)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming that `format` has O(1) costs.\n public func toText<T>(stack : Stack<T>, format : T -> Text) : Text {\n var text = \"Stack[\";\n var sep = \"\";\n for (element in values(stack)) {\n text #= sep # format(element);\n sep := \", \"\n };\n text #= \"]\";\n text\n };\n\n /// Compares two stacks lexicographically using the provided comparison function.\n ///\n /// Example:\n /// ```motoko\n /// import Stack \"mo:core/Stack\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let stack1 = Stack.fromIter<Nat>([2, 1].values());\n /// let stack2 = Stack.fromIter<Nat>([3, 2, 1].values());\n /// assert Stack.compare(stack1, stack2, Nat.compare) == #less;\n /// }\n /// ```\n ///\n /// Runtime: O(n)\n /// Space: O(1)\n /// where `n` denotes the number of elements stored on the stack and\n /// assuming that `compare` has O(1) costs.\n public func compare<T>(stack1 : Stack<T>, stack2 : Stack<T>, compare : (T, T) -> Order.Order) : Order.Order {\n let iterator1 = values(stack1);\n let iterator2 = values(stack2);\n loop {\n switch (iterator1.next(), iterator2.next()) {\n case (null, null) return #equal;\n case (null, _) return #less;\n case (_, null) return #greater;\n case (?element1, ?element2) {\n let comparison = compare(element1, element2);\n if (comparison != #equal) {\n return comparison\n }\n }\n }\n }\n }\n}\n"},"Region.mo":{"content":"/// Byte-level access to isolated, virtual stable memory regions.\n///\n/// This is a moderately lightweight abstraction over IC _stable memory_ and supports persisting\n/// regions of binary data across Motoko upgrades.\n/// Use of this module is fully compatible with Motoko's use of\n/// _stable variables_, whose persistence mechanism also uses (real) IC stable memory internally, but does not interfere with this API.\n/// It is also fully compatible with existing uses of the `ExperimentalStableMemory` library, which has a similar interface, but,\n/// only supported a single memory region, without isolation between different applications.\n///\n/// The `Region` type is stable and can be used in stable data structures.\n///\n/// A new, empty `Region` is allocated using function `new()`.\n///\n/// Regions are stateful objects and can be distinguished by the numeric identifier returned by function `id(region)`.\n/// Every region owns an initially empty, but growable sequence of virtual IC stable memory pages.\n/// The current size, in pages, of a region is returned by function `size(region)`.\n/// The size of a region determines the range, [ 0, ..., size(region)*2^16 ), of valid byte-offsets into the region; these offsets are used as the source and destination of `load`/`store` operations on the region.\n///\n/// Memory is allocated to a region, using function `grow(region, pages)`, sequentially and on demand, in units of 64KiB logical pages, starting with 0 allocated pages.\n/// A call to `grow` may succeed, returning the previous size of the region, or fail, returning a sentinel value. New pages are zero initialized.\n///\n/// A size of a region can only grow and never shrink.\n/// In addition, the stable memory pages allocated to a region will *not* be reclaimed by garbage collection, even\n/// if the region object itself becomes unreachable.\n///\n/// Growth is capped by a soft limit on physical page count controlled by compile-time flag\n/// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n///\n/// Each `load` operation loads from region relative byte address `offset` in little-endian\n/// format using the natural bit-width of the type in question.\n/// The operation traps if attempting to read beyond the current region size.\n///\n/// Each `store` operation stores to region relative byte address `offset` in little-endian format using the natural bit-width of the type in question.\n/// The operation traps if attempting to write beyond the current region size.\n///\n/// Text values can be handled by using `Text.decodeUtf8` and `Text.encodeUtf8`, in conjunction with `loadBlob` and `storeBlob`.\n///\n/// The current region allocation and region contents are preserved across upgrades.\n///\n/// NB: The IC's actual stable memory size (`ic0.stable_size`) may exceed the\n/// total page size reported by summing all regions sizes.\n/// This (and the cap on growth) are to accommodate Motoko's stable variables and bookkeeping for regions.\n/// Applications that plan to use Motoko stable variables sparingly or not at all can\n/// increase `--max-stable-pages` as desired, approaching the IC maximum (initially 8GiB, then 32Gib, currently 64Gib).\n/// All applications should reserve at least one page for stable variable data, even when no stable variables are used.\n///\n/// Usage:\n/// ```motoko no-repl name=import\n/// import Region \"mo:core/Region\";\n/// ```\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// A stateful handle to an isolated region of IC stable memory.\n /// `Region` is a stable type and regions can be stored in stable variables.\n public type Region = Prim.Types.Region;\n\n /// Allocate a new, isolated Region of size 0.\n ///\n /// Example:\n ///\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// assert Region.size(region) == 0;\n /// }\n /// }\n /// ```\n public let new : () -> Region = Prim.regionNew;\n\n /// Return a Nat identifying the given region.\n /// May be used for equality, comparison and hashing.\n /// NB: Regions returned by `new()` are numbered from 16\n /// (regions 0..15 are currently reserved for internal use).\n /// Allocate a new, isolated Region of size 0.\n ///\n /// Example:\n ///\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// assert Region.id(region) == 16;\n /// }\n /// }\n /// ```\n public let id : Region -> Nat = Prim.regionId;\n\n /// Current size of `region`, in pages.\n /// Each page is 64KiB (65536 bytes).\n /// Initially `0`.\n /// Preserved across upgrades, together with contents of allocated\n /// stable memory.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let beforeSize = Region.size(region);\n /// ignore Region.grow(region, 10);\n /// let afterSize = Region.size(region);\n /// assert afterSize - beforeSize == 10;\n /// }\n /// }\n /// ```\n public let size : (region : Region) -> (pages : Nat64) = Prim.regionSize;\n\n /// Grow current `size` of `region` by the given number of pages.\n /// Each page is 64KiB (65536 bytes).\n /// Returns the previous `size` when able to grow.\n /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n /// Every new page is zero-initialized, containing byte 0x00 at every offset.\n /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n /// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// import Error \"mo:core/Error\";\n ///\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let beforeSize = Region.grow(region, 10);\n /// if (beforeSize == 0xFFFF_FFFF_FFFF_FFFF) {\n /// throw Error.reject(\"Out of memory\");\n /// };\n /// let afterSize = Region.size(region);\n /// assert afterSize - beforeSize == 10;\n /// }\n /// }\n /// ```\n public let grow : (region : Region, newPages : Nat64) -> (oldPages : Nat64) = Prim.regionGrow;\n\n /// Within `region`, load a `Nat8` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Nat8 = 123;\n /// Region.storeNat8(region, offset, value);\n /// assert Region.loadNat8(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let loadNat8 : (region : Region, offset : Nat64) -> Nat8 = Prim.regionLoadNat8;\n\n /// Within `region`, store a `Nat8` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Nat8 = 123;\n /// Region.storeNat8(region, offset, value);\n /// assert Region.loadNat8(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let storeNat8 : (region : Region, offset : Nat64, value : Nat8) -> () = Prim.regionStoreNat8;\n\n /// Within `region`, load a `Nat16` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Nat16 = 123;\n /// Region.storeNat16(region, offset, value);\n /// assert Region.loadNat16(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let loadNat16 : (region : Region, offset : Nat64) -> Nat16 = Prim.regionLoadNat16;\n\n /// Within `region`, store a `Nat16` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Nat16 = 123;\n /// Region.storeNat16(region, offset, value);\n /// assert Region.loadNat16(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let storeNat16 : (region : Region, offset : Nat64, value : Nat16) -> () = Prim.regionStoreNat16;\n\n /// Within `region`, load a `Nat32` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Nat32 = 123;\n /// Region.storeNat32(region, offset, value);\n /// assert Region.loadNat32(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let loadNat32 : (region : Region, offset : Nat64) -> Nat32 = Prim.regionLoadNat32;\n\n /// Within `region`, store a `Nat32` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Nat32 = 123;\n /// Region.storeNat32(region, offset, value);\n /// assert Region.loadNat32(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let storeNat32 : (region : Region, offset : Nat64, value : Nat32) -> () = Prim.regionStoreNat32;\n\n /// Within `region`, load a `Nat64` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Nat64 = 123;\n /// Region.storeNat64(region, offset, value);\n /// assert Region.loadNat64(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let loadNat64 : (region : Region, offset : Nat64) -> Nat64 = Prim.regionLoadNat64;\n\n /// Within `region`, store a `Nat64` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Nat64 = 123;\n /// Region.storeNat64(region, offset, value);\n /// assert Region.loadNat64(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let storeNat64 : (region : Region, offset : Nat64, value : Nat64) -> () = Prim.regionStoreNat64;\n\n /// Within `region`, load a `Int8` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Int8 = 123;\n /// Region.storeInt8(region, offset, value);\n /// assert Region.loadInt8(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let loadInt8 : (region : Region, offset : Nat64) -> Int8 = Prim.regionLoadInt8;\n\n /// Within `region`, store a `Int8` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Int8 = 123;\n /// Region.storeInt8(region, offset, value);\n /// assert Region.loadInt8(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let storeInt8 : (region : Region, offset : Nat64, value : Int8) -> () = Prim.regionStoreInt8;\n\n /// Within `region`, load a `Int16` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Int16 = 123;\n /// Region.storeInt16(region, offset, value);\n /// assert Region.loadInt16(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let loadInt16 : (region : Region, offset : Nat64) -> Int16 = Prim.regionLoadInt16;\n\n /// Within `region`, store a `Int16` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Int16 = 123;\n /// Region.storeInt16(region, offset, value);\n /// assert Region.loadInt16(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let storeInt16 : (region : Region, offset : Nat64, value : Int16) -> () = Prim.regionStoreInt16;\n\n /// Within `region`, load a `Int32` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Int32 = 123;\n /// Region.storeInt32(region, offset, value);\n /// assert Region.loadInt32(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let loadInt32 : (region : Region, offset : Nat64) -> Int32 = Prim.regionLoadInt32;\n\n /// Within `region`, store a `Int32` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Int32 = 123;\n /// Region.storeInt32(region, offset, value);\n /// assert Region.loadInt32(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let storeInt32 : (region : Region, offset : Nat64, value : Int32) -> () = Prim.regionStoreInt32;\n\n /// Within `region`, load a `Int64` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Int64 = 123;\n /// Region.storeInt64(region, offset, value);\n /// assert Region.loadInt64(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let loadInt64 : (region : Region, offset : Nat64) -> Int64 = Prim.regionLoadInt64;\n\n /// Within `region`, store a `Int64` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value : Int64 = 123;\n /// Region.storeInt64(region, offset, value);\n /// assert Region.loadInt64(region, offset) == 123;\n /// }\n /// }\n /// ```\n public let storeInt64 : (region : Region, offset : Nat64, value : Int64) -> () = Prim.regionStoreInt64;\n\n /// Within `region`, loads a `Float` value from the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value = 1.25;\n /// Region.storeFloat(region, offset, value);\n /// assert Region.loadFloat(region, offset) == 1.25;\n /// }\n /// }\n /// ```\n public let loadFloat : (region : Region, offset : Nat64) -> Float = Prim.regionLoadFloat;\n\n /// Within `region`, store float `value` at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value = 1.25;\n /// Region.storeFloat(region, offset, value);\n /// assert Region.loadFloat(region, offset) == 1.25;\n /// }\n /// }\n /// ```\n public let storeFloat : (region : Region, offset : Nat64, value : Float) -> () = Prim.regionStoreFloat;\n\n /// Within `region,` load `size` bytes starting from `offset` as a `Blob`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// import Blob \"mo:core/Blob\";\n ///\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// Region.storeBlob(region, offset, value);\n /// assert Blob.toArray(Region.loadBlob(region, offset, size)) == [1, 2, 3];\n /// }\n /// }\n /// ```\n public let loadBlob : (region : Region, offset : Nat64, size : Nat) -> Blob = Prim.regionLoadBlob;\n\n /// Within `region, write `blob.size()` bytes of `blob` beginning at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl include=import\n /// import Blob \"mo:core/Blob\";\n ///\n /// persistent actor {\n /// public func example() : async () {\n /// let region = Region.new();\n /// let offset : Nat64 = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// Region.storeBlob(region, offset, value);\n /// assert Blob.toArray(Region.loadBlob(region, offset, size)) == [1, 2, 3];\n /// }\n /// }\n /// ```\n public let storeBlob : (region : Region, offset : Nat64, value : Blob) -> () = Prim.regionStoreBlob;\n\n}\n"},"Int16.mo":{"content":"/// Utility functions on 16-bit signed integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Int16 \"mo:core/Int16\";\n/// ```\n\nimport Int \"Int\";\nimport Iter \"Iter\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// 16-bit signed integers.\n public type Int16 = Prim.Types.Int16;\n\n /// Minimum 16-bit integer value, `-2 ** 15`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.minValue == (-32_768 : Int16);\n /// ```\n public let minValue : Int16 = -32_768;\n\n /// Maximum 16-bit integer value, `+2 ** 15 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.maxValue == (+32_767 : Int16);\n /// ```\n public let maxValue : Int16 = 32_767;\n\n /// Converts a 16-bit signed integer to a signed integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.toInt(12_345) == (12_345 : Int);\n /// ```\n public let toInt : Int16 -> Int = Prim.int16ToInt;\n\n /// Converts a signed integer with infinite precision to a 16-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.fromInt(12_345) == (+12_345 : Int16);\n /// ```\n public let fromInt : Int -> Int16 = Prim.intToInt16;\n\n /// Converts a signed integer with infinite precision to a 16-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.fromIntWrap(-12_345) == (-12_345 : Int);\n /// ```\n public let fromIntWrap : Int -> Int16 = Prim.intToInt16Wrap;\n\n /// Converts a 8-bit signed integer to a 16-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.fromInt8(-123) == (-123 : Int16);\n /// ```\n public let fromInt8 : Int8 -> Int16 = Prim.int8ToInt16;\n\n /// Converts a 16-bit signed integer to a 8-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.toInt8(-123) == (-123 : Int8);\n /// ```\n public let toInt8 : Int16 -> Int8 = Prim.int16ToInt8;\n\n /// Converts a 32-bit signed integer to a 16-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.fromInt32(-12_345) == (-12_345 : Int16);\n /// ```\n public let fromInt32 : Int32 -> Int16 = Prim.int32ToInt16;\n\n /// Converts a 16-bit signed integer to a 32-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.toInt32(-12_345) == (-12_345 : Int32);\n /// ```\n public let toInt32 : Int16 -> Int32 = Prim.int16ToInt32;\n\n /// Converts an unsigned 16-bit integer to a signed 16-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.fromNat16(12_345) == (+12_345 : Int16);\n /// ```\n public let fromNat16 : Nat16 -> Int16 = Prim.nat16ToInt16;\n\n /// Converts a signed 16-bit integer to an unsigned 16-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.toNat16(-1) == (65_535 : Nat16); // underflow\n /// ```\n public let toNat16 : Int16 -> Nat16 = Prim.int16ToNat16;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.toText(-12345) == \"-12345\";\n /// ```\n public func toText(x : Int16) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Traps when `x == -2 ** 15` (the minimum `Int16` value).\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.abs(-12345) == +12_345;\n /// ```\n public func abs(x : Int16) : Int16 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.min(+2, -3) == -3;\n /// ```\n public func min(x : Int16, y : Int16) : Int16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.max(+2, -3) == +2;\n /// ```\n public func max(x : Int16, y : Int16) : Int16 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int16 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.equal(-1, -1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Int16 = -123;\n /// let b : Int16 = 123;\n /// assert not Int16.equal(a, b);\n /// ```\n public func equal(x : Int16, y : Int16) : Bool { x == y };\n\n /// Inequality function for Int16 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.notEqual(-1, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int16, y : Int16) : Bool { x != y };\n\n /// \"Less than\" function for Int16 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.less(-2, 1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int16, y : Int16) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int16 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.lessOrEqual(-2, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int16, y : Int16) : Bool { x <= y };\n\n /// \"Greater than\" function for Int16 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert not Int16.greater(-2, 1);\n /// ```\n public func greater(x : Int16, y : Int16) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int16 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.greaterOrEqual(-2, -2);\n /// ```\n public func greaterOrEqual(x : Int16, y : Int16) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int16`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.compare(-3, 2) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([1, -2, -3] : [Int16], Int16.compare) == [-3, -2, 1];\n /// ```\n public func compare(x : Int16, y : Int16) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n ///\n /// Traps on overflow, i.e. for `neg(-2 ** 15)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.neg(123) == -123;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int16) : Int16 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.add(100, 23) == +123;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int16, Int16>([1, -2, -3], 0, Int16.add) == -4;\n /// ```\n public func add(x : Int16, y : Int16) : Int16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.sub(123, 100) == +23;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int16, Int16>([1, -2, -3], 0, Int16.sub) == 4;\n /// ```\n public func sub(x : Int16, y : Int16) : Int16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.mul(12, 10) == +120;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int16, Int16>([1, -2, -3], 1, Int16.mul) == 6;\n /// ```\n public func mul(x : Int16, y : Int16) : Int16 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.div(123, 10) == +12;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int16, y : Int16) : Int16 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.rem(123, 10) == +3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int16, y : Int16) : Int16 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps on overflow/underflow and when `y < 0 or y >= 16`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.pow(2, 10) == +1_024;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int16, y : Int16) : Int16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitnot(-256 /* 0xff00 */) == +255 // 0xff;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Int16) : Int16 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitand(0x0fff, 0x00f0) == +240 // 0xf0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Int16, y : Int16) : Int16 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitor(0x0f0f, 0x00f0) == +4_095 // 0x0fff;\n /// ```\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Int16, y : Int16) : Int16 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitxor(0x0fff, 0x00f0) == +3_855 // 0x0f0f;\n /// ```\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Int16, y : Int16) : Int16 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n ///\n /// For `y >= 16`, the semantics is the same as for `bitshiftLeft(x, y % 16)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitshiftLeft(1, 8) == +256 // 0x100 equivalent to `2 ** 8`.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Int16, y : Int16) : Int16 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n ///\n /// For `y >= 16`, the semantics is the same as for `bitshiftRight(x, y % 16)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitshiftRight(1024, 8) == +4 // equivalent to `1024 / (2 ** 8)`;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Int16, y : Int16) : Int16 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 16`, the semantics is the same as for `bitrotLeft(x, y % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitrotLeft(0x2001, 4) == +18 // 0x12.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Int16, y : Int16) : Int16 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 16`, the semantics is the same as for `bitrotRight(x, y % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitrotRight(0x2010, 8) == +4_128 // 0x01020.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Int16, y : Int16) : Int16 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 16`, the semantics is the same as for `bittest(x, p % 16)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bittest(128, 7);\n /// ```\n public func bittest(x : Int16, p : Nat) : Bool {\n Prim.btstInt16(x, Prim.intToInt16(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 16`, the semantics is the same as for `bitset(x, p % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitset(0, 7) == +128;\n /// ```\n public func bitset(x : Int16, p : Nat) : Int16 {\n x | (1 << Prim.intToInt16(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitclear(-1, 7) == -129;\n /// ```\n public func bitclear(x : Int16, p : Nat) : Int16 {\n x & ^(1 << Prim.intToInt16(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitflip(255, 7) == +127;\n /// ```\n public func bitflip(x : Int16, p : Nat) : Int16 {\n x ^ (1 << Prim.intToInt16(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitcountNonZero(0xff) == +8;\n /// ```\n public let bitcountNonZero : (x : Int16) -> Int16 = Prim.popcntInt16;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitcountLeadingZero(0x80) == +8;\n /// ```\n public let bitcountLeadingZero : (x : Int16) -> Int16 = Prim.clzInt16;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.bitcountTrailingZero(0x0100) == +8;\n /// ```\n public let bitcountTrailingZero : (x : Int16) -> Int16 = Prim.ctzInt16;\n\n /// Returns the upper (i.e. most significant) and lower (least significant) byte of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.explode 0x77ee == (119, 238);\n /// ```\n public let explode : (x : Int16) -> (msb : Nat8, lsb : Nat8) = Prim.explodeInt16;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.addWrap(2 ** 14, 2 ** 14) == -32_768; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Int16, y : Int16) : Int16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.subWrap(-2 ** 15, 1) == +32_767; // underflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Int16, y : Int16) : Int16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int16.mulWrap(2 ** 8, 2 ** 8) == 0; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Int16, y : Int16) : Int16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n ///\n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 16`.\n ///\n /// Example:\n /// ```motoko include=import\n ///\n /// assert Int16.powWrap(2, 15) == -32_768; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Int16, y : Int16) : Int16 { x **% y };\n\n /// Returns an iterator over `Int16` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int16.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int16.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Int16, toExclusive : Int16) : Iter.Iter<Int16> {\n if (fromInclusive >= toExclusive) {\n Iter.empty()\n } else {\n object {\n var n = fromInclusive;\n public func next() : ?Int16 {\n if (n == toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over `Int16` values from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int16.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int16.rangeInclusive(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Int16, to : Int16) : Iter.Iter<Int16> {\n if (from > to) {\n Iter.empty()\n } else {\n object {\n var n = from;\n var done = false;\n public func next() : ?Int16 {\n if (done) {\n null\n } else {\n let result = n;\n if (n == to) {\n done := true\n } else {\n n += 1\n };\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over all Int16 values, from minValue to maxValue.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int16.allValues();\n /// assert iter.next() == ?-32_768;\n /// assert iter.next() == ?-32_767;\n /// assert iter.next() == ?-32_766;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Int16> {\n rangeInclusive(minValue, maxValue)\n };\n\n}\n"},"Int64.mo":{"content":"/// Utility functions on 64-bit signed integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Int64 \"mo:core/Int64\";\n/// ```\n\nimport Int \"Int\";\nimport Iter \"Iter\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// 64-bit signed integers.\n public type Int64 = Prim.Types.Int64;\n\n /// Minimum 64-bit integer value, `-2 ** 63`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.minValue == -9_223_372_036_854_775_808;\n /// ```\n public let minValue : Int64 = -9_223_372_036_854_775_808;\n\n /// Maximum 64-bit integer value, `+2 ** 63 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.maxValue == +9_223_372_036_854_775_807;\n /// ```\n public let maxValue : Int64 = 9_223_372_036_854_775_807;\n\n /// Converts a 64-bit signed integer to a signed integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.toInt(123_456) == (123_456 : Int);\n /// ```\n public let toInt : Int64 -> Int = Prim.int64ToInt;\n\n /// Converts a signed integer with infinite precision to a 64-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.fromInt(123_456) == (+123_456 : Int64);\n /// ```\n public let fromInt : Int -> Int64 = Prim.intToInt64;\n\n /// Converts a 32-bit signed integer to a 64-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.fromInt32(-123_456) == (-123_456 : Int64);\n /// ```\n public let fromInt32 : Int32 -> Int64 = Prim.int32ToInt64;\n\n /// Converts a 64-bit signed integer to a 32-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.toInt32(-123_456) == (-123_456 : Int32);\n /// ```\n public let toInt32 : Int64 -> Int32 = Prim.int64ToInt32;\n\n /// Converts a signed integer with infinite precision to a 64-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.fromIntWrap(-123_456) == (-123_456 : Int64);\n /// ```\n public let fromIntWrap : Int -> Int64 = Prim.intToInt64Wrap;\n\n /// Converts an unsigned 64-bit integer to a signed 64-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.fromNat64(123_456) == (+123_456 : Int64);\n /// ```\n public let fromNat64 : Nat64 -> Int64 = Prim.nat64ToInt64;\n\n /// Converts a signed 64-bit integer to an unsigned 64-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.toNat64(-1) == (18_446_744_073_709_551_615 : Nat64); // underflow\n /// ```\n public let toNat64 : Int64 -> Nat64 = Prim.int64ToNat64;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.toText(-123456) == \"-123456\";\n /// ```\n public func toText(x : Int64) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Traps when `x == -2 ** 63` (the minimum `Int64` value).\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.abs(-123456) == +123_456;\n /// ```\n public func abs(x : Int64) : Int64 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.min(+2, -3) == -3;\n /// ```\n public func min(x : Int64, y : Int64) : Int64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.max(+2, -3) == +2;\n /// ```\n public func max(x : Int64, y : Int64) : Int64 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int64 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.equal(-1, -1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let a : Int64 = -123;\n /// let b : Int64 = 123;\n /// assert not Int64.equal(a, b);\n /// ```\n public func equal(x : Int64, y : Int64) : Bool { x == y };\n\n /// Inequality function for Int64 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.notEqual(-1, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int64, y : Int64) : Bool { x != y };\n\n /// \"Less than\" function for Int64 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.less(-2, 1);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int64, y : Int64) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int64 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.lessOrEqual(-2, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int64, y : Int64) : Bool { x <= y };\n\n /// \"Greater than\" function for Int64 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.greater(-2, -3);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Int64, y : Int64) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int64 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.greaterOrEqual(-2, -2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Int64, y : Int64) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int64`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.compare(-3, 2) == #less;\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.sort([1, -2, -3] : [Int64], Int64.compare) == [-3, -2, 1];\n /// ```\n public func compare(x : Int64, y : Int64) : Order.Order {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n ///\n /// Traps on overflow, i.e. for `neg(-2 ** 63)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.neg(123) == -123;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int64) : Int64 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.add(1234, 123) == +1_357;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int64, Int64>([1, -2, -3], 0, Int64.add) == -4;\n /// ```\n public func add(x : Int64, y : Int64) : Int64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.sub(123, 100) == +23;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int64, Int64>([1, -2, -3], 0, Int64.sub) == 4;\n /// ```\n public func sub(x : Int64, y : Int64) : Int64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.mul(123, 10) == +1_230;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n /// assert Array.foldLeft<Int64, Int64>([1, -2, -3], 1, Int64.mul) == 6;\n /// ```\n public func mul(x : Int64, y : Int64) : Int64 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.div(123, 10) == +12;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int64, y : Int64) : Int64 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.rem(123, 10) == +3;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int64, y : Int64) : Int64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps on overflow/underflow and when `y < 0 or y >= 64`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.pow(2, 10) == +1_024;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int64, y : Int64) : Int64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitnot(-256 /* 0xffff_ffff_ffff_ff00 */) == +255 // 0xff;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Int64) : Int64 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitand(0xffff, 0x00f0) == +240 // 0xf0;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Int64, y : Int64) : Int64 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitor(0xffff, 0x00f0) == +65_535 // 0xffff;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Int64, y : Int64) : Int64 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitxor(0xffff, 0x00f0) == +65_295 // 0xff0f;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Int64, y : Int64) : Int64 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n ///\n /// For `y >= 64`, the semantics is the same as for `bitshiftLeft(x, y % 64)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitshiftLeft(1, 8) == +256 // 0x100 equivalent to `2 ** 8`.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Int64, y : Int64) : Int64 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n ///\n /// For `y >= 64`, the semantics is the same as for `bitshiftRight(x, y % 64)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitshiftRight(1024, 8) == +4 // equivalent to `1024 / (2 ** 8)`;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Int64, y : Int64) : Int64 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 64`, the semantics is the same as for `bitrotLeft(x, y % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n ///\n /// assert Int64.bitrotLeft(0x2000_0000_0000_0001, 4) == +18 // 0x12.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Int64, y : Int64) : Int64 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 64`, the semantics is the same as for `bitrotRight(x, y % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitrotRight(0x0002_0000_0000_0001, 48) == +65538 // 0x1_0002.;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Int64, y : Int64) : Int64 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 64`, the semantics is the same as for `bittest(x, p % 64)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bittest(128, 7);\n /// ```\n public func bittest(x : Int64, p : Nat) : Bool {\n Prim.btstInt64(x, Prim.intToInt64(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 64`, the semantics is the same as for `bitset(x, p % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitset(0, 7) == +128;\n /// ```\n public func bitset(x : Int64, p : Nat) : Int64 {\n x | (1 << Prim.intToInt64(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitclear(-1, 7) == -129;\n /// ```\n public func bitclear(x : Int64, p : Nat) : Int64 {\n x & ^(1 << Prim.intToInt64(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitflip(255, 7) == +127;\n /// ```\n public func bitflip(x : Int64, p : Nat) : Int64 {\n x ^ (1 << Prim.intToInt64(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitcountNonZero(0xffff) == +16;\n /// ```\n public let bitcountNonZero : (x : Int64) -> Int64 = Prim.popcntInt64;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitcountLeadingZero(0x8000_0000) == +32;\n /// ```\n public let bitcountLeadingZero : (x : Int64) -> Int64 = Prim.clzInt64;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.bitcountTrailingZero(0x0201_0000) == +16;\n /// ```\n public let bitcountTrailingZero : (x : Int64) -> Int64 = Prim.ctzInt64;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.explode 0x33772266aa885511 == (51, 119, 34, 102, 170, 136, 85, 17);\n /// ```\n public let explode : (x : Int64) -> (msb : Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeInt64;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.addWrap(2 ** 62, 2 ** 62) == -9_223_372_036_854_775_808; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Int64, y : Int64) : Int64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.subWrap(-2 ** 63, 1) == +9_223_372_036_854_775_807; // underflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Int64, y : Int64) : Int64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.mulWrap(2 ** 32, 2 ** 32) == 0; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Int64, y : Int64) : Int64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n ///\n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 64`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert Int64.powWrap(2, 63) == -9_223_372_036_854_775_808; // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Int64, y : Int64) : Int64 { x **% y };\n\n /// Returns an iterator over `Int64` values from the first to second argument with an exclusive upper bound.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int64.range(1, 4);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int64.range(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func range(fromInclusive : Int64, toExclusive : Int64) : Iter.Iter<Int64> {\n if (fromInclusive >= toExclusive) {\n Iter.empty()\n } else {\n object {\n var n = fromInclusive;\n public func next() : ?Int64 {\n if (n == toExclusive) {\n null\n } else {\n let result = n;\n n += 1;\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over `Int64` values from the first to second argument, inclusive.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int64.rangeInclusive(1, 3);\n /// assert iter.next() == ?1;\n /// assert iter.next() == ?2;\n /// assert iter.next() == ?3;\n /// assert iter.next() == null;\n /// ```\n ///\n /// If the first argument is greater than the second argument, the function returns an empty iterator.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int64.rangeInclusive(4, 1);\n /// assert iter.next() == null; // empty iterator\n /// ```\n public func rangeInclusive(from : Int64, to : Int64) : Iter.Iter<Int64> {\n if (from > to) {\n Iter.empty()\n } else {\n object {\n var n = from;\n var done = false;\n public func next() : ?Int64 {\n if (done) {\n null\n } else {\n let result = n;\n if (n == to) {\n done := true\n } else {\n n += 1\n };\n ?result\n }\n }\n }\n }\n };\n\n /// Returns an iterator over all Int64 values, from minValue to maxValue.\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let iter = Int64.allValues();\n /// assert iter.next() == ?-9_223_372_036_854_775_808;\n /// assert iter.next() == ?-9_223_372_036_854_775_807;\n /// assert iter.next() == ?-9_223_372_036_854_775_806;\n /// // ...\n /// ```\n public func allValues() : Iter.Iter<Int64> {\n rangeInclusive(minValue, maxValue)\n };\n\n}\n"},"Text.mo":{"content":"/// Utility functions for `Text` values.\n///\n/// A `Text` value represents human-readable text as a sequence of characters of type `Char`.\n///\n/// ```motoko\n/// let text = \"Hello!\";\n/// let size = text.size();\n/// assert size == 6;\n/// let iter = text.chars();\n/// assert iter.next() == ?'H';\n/// assert iter.next() == ?'e';\n/// assert iter.next() == ?'l';\n/// assert iter.next() == ?'l';\n/// assert iter.next() == ?'o';\n/// assert iter.next() == ?'!';\n/// assert iter.next() == null;\n/// let concat = text # \" 👋\";\n/// assert concat == \"Hello! 👋\";\n/// ```\n///\n/// The `\"mo:core/Text\"` module defines additional operations on `Text` values.\n///\n/// Import the module from the core library:\n///\n/// ```motoko name=import\n/// import Text \"mo:core/Text\";\n/// ```\n///\n/// Note: `Text` values are represented as ropes of UTF-8 character sequences with O(1) concatenation.\n///\n\nimport Char \"Char\";\nimport Iter \"Iter\";\nimport Stack \"Stack\";\nimport Types \"Types\";\nimport Prim \"mo:⛔\";\nimport Order \"Order\";\n\nmodule {\n\n /// The type corresponding to primitive `Text` values.\n ///\n /// ```motoko\n /// let hello = \"Hello!\";\n /// let emoji = \"👋\";\n /// let concat = hello # \" \" # emoji;\n /// assert concat == \"Hello! 👋\";\n /// ```\n public type Text = Prim.Types.Text;\n\n /// Converts the given `Char` to a `Text` value.\n ///\n /// ```motoko include=import\n /// let text = Text.fromChar('A');\n /// assert text == \"A\";\n /// ```\n public let fromChar : (c : Char) -> Text = Prim.charToText;\n\n /// Converts the given `[Char]` to a `Text` value.\n ///\n /// ```motoko include=import\n /// let text = Text.fromArray(['A', 'v', 'o', 'c', 'a', 'd', 'o']);\n /// assert text == \"Avocado\";\n /// ```\n ///\n /// Runtime: O(a.size())\n /// Space: O(a.size())\n public func fromArray(a : [Char]) : Text = fromIter(a.vals());\n\n /// Converts the given `[var Char]` to a `Text` value.\n ///\n /// ```motoko include=import\n /// let text = Text.fromVarArray([var 'E', 'g', 'g', 'p', 'l', 'a', 'n', 't']);\n /// assert text == \"Eggplant\";\n /// ```\n ///\n /// Runtime: O(a.size())\n /// Space: O(a.size())\n public func fromVarArray(a : [var Char]) : Text = fromIter(a.vals());\n\n /// Iterates over each `Char` value in the given `Text`.\n ///\n /// Equivalent to calling the `t.chars()` method where `t` is a `Text` value.\n ///\n /// ```motoko include=import\n /// let chars = Text.toIter(\"abc\");\n /// assert chars.next() == ?'a';\n /// assert chars.next() == ?'b';\n /// assert chars.next() == ?'c';\n /// assert chars.next() == null;\n /// ```\n public func toIter(t : Text) : Iter.Iter<Char> = t.chars();\n\n /// Creates a new `Array` containing characters of the given `Text`.\n ///\n /// Equivalent to `Iter.toArray(t.chars())`.\n ///\n /// ```motoko include=import\n /// assert Text.toArray(\"Café\") == ['C', 'a', 'f', 'é'];\n /// ```\n ///\n /// Runtime: O(t.size())\n /// Space: O(t.size())\n public func toArray(t : Text) : [Char] {\n let cs = t.chars();\n // We rely on Array_tabulate's implementation details: it fills\n // the array from left to right sequentially.\n Prim.Array_tabulate<Char>(\n t.size(),\n func _ {\n switch (cs.next()) {\n case (?c) { c };\n case null { Prim.trap(\"Text.toArray()\") }\n }\n }\n )\n };\n\n /// Creates a new mutable `Array` containing characters of the given `Text`.\n ///\n /// Equivalent to `Iter.toArrayMut(t.chars())`.\n ///\n /// ```motoko include=import\n /// import VarArray \"mo:core/VarArray\";\n /// import Char \"mo:core/Char\";\n ///\n /// assert VarArray.equal(Text.toVarArray(\"Café\"), [var 'C', 'a', 'f', 'é'], Char.equal);\n /// ```\n ///\n /// Runtime: O(t.size())\n /// Space: O(t.size())\n public func toVarArray(t : Text) : [var Char] {\n let n = t.size();\n if (n == 0) {\n return [var]\n };\n let array = Prim.Array_init<Char>(n, ' ');\n var i = 0;\n for (c in t.chars()) {\n array[i] := c;\n i += 1\n };\n array\n };\n\n /// Creates a `Text` value from a `Char` iterator.\n ///\n /// ```motoko include=import\n /// let text = Text.fromIter(['a', 'b', 'c'].values());\n /// assert text == \"abc\";\n /// ```\n public func fromIter(cs : Iter.Iter<Char>) : Text {\n var r = \"\";\n for (c in cs) {\n r #= Prim.charToText(c)\n };\n return r\n };\n\n /// Returns whether the given `Text` is empty (has a size of zero).\n ///\n /// ```motoko include=import\n /// let text1 = \"\";\n /// let text2 = \"example\";\n /// assert Text.isEmpty(text1);\n /// assert not Text.isEmpty(text2);\n /// ```\n public func isEmpty(t : Text) : Bool = t == \"\";\n\n /// Returns the number of characters in the given `Text`.\n ///\n /// Equivalent to calling `t.size()` where `t` is a `Text` value.\n ///\n /// ```motoko include=import\n /// let size = Text.size(\"abc\");\n /// assert size == 3;\n /// ```\n public func size(t : Text) : Nat = t.size();\n\n /// Returns `t1 # t2`, where `#` is the `Text` concatenation operator.\n ///\n /// ```motoko include=import\n /// let a = \"Hello\";\n /// let b = \"There\";\n /// let together = a # b;\n /// assert together == \"HelloThere\";\n /// let withSpace = a # \" \" # b;\n /// assert withSpace == \"Hello There\";\n /// let togetherAgain = Text.concat(a, b);\n /// assert togetherAgain == \"HelloThere\";\n /// ```\n public func concat(t1 : Text, t2 : Text) : Text = t1 # t2;\n\n /// Returns a new `Text` with the characters of the input `Text` in reverse order.\n ///\n /// ```motoko include=import\n /// let text = Text.reverse(\"Hello\");\n /// assert text == \"olleH\";\n /// ```\n ///\n /// Runtime: O(t.size())\n /// Space: O(t.size())\n public func reverse(t : Text) : Text {\n fromIter(Iter.reverse(t.chars()))\n };\n\n /// Returns true if two text values are equal.\n ///\n /// ```motoko\n /// import Text \"mo:core/Text\";\n ///\n /// assert Text.equal(\"hello\", \"hello\");\n /// assert not Text.equal(\"hello\", \"world\");\n /// ```\n public func equal(t1 : Text, t2 : Text) : Bool { t1 == t2 };\n\n /// Returns true if two text values are not equal.\n ///\n /// ```motoko\n /// import Text \"mo:core/Text\";\n ///\n /// assert Text.notEqual(\"hello\", \"world\");\n /// assert not Text.notEqual(\"hello\", \"hello\");\n /// ```\n public func notEqual(t1 : Text, t2 : Text) : Bool { t1 != t2 };\n\n /// Returns true if the first text value is lexicographically less than the second.\n ///\n /// ```motoko\n /// import Text \"mo:core/Text\";\n ///\n /// assert Text.less(\"apple\", \"banana\");\n /// assert not Text.less(\"banana\", \"apple\");\n /// ```\n public func less(t1 : Text, t2 : Text) : Bool { t1 < t2 };\n\n /// Returns true if the first text value is lexicographically less than or equal to the second.\n ///\n /// ```motoko\n /// import Text \"mo:core/Text\";\n ///\n /// assert Text.lessOrEqual(\"apple\", \"banana\");\n /// assert Text.lessOrEqual(\"apple\", \"apple\");\n /// assert not Text.lessOrEqual(\"banana\", \"apple\");\n /// ```\n public func lessOrEqual(t1 : Text, t2 : Text) : Bool { t1 <= t2 };\n\n /// Returns true if the first text value is lexicographically greater than the second.\n ///\n /// ```motoko\n /// import Text \"mo:core/Text\";\n ///\n /// assert Text.greater(\"banana\", \"apple\");\n /// assert not Text.greater(\"apple\", \"banana\");\n /// ```\n public func greater(t1 : Text, t2 : Text) : Bool { t1 > t2 };\n\n /// Returns true if the first text value is lexicographically greater than or equal to the second.\n ///\n /// ```motoko\n /// import Text \"mo:core/Text\";\n ///\n /// assert Text.greaterOrEqual(\"banana\", \"apple\");\n /// assert Text.greaterOrEqual(\"apple\", \"apple\");\n /// assert not Text.greaterOrEqual(\"apple\", \"banana\");\n /// ```\n public func greaterOrEqual(t1 : Text, t2 : Text) : Bool { t1 >= t2 };\n\n /// Compares `t1` and `t2` lexicographically.\n ///\n /// ```motoko include=import\n /// assert Text.compare(\"abc\", \"abc\") == #equal;\n /// assert Text.compare(\"abc\", \"def\") == #less;\n /// assert Text.compare(\"abc\", \"ABC\") == #greater;\n /// ```\n public func compare(t1 : Text, t2 : Text) : Order.Order {\n let c = Prim.textCompare(t1, t2);\n if (c < 0) #less else if (c == 0) #equal else #greater\n };\n\n private func extract(t : Text, i : Nat, j : Nat) : Text {\n let size = t.size();\n if (i == 0 and j == size) return t;\n assert (j <= size);\n let cs = t.chars();\n var r = \"\";\n var n = i;\n while (n > 0) {\n ignore cs.next();\n n -= 1\n };\n n := j;\n while (n > 0) {\n switch (cs.next()) {\n case null { assert false };\n case (?c) { r #= Prim.charToText(c) }\n };\n n -= 1\n };\n return r\n };\n\n /// Join an iterator of `Text` values with a given delimiter.\n ///\n /// ```motoko include=import\n /// let joined = Text.join(\", \", [\"a\", \"b\", \"c\"].values());\n /// assert joined == \"a, b, c\";\n /// ```\n public func join(sep : Text, ts : Iter.Iter<Text>) : Text {\n var r = \"\";\n if (sep.size() == 0) {\n for (t in ts) {\n r #= t\n };\n return r\n };\n let next = ts.next;\n switch (next()) {\n case null { return r };\n case (?t) {\n r #= t\n }\n };\n loop {\n switch (next()) {\n case null { return r };\n case (?t) {\n r #= sep;\n r #= t\n }\n }\n }\n };\n\n /// Applies a function to each character in a `Text` value, returning the concatenated `Char` results.\n ///\n /// ```motoko include=import\n /// // Replace all occurrences of '?' with '!'\n /// let result = Text.map(\"Motoko?\", func(c) {\n /// if (c == '?') '!'\n /// else c\n /// });\n /// assert result == \"Motoko!\";\n /// ```\n public func map(t : Text, f : Char -> Char) : Text {\n var r = \"\";\n for (c in t.chars()) {\n r #= Prim.charToText(f(c))\n };\n return r\n };\n\n /// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate text values.\n ///\n /// ```motoko include=import\n /// // Replace all occurrences of '?' with \"!!\"\n /// let result = Text.flatMap(\"Motoko?\", func(c) {\n /// if (c == '?') \"!!\"\n /// else Text.fromChar(c)\n /// });\n /// assert result == \"Motoko!!\";\n /// ```\n public func flatMap(t : Text, f : Char -> Text) : Text {\n var r = \"\";\n for (c in t.chars()) {\n r #= f(c)\n };\n return r\n };\n\n /// A pattern `p` describes a sequence of characters. A pattern has one of the following forms:\n ///\n /// * `#char c` matches the single character sequence, `c`.\n /// * `#text t` matches multi-character text sequence `t`.\n /// * `#predicate p` matches any single character sequence `c` satisfying predicate `p(c)`.\n ///\n /// A _match_ for `p` is any sequence of characters matching the pattern `p`.\n ///\n /// ```motoko include=import\n /// let charPattern = #char 'A';\n /// let textPattern = #text \"phrase\";\n /// let predicatePattern : Text.Pattern = #predicate (func(c) { c == 'A' or c == 'B' });\n /// assert Text.contains(\"A\", predicatePattern);\n /// assert Text.contains(\"B\", predicatePattern);\n /// ```\n public type Pattern = Types.Pattern;\n\n private func take(n : Nat, cs : Iter.Iter<Char>) : Iter.Iter<Char> {\n var i = n;\n object {\n public func next() : ?Char {\n if (i == 0) return null;\n i -= 1;\n return cs.next()\n }\n }\n };\n\n private func empty() : Iter.Iter<Char> {\n object {\n public func next() : ?Char = null\n }\n };\n\n private type Match = {\n /// #success on complete match\n #success;\n /// #fail(cs,c) on partial match of cs, but failing match on c\n #fail : (cs : Iter.Iter<Char>, c : Char);\n /// #empty(cs) on partial match of cs and empty stream\n #empty : (cs : Iter.Iter<Char>)\n };\n\n private func sizeOfPattern(pat : Pattern) : Nat {\n switch pat {\n case (#text(t)) { t.size() };\n case (#predicate(_) or #char(_)) { 1 }\n }\n };\n\n private func matchOfPattern(pat : Pattern) : (cs : Iter.Iter<Char>) -> Match {\n switch pat {\n case (#char(p)) {\n func(cs : Iter.Iter<Char>) : Match {\n switch (cs.next()) {\n case (?c) {\n if (p == c) {\n #success\n } else {\n #fail(empty(), c)\n }\n };\n case null { #empty(empty()) }\n }\n }\n };\n case (#predicate(p)) {\n func(cs : Iter.Iter<Char>) : Match {\n switch (cs.next()) {\n case (?c) {\n if (p(c)) {\n #success\n } else {\n #fail(empty(), c)\n }\n };\n case null { #empty(empty()) }\n }\n }\n };\n case (#text(p)) {\n func(cs : Iter.Iter<Char>) : Match {\n var i = 0;\n let ds = p.chars();\n loop {\n switch (ds.next()) {\n case (?d) {\n switch (cs.next()) {\n case (?c) {\n if (c != d) {\n return #fail(take(i, p.chars()), c)\n };\n i += 1\n };\n case null {\n return #empty(take(i, p.chars()))\n }\n }\n };\n case null { return #success }\n }\n }\n }\n }\n }\n };\n\n private class CharBuffer(cs : Iter.Iter<Char>) : Iter.Iter<Char> = {\n\n var stack : Stack.Stack<(Iter.Iter<Char>, Char)> = Stack.empty();\n\n public func pushBack(cs0 : Iter.Iter<Char>, c : Char) {\n Stack.push(stack, (cs0, c))\n };\n\n public func next() : ?Char {\n switch (Stack.peek(stack)) {\n case (?(buff, c)) {\n switch (buff.next()) {\n case null {\n ignore Stack.pop(stack);\n return ?c\n };\n case oc {\n return oc\n }\n }\n };\n case null {\n return cs.next()\n }\n }\n }\n };\n\n /// Splits the input `Text` with the specified `Pattern`.\n ///\n /// Two fields are separated by exactly one match.\n ///\n /// ```motoko include=import\n /// let words = Text.split(\"This is a sentence.\", #char ' ');\n /// assert Text.join(\"|\", words) == \"This|is|a|sentence.\";\n /// ```\n public func split(t : Text, p : Pattern) : Iter.Iter<Text> {\n let match = matchOfPattern(p);\n let cs = CharBuffer(t.chars());\n var state = 0;\n var field = \"\";\n object {\n public func next() : ?Text {\n switch state {\n case (0 or 1) {\n loop {\n switch (match(cs)) {\n case (#success) {\n let r = field;\n field := \"\";\n state := 1;\n return ?r\n };\n case (#empty(cs1)) {\n for (c in cs1) {\n field #= fromChar(c)\n };\n let r = if (state == 0 and field == \"\") {\n null\n } else {\n ?field\n };\n state := 2;\n return r\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c);\n switch (cs.next()) {\n case (?ci) {\n field #= fromChar(ci)\n };\n case null {\n let r = if (state == 0 and field == \"\") {\n null\n } else {\n ?field\n };\n state := 2;\n return r\n }\n }\n }\n }\n }\n };\n case _ { return null }\n }\n }\n }\n };\n\n /// Returns a sequence of tokens from the input `Text` delimited by the specified `Pattern`, derived from start to end.\n /// A \"token\" is a non-empty maximal subsequence of `t` not containing a match for pattern `p`.\n /// Two tokens may be separated by one or more matches of `p`.\n ///\n /// ```motoko include=import\n /// let tokens = Text.tokens(\"this needs\\n an example\", #predicate (func(c) { c == ' ' or c == '\\n' }));\n /// assert Text.join(\"|\", tokens) == \"this|needs|an|example\";\n /// ```\n public func tokens(t : Text, p : Pattern) : Iter.Iter<Text> {\n let fs = split(t, p);\n object {\n public func next() : ?Text {\n switch (fs.next()) {\n case (?\"\") { next() };\n case ot { ot }\n }\n }\n }\n };\n\n /// Returns `true` if the input `Text` contains a match for the specified `Pattern`.\n ///\n /// ```motoko include=import\n /// assert Text.contains(\"Motoko\", #text \"oto\");\n /// assert not Text.contains(\"Motoko\", #text \"xyz\");\n /// ```\n public func contains(t : Text, p : Pattern) : Bool {\n let match = matchOfPattern(p);\n let cs = CharBuffer(t.chars());\n loop {\n switch (match(cs)) {\n case (#success) {\n return true\n };\n case (#empty(_cs1)) {\n return false\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c);\n switch (cs.next()) {\n case null {\n return false\n };\n case _ {}; // continue\n }\n }\n }\n }\n };\n\n /// Returns `true` if the input `Text` starts with a prefix matching the specified `Pattern`.\n ///\n /// ```motoko include=import\n /// assert Text.startsWith(\"Motoko\", #text \"Mo\");\n /// ```\n public func startsWith(t : Text, p : Pattern) : Bool {\n var cs = t.chars();\n let match = matchOfPattern(p);\n switch (match(cs)) {\n case (#success) { true };\n case _ { false }\n }\n };\n\n /// Returns `true` if the input `Text` ends with a suffix matching the specified `Pattern`.\n ///\n /// ```motoko include=import\n /// assert Text.endsWith(\"Motoko\", #char 'o');\n /// ```\n public func endsWith(t : Text, p : Pattern) : Bool {\n let s2 = sizeOfPattern(p);\n if (s2 == 0) return true;\n let s1 = t.size();\n if (s2 > s1) return false;\n let match = matchOfPattern(p);\n var cs1 = t.chars();\n var diff : Nat = s1 - s2;\n while (diff > 0) {\n ignore cs1.next();\n diff -= 1\n };\n switch (match(cs1)) {\n case (#success) { true };\n case _ { false }\n }\n };\n\n /// Returns the input text `t` with all matches of pattern `p` replaced by text `r`.\n ///\n /// ```motoko include=import\n /// let result = Text.replace(\"abcabc\", #char 'a', \"A\");\n /// assert result == \"AbcAbc\";\n /// ```\n public func replace(t : Text, p : Pattern, r : Text) : Text {\n let match = matchOfPattern(p);\n let size = sizeOfPattern(p);\n let cs = CharBuffer(t.chars());\n var res = \"\";\n label l loop {\n switch (match(cs)) {\n case (#success) {\n res #= r;\n if (size > 0) {\n continue l\n }\n };\n case (#empty(cs1)) {\n for (c1 in cs1) {\n res #= fromChar(c1)\n };\n break l\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c)\n }\n };\n switch (cs.next()) {\n case null {\n break l\n };\n case (?c1) {\n res #= fromChar(c1)\n }; // continue\n }\n };\n return res\n };\n\n /// Strips one occurrence of the given `Pattern` from the beginning of the input `Text`.\n /// If you want to remove multiple instances of the pattern, use `Text.trimStart()` instead.\n ///\n /// ```motoko include=import\n /// // Try to strip a nonexistent character\n /// let none = Text.stripStart(\"abc\", #char '-');\n /// assert none == null;\n /// // Strip just one '-'\n /// let one = Text.stripStart(\"--abc\", #char '-');\n /// assert one == ?\"-abc\";\n /// ```\n public func stripStart(t : Text, p : Pattern) : ?Text {\n let s = sizeOfPattern(p);\n if (s == 0) return ?t;\n var cs = t.chars();\n let match = matchOfPattern(p);\n switch (match(cs)) {\n case (#success) return ?fromIter(cs);\n case _ return null\n }\n };\n\n /// Strips one occurrence of the given `Pattern` from the end of the input `Text`.\n /// If you want to remove multiple instances of the pattern, use `Text.trimEnd()` instead.\n ///\n /// ```motoko include=import\n /// // Try to strip a nonexistent character\n /// let none = Text.stripEnd(\"xyz\", #char '-');\n /// assert none == null;\n /// // Strip just one '-'\n /// let one = Text.stripEnd(\"xyz--\", #char '-');\n /// assert one == ?\"xyz-\";\n /// ```\n public func stripEnd(t : Text, p : Pattern) : ?Text {\n let s2 = sizeOfPattern(p);\n if (s2 == 0) return ?t;\n let s1 = t.size();\n if (s2 > s1) return null;\n let match = matchOfPattern(p);\n var cs1 = t.chars();\n var diff : Nat = s1 - s2;\n while (diff > 0) {\n ignore cs1.next();\n diff -= 1\n };\n switch (match(cs1)) {\n case (#success) return ?extract(t, 0, s1 - s2);\n case _ return null\n }\n };\n\n /// Trims the given `Pattern` from the start of the input `Text`.\n /// If you only want to remove a single instance of the pattern, use `Text.stripStart()` instead.\n ///\n /// ```motoko include=import\n /// let trimmed = Text.trimStart(\"---abc\", #char '-');\n /// assert trimmed == \"abc\";\n /// ```\n public func trimStart(t : Text, p : Pattern) : Text {\n let cs = t.chars();\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n var matchSize = 0;\n let match = matchOfPattern(p);\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size\n }; // continue\n case (#empty(cs1)) {\n return if (matchSize == 0) {\n t\n } else {\n fromIter(cs1)\n }\n };\n case (#fail(cs1, c)) {\n return if (matchSize == 0) {\n t\n } else {\n fromIter(cs1) # fromChar(c) # fromIter(cs)\n }\n }\n }\n }\n };\n\n /// Trims the given `Pattern` from the end of the input `Text`.\n /// If you only want to remove a single instance of the pattern, use `Text.stripEnd()` instead.\n ///\n /// ```motoko include=import\n /// let trimmed = Text.trimEnd(\"xyz---\", #char '-');\n /// assert trimmed == \"xyz\";\n /// ```\n public func trimEnd(t : Text, p : Pattern) : Text {\n let cs = CharBuffer(t.chars());\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n let match = matchOfPattern(p);\n var matchSize = 0;\n label l loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size\n }; // continue\n case (#empty(cs1)) {\n switch (cs1.next()) {\n case null break l;\n case (?_) return t\n }\n };\n case (#fail(cs1, c)) {\n matchSize := 0;\n cs.pushBack(cs1, c);\n ignore cs.next()\n }\n }\n };\n extract(t, 0, t.size() - matchSize)\n };\n\n /// Trims the given `Pattern` from both the start and end of the input `Text`.\n ///\n /// ```motoko include=import\n /// let trimmed = Text.trim(\"---abcxyz---\", #char '-');\n /// assert trimmed == \"abcxyz\";\n /// ```\n public func trim(t : Text, p : Pattern) : Text {\n let cs = t.chars();\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n var matchSize = 0;\n let match = matchOfPattern(p);\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size\n }; // continue\n case (#empty(cs1)) {\n return if (matchSize == 0) { t } else { fromIter(cs1) }\n };\n case (#fail(cs1, c)) {\n let start = matchSize;\n let cs2 = CharBuffer(cs);\n cs2.pushBack(cs1, c);\n ignore cs2.next();\n matchSize := 0;\n label l loop {\n switch (match(cs2)) {\n case (#success) {\n matchSize += size\n }; // continue\n case (#empty(_cs3)) {\n switch (cs1.next()) {\n case null break l;\n case (?_) return t\n }\n };\n case (#fail(cs3, c1)) {\n matchSize := 0;\n cs2.pushBack(cs3, c1);\n ignore cs2.next()\n }\n }\n };\n return extract(t, start, t.size() - matchSize - start)\n }\n }\n }\n };\n\n /// Compares `t1` and `t2` using the provided character-wise comparison function.\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n ///\n /// assert Text.compareWith(\"abc\", \"ABC\", func(c1, c2) { Char.compare(c1, c2) }) == #greater;\n /// ```\n public func compareWith(\n t1 : Text,\n t2 : Text,\n cmp : (Char, Char) -> Order.Order\n ) : Order.Order {\n let cs1 = t1.chars();\n let cs2 = t2.chars();\n loop {\n switch (cs1.next(), cs2.next()) {\n case (null, null) { return #equal };\n case (null, ?_) { return #less };\n case (?_, null) { return #greater };\n case (?c1, ?c2) {\n switch (cmp(c1, c2)) {\n case (#equal) {}; // continue\n case other { return other }\n }\n }\n }\n }\n };\n\n /// Returns a UTF-8 encoded `Blob` from the given `Text`.\n ///\n /// ```motoko include=import\n /// let blob = Text.encodeUtf8(\"Hello\");\n /// assert blob == \"\\48\\65\\6C\\6C\\6F\";\n /// ```\n public let encodeUtf8 : Text -> Blob = Prim.encodeUtf8;\n\n /// Tries to decode the given `Blob` as UTF-8.\n /// Returns `null` if the blob is not valid UTF-8.\n ///\n /// ```motoko include=import\n /// let text = Text.decodeUtf8(\"\\48\\65\\6C\\6C\\6F\");\n /// assert text == ?\"Hello\";\n /// ```\n public let decodeUtf8 : Blob -> ?Text = Prim.decodeUtf8;\n\n /// Returns the text argument in lowercase.\n /// WARNING: Unicode compliant only when compiled, not interpreted.\n ///\n /// ```motoko include=import\n /// let text = Text.toLower(\"Good Day\");\n /// assert text == \"good day\";\n /// ```\n public let toLower : Text -> Text = Prim.textLowercase;\n\n /// Returns the text argument in uppercase. Unicode compliant.\n /// WARNING: Unicode compliant only when compiled, not interpreted.\n ///\n /// ```motoko include=import\n /// let text = Text.toUpper(\"Good Day\");\n /// assert text == \"GOOD DAY\";\n /// ```\n public let toUpper : Text -> Text = Prim.textUppercase;\n\n /// Returns the given text value unchanged.\n /// This function is provided for consistency with other modules.\n ///\n /// ```motoko include=import\n /// assert Text.toText(\"Hello\") == \"Hello\";\n /// ```\n public func toText(t : Text) : Text = t\n}\n"},"pure/Queue.mo":{"content":"/// Double-ended queue of a generic element type `T`.\n///\n/// The interface is purely functional, not imperative, and queues are immutable values.\n/// In particular, Queue operations such as push and pop do not update their input queue but, instead, return the\n/// value of the modified Queue, alongside any other data.\n/// The input queue is left unchanged.\n///\n/// Examples of use-cases:\n/// Queue (FIFO) by using `pushBack()` and `popFront()`.\n/// Stack (LIFO) by using `pushFront()` and `popFront()`.\n///\n/// A Queue is internally implemented as two lists, a head access list and a (reversed) tail access list,\n/// that are dynamically size-balanced by splitting.\n///\n/// Construction: Create a new queue with the `empty<T>()` function.\n///\n/// Note on the costs of push and pop functions:\n/// * Runtime: `O(1)` amortized costs, `O(size)` worst case cost per single call.\n/// * Space: `O(1)` amortized costs, `O(size)` worst case cost per single call.\n///\n/// `n` denotes the number of elements stored in the queue.\n///\n/// Note that some operations that traverse the elements of the queue (e.g. `forEach`, `values`) preserve the order of the elements,\n/// whereas others (e.g. `map`, `contains`) do NOT guarantee that the elements are visited in any order.\n/// The order is undefined to avoid allocations, making these operations more efficient.\n///\n/// ```motoko name=import\n/// import Queue \"mo:core/pure/Queue\";\n/// ```\n\nimport Iter \"../Iter\";\nimport List \"List\";\nimport Order \"../Order\";\nimport Types \"../Types\";\nimport Array \"../Array\";\nimport Prim \"mo:⛔\";\n\nmodule {\n type List<T> = Types.Pure.List<T>;\n\n /// Double-ended queue data type.\n public type Queue<T> = Types.Pure.Queue<T>;\n\n /// Create a new empty queue.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.empty<Nat>();\n /// assert Queue.isEmpty(queue);\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func empty<T>() : Queue<T> = (null, 0, null);\n\n /// Determine whether a queue is empty.\n /// Returns true if `queue` is empty, otherwise `false`.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.empty<Nat>();\n /// assert Queue.isEmpty(queue);\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func isEmpty<T>(queue : Queue<T>) : Bool = queue.1 == 0;\n\n /// Create a new queue comprising a single element.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.singleton(25);\n /// assert Queue.size(queue) == 1;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func singleton<T>(item : T) : Queue<T> = (null, 1, ?(item, null));\n\n /// Determine the number of elements contained in a queue.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.singleton(42);\n /// assert Queue.size(queue) == 1;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)` in Release profile (compiled with `--release` flag), `O(size)` otherwise.\n ///\n /// Space: `O(1)`.\n public func size<T>(queue : Queue<T>) : Nat {\n debug assert queue.1 == List.size(queue.0) + List.size(queue.2);\n queue.1\n };\n\n /// Check if a queue contains a specific element.\n /// Returns true if the queue contains an element equal to `item` according to the `equal` function.\n ///\n /// Note: The order in which elements are visited is undefined, for performance reasons.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter([1, 2, 3].values());\n /// assert Queue.contains(queue, Nat.equal, 2);\n /// assert not Queue.contains(queue, Nat.equal, 4);\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n public func contains<T>(queue : Queue<T>, equal : (T, T) -> Bool, item : T) : Bool = List.contains(queue.0, equal, item) or List.contains(queue.2, equal, item);\n\n /// Inspect the optional element on the front end of a queue.\n /// Returns `null` if `queue` is empty. Otherwise, the front element of `queue`.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.pushFront(Queue.pushFront(Queue.empty(), 2), 1);\n /// assert Queue.peekFront(queue) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func peekFront<T>(queue : Queue<T>) : ?T = switch queue {\n case ((?(x, _), _, _) or (_, _, ?(x, null))) ?x;\n case _ { debug assert List.isEmpty(queue.2); null }\n };\n\n /// Inspect the optional element on the back end of a queue.\n /// Returns `null` if `queue` is empty. Otherwise, the back element of `queue`.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.pushBack(Queue.pushBack(Queue.empty(), 1), 2);\n /// assert Queue.peekBack(queue) == ?2;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func peekBack<T>(queue : Queue<T>) : ?T = switch queue {\n case ((_, _, ?(x, _)) or (?(x, null), _, _)) ?x;\n case _ { debug assert List.isEmpty(queue.0); null }\n };\n\n // helper to rebalance the queue after getting lopsided\n func check<T>(q : Queue<T>) : Queue<T> {\n switch q {\n case (null, n, r) {\n let (a, b) = List.split(r, n / 2);\n (List.reverse b, n, a)\n };\n case (f, n, null) {\n let (a, b) = List.split(f, n / 2);\n (a, n, List.reverse b)\n };\n case q q\n }\n };\n\n /// Insert a new element on the front end of a queue.\n /// Returns the new queue with `element` in the front followed by the elements of `queue`.\n ///\n /// This may involve dynamic rebalancing of the two, internally used lists.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.pushFront(Queue.pushFront(Queue.empty(), 2), 1);\n /// assert Queue.peekFront(queue) == ?1;\n /// assert Queue.peekBack(queue) == ?2;\n /// assert Queue.size(queue) == 2;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)` worst-case, amortized to `O(1)`.\n ///\n /// Space: `O(size)` worst-case, amortized to `O(1)`.\n ///\n /// `n` denotes the number of elements stored in the queue.\n public func pushFront<T>(queue : Queue<T>, element : T) : Queue<T> = check(?(element, queue.0), queue.1 + 1, queue.2);\n\n /// Insert a new element on the back end of a queue.\n /// Returns the new queue with all the elements of `queue`, followed by `element` on the back.\n ///\n /// This may involve dynamic rebalancing of the two, internally used lists.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.pushBack(Queue.pushBack(Queue.empty(), 1), 2);\n /// assert Queue.peekBack(queue) == ?2;\n /// assert Queue.size(queue) == 2;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)` worst-case, amortized to `O(1)`.\n ///\n /// Space: `O(size)` worst-case, amortized to `O(1)`.\n ///\n /// `n` denotes the number of elements stored in the queue.\n public func pushBack<T>(queue : Queue<T>, element : T) : Queue<T> = check(queue.0, queue.1 + 1, ?(element, queue.2));\n\n /// Remove the element on the front end of a queue.\n /// Returns `null` if `queue` is empty. Otherwise, it returns a pair of\n /// the first element and a new queue that contains all the remaining elements of `queue`.\n ///\n /// This may involve dynamic rebalancing of the two, internally used lists.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Runtime \"mo:core/Runtime\";\n ///\n /// persistent actor {\n /// let initial = Queue.pushBack(Queue.pushBack(Queue.empty(), 1), 2);\n /// // initial queue with elements [1, 2]\n /// switch (Queue.popFront(initial)) {\n /// case null Runtime.trap \"Empty queue impossible\";\n /// case (?(frontElement, remainingQueue)) {\n /// assert frontElement == 1;\n /// assert Queue.size(remainingQueue) == 1\n /// }\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(size)` worst-case, amortized to `O(1)`.\n ///\n /// Space: `O(size)` worst-case, amortized to `O(1)`.\n ///\n /// `n` denotes the number of elements stored in the queue.\n public func popFront<T>(queue : Queue<T>) : ?(T, Queue<T>) = if (queue.1 == 0) null else switch queue {\n case (?(i, f), n, b) ?(i, (f, n - 1, b));\n case (null, _, ?(i, null)) ?(i, (null, 0, null));\n case _ popFront(check queue)\n };\n\n /// Remove the element on the back end of a queue.\n /// Returns `null` if `queue` is empty. Otherwise, it returns a pair of\n /// a new queue that contains the remaining elements of `queue`\n /// and, as the second pair item, the removed back element.\n ///\n /// This may involve dynamic rebalancing of the two, internally used lists.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Runtime \"mo:core/Runtime\";\n ///\n /// persistent actor {\n /// let initial = Queue.pushBack(Queue.pushBack(Queue.empty(), 1), 2);\n /// // initial queue with elements [1, 2]\n /// let reduced = Queue.popBack(initial);\n /// switch reduced {\n /// case null Runtime.trap(\"Empty queue impossible\");\n /// case (?result) {\n /// let reducedQueue = result.0;\n /// let removedElement = result.1;\n /// assert removedElement == 2;\n /// assert Queue.size(reducedQueue) == 1;\n /// }\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(size)` worst-case, amortized to `O(1)`.\n ///\n /// Space: `O(size)` worst-case, amortized to `O(1)`.\n ///\n /// `n` denotes the number of elements stored in the queue.\n public func popBack<T>(queue : Queue<T>) : ?(Queue<T>, T) = if (queue.1 == 0) null else switch queue {\n case (f, n, ?(i, b)) ?((f, n - 1, b), i);\n case (?(i, null), _, null) ?((null, 0, null), i);\n case _ popBack(check queue)\n };\n\n /// Turn an iterator into a queue, consuming it.\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter([0, 1, 2, 3, 4].values());\n /// assert Queue.size(queue) == 5;\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromIter<T>(iter : Iter.Iter<T>) : Queue<T> {\n let list = List.fromIter iter;\n check(list, List.size list, null)\n };\n\n /// Create a queue from an array.\n /// Elements appear in the same order as in the array.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromArray<Text>([\"A\", \"B\", \"C\"]);\n /// assert Queue.size(queue) == 3;\n /// assert Queue.peekFront(queue) == ?\"A\";\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromArray<T>(array : [T]) : Queue<T> {\n let list = List.fromArray array;\n check(list, array.size(), null)\n };\n\n /// Create an immutable array from a queue.\n /// Elements appear in the same order as in the queue (front to back).\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromArray<Text>([\"A\", \"B\", \"C\"]);\n /// let array = Queue.toArray(queue);\n /// assert array == [\"A\", \"B\", \"C\"];\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toArray<T>(queue : Queue<T>) : [T] {\n let iter = values(queue);\n Array.tabulate<T>(\n queue.1,\n func(i) {\n switch (iter.next()) {\n case null {\n Prim.trap(\"pure/Queue.toArray: unexpected end of iterator\")\n };\n case (?value) { value }\n }\n }\n )\n };\n\n /// Convert a queue to an iterator of its elements in front-to-back order.\n ///\n /// Performance note: Creating the iterator needs `O(size)` runtime and space!\n ///\n /// Example:\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter([1, 2, 3].values());\n /// assert Iter.toArray(Queue.values(queue)) == [1, 2, 3];\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func values<T>(queue : Queue<T>) : Iter.Iter<T> = Iter.concat(List.values(queue.0), List.values(List.reverse(queue.2)));\n\n /// Compare two queues for equality using the provided equality function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue1 = Queue.fromIter([1, 2].values());\n /// let queue2 = Queue.fromIter([1, 2].values());\n /// let queue3 = Queue.fromIter([1, 3].values());\n /// assert Queue.equal(queue1, queue2, Nat.equal);\n /// assert not Queue.equal(queue1, queue3, Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func equal<T>(queue1 : Queue<T>, queue2 : Queue<T>, equal : (T, T) -> Bool) : Bool {\n if (queue1.1 != queue2.1) {\n return false\n };\n let (iter1, iter2) = (values(queue1), values(queue2));\n loop {\n switch (iter1.next(), iter2.next()) {\n case (null, null) { return true };\n case (?v1, ?v2) {\n if (not equal(v1, v2)) { return false }\n };\n case (_, _) { return false }\n }\n }\n };\n\n /// Return true if the given predicate `f` is true for all queue\n /// elements.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter([1, 2, 3].values());\n /// let allGreaterThanOne = Queue.all<Nat>(queue, func n = n > 1);\n /// assert not allGreaterThanOne; // false because 1 is not > 1\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)` as the current implementation uses `values` to iterate over the queue.\n ///\n /// *Runtime and space assumes that the `predicate` runs in `O(1)` time and space.\n public func all<T>(queue : Queue<T>, predicate : T -> Bool) : Bool {\n for (item in values queue) if (not (predicate item)) return false;\n return true\n };\n\n /// Return true if there exists a queue element for which\n /// the given predicate `f` is true.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter([1, 2, 3].values());\n /// let hasGreaterThanOne = Queue.any<Nat>(queue, func n = n > 1);\n /// assert hasGreaterThanOne; // true because 2 and 3 are > 1\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)` as the current implementation uses `values` to iterate over the queue.\n ///\n /// *Runtime and space assumes that the `predicate` runs in `O(1)` time and space.\n public func any<T>(queue : Queue<T>, predicate : T -> Bool) : Bool {\n for (item in values queue) if (predicate item) return true;\n return false\n };\n\n /// Call the given function for its side effect, with each queue element in turn.\n /// The order of visiting elements is front-to-back.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// var text = \"\";\n /// let queue = Queue.fromIter([\"A\", \"B\", \"C\"].values());\n /// Queue.forEach<Text>(queue, func n = text #= n);\n /// assert text == \"ABC\";\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in `O(1)` time and space.\n public func forEach<T>(queue : Queue<T>, f : T -> ()) = for (item in values queue) f item;\n\n /// Call the given function `f` on each queue element and collect the results\n /// in a new queue.\n ///\n /// Note: The order of visiting elements is undefined with the current implementation.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter([0, 1, 2].values());\n /// let textQueue = Queue.map<Nat, Text>(queue, Nat.toText);\n /// assert Iter.toArray(Queue.values(textQueue)) == [\"0\", \"1\", \"2\"];\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in `O(1)` time and space.\n public func map<T1, T2>(queue : Queue<T1>, f : T1 -> T2) : Queue<T2> {\n let (fr, n, b) = queue;\n (List.map(fr, f), n, List.map(b, f))\n };\n\n /// Create a new queue with only those elements of the original queue for which\n /// the given function (often called the _predicate_) returns true.\n ///\n /// Note: The order of visiting elements is undefined with the current implementation.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter([0, 1, 2, 1].values());\n /// let filtered = Queue.filter<Nat>(queue, func n = n != 1);\n /// assert Queue.size(filtered) == 2;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `predicate` runs in `O(1)` time and space.\n public func filter<T>(queue : Queue<T>, predicate : T -> Bool) : Queue<T> {\n let (fr, _, b) = queue;\n let front = List.filter(fr, predicate);\n let back = List.filter(b, predicate);\n check(front, List.size front + List.size back, back)\n };\n\n /// Call the given function on each queue element, and collect the non-null results\n /// in a new queue.\n ///\n /// Note: The order of visiting elements is undefined with the current implementation.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter([1, 2, 3].values());\n /// let doubled = Queue.filterMap<Nat, Nat>(\n /// queue,\n /// func n = if (n > 1) ?(n * 2) else null\n /// );\n /// assert Queue.size(doubled) == 2;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in `O(1)` time and space.\n public func filterMap<T, U>(queue : Queue<T>, f : T -> ?U) : Queue<U> {\n let (fr, _n, b) = queue;\n let front = List.filterMap(fr, f);\n let back = List.filterMap(b, f);\n check(front, List.size front + List.size back, back)\n };\n\n /// Convert a queue to its text representation using the provided conversion function.\n /// This function is meant to be used for debugging and testing purposes.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter([1, 2, 3].values());\n /// assert Queue.toText(queue, Nat.toText) == \"PureQueue[1, 2, 3]\";\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n public func toText<T>(queue : Queue<T>, f : T -> Text) : Text {\n var text = \"PureQueue[\";\n func add(item : T) {\n if (text.size() > 10) text #= \", \";\n text #= f(item)\n };\n List.forEach(queue.0, add);\n List.forEach(List.reverse(queue.2), add);\n text # \"]\"\n };\n\n /// Compare two queues using lexicographic ordering specified by argument function `compareItem`.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue1 = Queue.fromIter([1, 2].values());\n /// let queue2 = Queue.fromIter([1, 3].values());\n /// assert Queue.compare(queue1, queue2, Nat.compare) == #less;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that argument `compareItem` runs in `O(1)` time and space.\n public func compare<T>(queue1 : Queue<T>, queue2 : Queue<T>, compareItem : (T, T) -> Order.Order) : Order.Order {\n let (i1, i2) = (values queue1, values queue2);\n loop switch (i1.next(), i2.next()) {\n case (?v1, ?v2) switch (compareItem(v1, v2)) {\n case (#equal) ();\n case c return c\n };\n case (null, null) return #equal;\n case (null, _) return #less;\n case (_, null) return #greater\n }\n };\n\n /// Reverse the order of elements in a queue.\n /// This operation is cheap, it does NOT require copying the elements.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter([1, 2, 3].values());\n /// let reversed = Queue.reverse(queue);\n /// assert Queue.peekFront(reversed) == ?3;\n /// assert Queue.peekBack(reversed) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func reverse<T>(queue : Queue<T>) : Queue<T> = (queue.2, queue.1, queue.0)\n}\n"},"Principal.mo":{"content":"/// Module for interacting with Principals (users and canisters).\n///\n/// Principals are used to identify entities that can interact with the Internet\n/// Computer. These entities are either users or canisters.\n///\n/// Example textual representation of Principals:\n///\n/// `un4fu-tqaaa-aaaab-qadjq-cai`\n///\n/// In Motoko, there is a primitive Principal type called `Principal`. As an example\n/// of where you might see Principals, you can access the Principal of the\n/// caller of your shared function.\n///\n/// ```motoko no-repl\n/// persistent actor {\n/// public shared(msg) func foo() {\n/// let caller : Principal = msg.caller;\n/// };\n/// }\n/// ```\n///\n/// Then, you can use this module to work with the `Principal`.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import Principal \"mo:core/Principal\";\n/// ```\n\nimport Prim \"mo:⛔\";\nimport Blob \"Blob\";\nimport Array \"Array\";\nimport VarArray \"VarArray\";\nimport Nat8 \"Nat8\";\nimport Nat32 \"Nat32\";\nimport Nat64 \"Nat64\";\nimport Text \"Text\";\nimport Types \"Types\";\n\nmodule {\n\n public type Principal = Prim.Types.Principal;\n\n /// Get the `Principal` identifier of an actor.\n ///\n /// Example:\n /// ```motoko include=import no-repl\n /// actor MyCanister {\n /// func getPrincipal() : Principal {\n /// let principal = Principal.fromActor(MyCanister);\n /// }\n /// }\n /// ```\n public func fromActor(a : actor {}) : Principal = Prim.principalOfActor a;\n\n /// Compute the Ledger account identifier of a principal. Optionally specify a sub-account.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let subAccount : Blob = \"\\4A\\8D\\3F\\2B\\6E\\01\\C8\\7D\\9E\\03\\B4\\56\\7C\\F8\\9A\\01\\D2\\34\\56\\78\\9A\\BC\\DE\\F0\\12\\34\\56\\78\\9A\\BC\\DE\\F0\";\n /// let account = Principal.toLedgerAccount(principal, ?subAccount);\n /// assert account == \"\\8C\\5C\\20\\C6\\15\\3F\\7F\\51\\E2\\0D\\0F\\0F\\B5\\08\\51\\5B\\47\\65\\63\\A9\\62\\B4\\A9\\91\\5F\\4F\\02\\70\\8A\\ED\\4F\\82\";\n /// ```\n public func toLedgerAccount(principal : Principal, subAccount : ?Blob) : Blob {\n let sha224 = SHA224();\n let accountSeparator : Blob = \"\\0Aaccount-id\";\n sha224.writeBlob(accountSeparator);\n sha224.writeBlob(toBlob(principal));\n switch subAccount {\n case (?subAccount) {\n sha224.writeBlob(subAccount)\n };\n case (null) {\n let defaultSubAccount = Array.tabulate<Nat8>(32, func _ = 0);\n sha224.writeArray(defaultSubAccount)\n }\n };\n\n let hashSum = sha224.sum();\n\n // hashBlob is a CRC32 implementation\n let crc32Bytes = nat32ToByteArray(Prim.hashBlob hashSum);\n\n Blob.fromArray(Array.concat(crc32Bytes, Blob.toArray(hashSum)))\n };\n\n /// Convert a `Principal` to its `Blob` (bytes) representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let blob = Principal.toBlob(principal);\n /// assert blob == \"\\00\\00\\00\\00\\00\\30\\00\\D3\\01\\01\";\n /// ```\n public func toBlob(p : Principal) : Blob = Prim.blobOfPrincipal p;\n\n /// Converts a `Blob` (bytes) representation of a `Principal` to a `Principal` value.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\00\\00\\00\\00\\30\\00\\D3\\01\\01\" : Blob;\n /// let principal = Principal.fromBlob(blob);\n /// assert Principal.toText(principal) == \"un4fu-tqaaa-aaaab-qadjq-cai\";\n /// ```\n public func fromBlob(b : Blob) : Principal = Prim.principalOfBlob b;\n\n /// Converts a `Principal` to its `Text` representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// assert Principal.toText(principal) == \"un4fu-tqaaa-aaaab-qadjq-cai\";\n /// ```\n public func toText(p : Principal) : Text = debug_show (p);\n\n /// Converts a `Text` representation of a `Principal` to a `Principal` value.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// assert Principal.toText(principal) == \"un4fu-tqaaa-aaaab-qadjq-cai\";\n /// ```\n public func fromText(t : Text) : Principal = fromActor(actor (t));\n\n private let anonymousBlob : Blob = \"\\04\";\n\n /// Constructs and returns the anonymous principal.\n public func anonymous() : Principal = Prim.principalOfBlob(anonymousBlob);\n\n /// Checks if the given principal represents an anonymous user.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// assert not Principal.isAnonymous(principal);\n /// ```\n public func isAnonymous(p : Principal) : Bool = Prim.blobOfPrincipal p == anonymousBlob;\n\n /// Checks if the given principal is a canister.\n ///\n /// The last byte for opaque principal ids must be 0x01\n /// https://internetcomputer.org/docs/current/references/ic-interface-spec#principal\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// assert Principal.isCanister(principal);\n /// ```\n public func isCanister(p : Principal) : Bool {\n let byteArray = toByteArray(p);\n\n byteArray.size() >= 0 and byteArray.size() <= 29 and isLastByte(byteArray, 1)\n };\n\n /// Checks if the given principal is a self authenticating principal.\n /// Most of the time, this is a user principal.\n ///\n /// The last byte for user principal ids must be 0x02\n /// https://internetcomputer.org/docs/current/references/ic-interface-spec#principal\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"6rgy7-3uukz-jrj2k-crt3v-u2wjm-dmn3t-p26d6-ndilt-3gusv-75ybk-jae\");\n /// assert Principal.isSelfAuthenticating(principal);\n /// ```\n public func isSelfAuthenticating(p : Principal) : Bool {\n let byteArray = toByteArray(p);\n\n byteArray.size() == 29 and isLastByte(byteArray, 2)\n };\n\n /// Checks if the given principal is a reserved principal.\n ///\n /// The last byte for reserved principal ids must be 0x7f\n /// https://internetcomputer.org/docs/current/references/ic-interface-spec#principal\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// assert not Principal.isReserved(principal);\n /// ```\n public func isReserved(p : Principal) : Bool {\n let byteArray = toByteArray(p);\n\n byteArray.size() >= 0 and byteArray.size() <= 29 and isLastByte(byteArray, 127)\n };\n\n /// Checks if the given principal can control this canister.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// assert not Principal.isController(principal);\n /// ```\n public func isController(p : Principal) : Bool = Prim.isController p;\n\n /// Hashes the given principal by hashing its `Blob` representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// assert Principal.hash(principal) == 2_742_573_646;\n /// ```\n public func hash(principal : Principal) : Types.Hash = Blob.hash(Prim.blobOfPrincipal(principal));\n\n /// General purpose comparison function for `Principal`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `principal1` with\n /// `principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// assert Principal.compare(principal1, principal2) == #equal;\n /// ```\n public func compare(principal1 : Principal, principal2 : Principal) : {\n #less;\n #equal;\n #greater\n } {\n if (principal1 < principal2) {\n #less\n } else if (principal1 == principal2) {\n #equal\n } else {\n #greater\n }\n };\n\n /// Equality function for Principal types.\n /// This is equivalent to `principal1 == principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.equal(principal1, principal2);\n /// assert principal1 == principal2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.anonymous();\n /// let principal2 = Principal.fromBlob(\"\\04\");\n /// assert Principal.equal(principal1, principal2);\n /// ```\n public func equal(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 == principal2\n };\n\n /// Inequality function for Principal types.\n /// This is equivalent to `principal1 != principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.notEqual(principal1, principal2);\n /// assert not (principal1 != principal2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 != principal2\n };\n\n /// \"Less than\" function for Principal types.\n /// This is equivalent to `principal1 < principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.less(principal1, principal2);\n /// assert not (principal1 < principal2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 < principal2\n };\n\n /// \"Less than or equal to\" function for Principal types.\n /// This is equivalent to `principal1 <= principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.lessOrEqual(principal1, principal2);\n /// assert principal1 <= principal2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 <= principal2\n };\n\n /// \"Greater than\" function for Principal types.\n /// This is equivalent to `principal1 > principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.greater(principal1, principal2);\n /// assert not (principal1 > principal2);\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 > principal2\n };\n\n /// \"Greater than or equal to\" function for Principal types.\n /// This is equivalent to `principal1 >= principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.greaterOrEqual(principal1, principal2);\n /// assert principal1 >= principal2;\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 >= principal2\n };\n\n /**\n * SHA224 Utilities used in toAccount().\n * Utilities are not exposed as public functions.\n * Taken with permission from https://github.com/research-ag/sha2\n **/\n let K00 : Nat32 = 0x428a2f98;\n let K01 : Nat32 = 0x71374491;\n let K02 : Nat32 = 0xb5c0fbcf;\n let K03 : Nat32 = 0xe9b5dba5;\n let K04 : Nat32 = 0x3956c25b;\n let K05 : Nat32 = 0x59f111f1;\n let K06 : Nat32 = 0x923f82a4;\n let K07 : Nat32 = 0xab1c5ed5;\n let K08 : Nat32 = 0xd807aa98;\n let K09 : Nat32 = 0x12835b01;\n let K10 : Nat32 = 0x243185be;\n let K11 : Nat32 = 0x550c7dc3;\n let K12 : Nat32 = 0x72be5d74;\n let K13 : Nat32 = 0x80deb1fe;\n let K14 : Nat32 = 0x9bdc06a7;\n let K15 : Nat32 = 0xc19bf174;\n let K16 : Nat32 = 0xe49b69c1;\n let K17 : Nat32 = 0xefbe4786;\n let K18 : Nat32 = 0x0fc19dc6;\n let K19 : Nat32 = 0x240ca1cc;\n let K20 : Nat32 = 0x2de92c6f;\n let K21 : Nat32 = 0x4a7484aa;\n let K22 : Nat32 = 0x5cb0a9dc;\n let K23 : Nat32 = 0x76f988da;\n let K24 : Nat32 = 0x983e5152;\n let K25 : Nat32 = 0xa831c66d;\n let K26 : Nat32 = 0xb00327c8;\n let K27 : Nat32 = 0xbf597fc7;\n let K28 : Nat32 = 0xc6e00bf3;\n let K29 : Nat32 = 0xd5a79147;\n let K30 : Nat32 = 0x06ca6351;\n let K31 : Nat32 = 0x14292967;\n let K32 : Nat32 = 0x27b70a85;\n let K33 : Nat32 = 0x2e1b2138;\n let K34 : Nat32 = 0x4d2c6dfc;\n let K35 : Nat32 = 0x53380d13;\n let K36 : Nat32 = 0x650a7354;\n let K37 : Nat32 = 0x766a0abb;\n let K38 : Nat32 = 0x81c2c92e;\n let K39 : Nat32 = 0x92722c85;\n let K40 : Nat32 = 0xa2bfe8a1;\n let K41 : Nat32 = 0xa81a664b;\n let K42 : Nat32 = 0xc24b8b70;\n let K43 : Nat32 = 0xc76c51a3;\n let K44 : Nat32 = 0xd192e819;\n let K45 : Nat32 = 0xd6990624;\n let K46 : Nat32 = 0xf40e3585;\n let K47 : Nat32 = 0x106aa070;\n let K48 : Nat32 = 0x19a4c116;\n let K49 : Nat32 = 0x1e376c08;\n let K50 : Nat32 = 0x2748774c;\n let K51 : Nat32 = 0x34b0bcb5;\n let K52 : Nat32 = 0x391c0cb3;\n let K53 : Nat32 = 0x4ed8aa4a;\n let K54 : Nat32 = 0x5b9cca4f;\n let K55 : Nat32 = 0x682e6ff3;\n let K56 : Nat32 = 0x748f82ee;\n let K57 : Nat32 = 0x78a5636f;\n let K58 : Nat32 = 0x84c87814;\n let K59 : Nat32 = 0x8cc70208;\n let K60 : Nat32 = 0x90befffa;\n let K61 : Nat32 = 0xa4506ceb;\n let K62 : Nat32 = 0xbef9a3f7;\n let K63 : Nat32 = 0xc67178f2;\n\n let ivs : [[Nat32]] = [\n [\n // 224\n 0xc1059ed8,\n 0x367cd507,\n 0x3070dd17,\n 0xf70e5939,\n 0xffc00b31,\n 0x68581511,\n 0x64f98fa7,\n 0xbefa4fa4\n ],\n [\n // 256\n 0x6a09e667,\n 0xbb67ae85,\n 0x3c6ef372,\n 0xa54ff53a,\n 0x510e527f,\n 0x9b05688c,\n 0x1f83d9ab,\n 0x5be0cd19\n ]\n ];\n\n let rot = Nat32.bitrotRight;\n\n class SHA224() {\n let (sum_bytes, iv) = (28, 0);\n\n var s0 : Nat32 = 0;\n var s1 : Nat32 = 0;\n var s2 : Nat32 = 0;\n var s3 : Nat32 = 0;\n var s4 : Nat32 = 0;\n var s5 : Nat32 = 0;\n var s6 : Nat32 = 0;\n var s7 : Nat32 = 0;\n\n let msg : [var Nat32] = VarArray.repeat<Nat32>(0, 16);\n let digest = VarArray.repeat<Nat8>(0, sum_bytes);\n var word : Nat32 = 0;\n\n var i_msg : Nat8 = 0;\n var i_byte : Nat8 = 4;\n var i_block : Nat64 = 0;\n\n public func reset() {\n i_msg := 0;\n i_byte := 4;\n i_block := 0;\n s0 := ivs[iv][0];\n s1 := ivs[iv][1];\n s2 := ivs[iv][2];\n s3 := ivs[iv][3];\n s4 := ivs[iv][4];\n s5 := ivs[iv][5];\n s6 := ivs[iv][6];\n s7 := ivs[iv][7]\n };\n\n reset();\n\n private func writeByte(val : Nat8) : () {\n word := (word << 8) ^ Nat32.fromIntWrap(Nat8.toNat(val));\n i_byte -%= 1;\n if (i_byte == 0) {\n msg[Nat8.toNat(i_msg)] := word;\n word := 0;\n i_byte := 4;\n i_msg +%= 1;\n if (i_msg == 16) {\n process_block();\n i_msg := 0;\n i_block +%= 1\n }\n }\n };\n\n private func process_block() : () {\n let w00 = msg[0];\n let w01 = msg[1];\n let w02 = msg[2];\n let w03 = msg[3];\n let w04 = msg[4];\n let w05 = msg[5];\n let w06 = msg[6];\n let w07 = msg[7];\n let w08 = msg[8];\n let w09 = msg[9];\n let w10 = msg[10];\n let w11 = msg[11];\n let w12 = msg[12];\n let w13 = msg[13];\n let w14 = msg[14];\n let w15 = msg[15];\n let w16 = w00 +% rot(w01, 07) ^ rot(w01, 18) ^ (w01 >> 03) +% w09 +% rot(w14, 17) ^ rot(w14, 19) ^ (w14 >> 10);\n let w17 = w01 +% rot(w02, 07) ^ rot(w02, 18) ^ (w02 >> 03) +% w10 +% rot(w15, 17) ^ rot(w15, 19) ^ (w15 >> 10);\n let w18 = w02 +% rot(w03, 07) ^ rot(w03, 18) ^ (w03 >> 03) +% w11 +% rot(w16, 17) ^ rot(w16, 19) ^ (w16 >> 10);\n let w19 = w03 +% rot(w04, 07) ^ rot(w04, 18) ^ (w04 >> 03) +% w12 +% rot(w17, 17) ^ rot(w17, 19) ^ (w17 >> 10);\n let w20 = w04 +% rot(w05, 07) ^ rot(w05, 18) ^ (w05 >> 03) +% w13 +% rot(w18, 17) ^ rot(w18, 19) ^ (w18 >> 10);\n let w21 = w05 +% rot(w06, 07) ^ rot(w06, 18) ^ (w06 >> 03) +% w14 +% rot(w19, 17) ^ rot(w19, 19) ^ (w19 >> 10);\n let w22 = w06 +% rot(w07, 07) ^ rot(w07, 18) ^ (w07 >> 03) +% w15 +% rot(w20, 17) ^ rot(w20, 19) ^ (w20 >> 10);\n let w23 = w07 +% rot(w08, 07) ^ rot(w08, 18) ^ (w08 >> 03) +% w16 +% rot(w21, 17) ^ rot(w21, 19) ^ (w21 >> 10);\n let w24 = w08 +% rot(w09, 07) ^ rot(w09, 18) ^ (w09 >> 03) +% w17 +% rot(w22, 17) ^ rot(w22, 19) ^ (w22 >> 10);\n let w25 = w09 +% rot(w10, 07) ^ rot(w10, 18) ^ (w10 >> 03) +% w18 +% rot(w23, 17) ^ rot(w23, 19) ^ (w23 >> 10);\n let w26 = w10 +% rot(w11, 07) ^ rot(w11, 18) ^ (w11 >> 03) +% w19 +% rot(w24, 17) ^ rot(w24, 19) ^ (w24 >> 10);\n let w27 = w11 +% rot(w12, 07) ^ rot(w12, 18) ^ (w12 >> 03) +% w20 +% rot(w25, 17) ^ rot(w25, 19) ^ (w25 >> 10);\n let w28 = w12 +% rot(w13, 07) ^ rot(w13, 18) ^ (w13 >> 03) +% w21 +% rot(w26, 17) ^ rot(w26, 19) ^ (w26 >> 10);\n let w29 = w13 +% rot(w14, 07) ^ rot(w14, 18) ^ (w14 >> 03) +% w22 +% rot(w27, 17) ^ rot(w27, 19) ^ (w27 >> 10);\n let w30 = w14 +% rot(w15, 07) ^ rot(w15, 18) ^ (w15 >> 03) +% w23 +% rot(w28, 17) ^ rot(w28, 19) ^ (w28 >> 10);\n let w31 = w15 +% rot(w16, 07) ^ rot(w16, 18) ^ (w16 >> 03) +% w24 +% rot(w29, 17) ^ rot(w29, 19) ^ (w29 >> 10);\n let w32 = w16 +% rot(w17, 07) ^ rot(w17, 18) ^ (w17 >> 03) +% w25 +% rot(w30, 17) ^ rot(w30, 19) ^ (w30 >> 10);\n let w33 = w17 +% rot(w18, 07) ^ rot(w18, 18) ^ (w18 >> 03) +% w26 +% rot(w31, 17) ^ rot(w31, 19) ^ (w31 >> 10);\n let w34 = w18 +% rot(w19, 07) ^ rot(w19, 18) ^ (w19 >> 03) +% w27 +% rot(w32, 17) ^ rot(w32, 19) ^ (w32 >> 10);\n let w35 = w19 +% rot(w20, 07) ^ rot(w20, 18) ^ (w20 >> 03) +% w28 +% rot(w33, 17) ^ rot(w33, 19) ^ (w33 >> 10);\n let w36 = w20 +% rot(w21, 07) ^ rot(w21, 18) ^ (w21 >> 03) +% w29 +% rot(w34, 17) ^ rot(w34, 19) ^ (w34 >> 10);\n let w37 = w21 +% rot(w22, 07) ^ rot(w22, 18) ^ (w22 >> 03) +% w30 +% rot(w35, 17) ^ rot(w35, 19) ^ (w35 >> 10);\n let w38 = w22 +% rot(w23, 07) ^ rot(w23, 18) ^ (w23 >> 03) +% w31 +% rot(w36, 17) ^ rot(w36, 19) ^ (w36 >> 10);\n let w39 = w23 +% rot(w24, 07) ^ rot(w24, 18) ^ (w24 >> 03) +% w32 +% rot(w37, 17) ^ rot(w37, 19) ^ (w37 >> 10);\n let w40 = w24 +% rot(w25, 07) ^ rot(w25, 18) ^ (w25 >> 03) +% w33 +% rot(w38, 17) ^ rot(w38, 19) ^ (w38 >> 10);\n let w41 = w25 +% rot(w26, 07) ^ rot(w26, 18) ^ (w26 >> 03) +% w34 +% rot(w39, 17) ^ rot(w39, 19) ^ (w39 >> 10);\n let w42 = w26 +% rot(w27, 07) ^ rot(w27, 18) ^ (w27 >> 03) +% w35 +% rot(w40, 17) ^ rot(w40, 19) ^ (w40 >> 10);\n let w43 = w27 +% rot(w28, 07) ^ rot(w28, 18) ^ (w28 >> 03) +% w36 +% rot(w41, 17) ^ rot(w41, 19) ^ (w41 >> 10);\n let w44 = w28 +% rot(w29, 07) ^ rot(w29, 18) ^ (w29 >> 03) +% w37 +% rot(w42, 17) ^ rot(w42, 19) ^ (w42 >> 10);\n let w45 = w29 +% rot(w30, 07) ^ rot(w30, 18) ^ (w30 >> 03) +% w38 +% rot(w43, 17) ^ rot(w43, 19) ^ (w43 >> 10);\n let w46 = w30 +% rot(w31, 07) ^ rot(w31, 18) ^ (w31 >> 03) +% w39 +% rot(w44, 17) ^ rot(w44, 19) ^ (w44 >> 10);\n let w47 = w31 +% rot(w32, 07) ^ rot(w32, 18) ^ (w32 >> 03) +% w40 +% rot(w45, 17) ^ rot(w45, 19) ^ (w45 >> 10);\n let w48 = w32 +% rot(w33, 07) ^ rot(w33, 18) ^ (w33 >> 03) +% w41 +% rot(w46, 17) ^ rot(w46, 19) ^ (w46 >> 10);\n let w49 = w33 +% rot(w34, 07) ^ rot(w34, 18) ^ (w34 >> 03) +% w42 +% rot(w47, 17) ^ rot(w47, 19) ^ (w47 >> 10);\n let w50 = w34 +% rot(w35, 07) ^ rot(w35, 18) ^ (w35 >> 03) +% w43 +% rot(w48, 17) ^ rot(w48, 19) ^ (w48 >> 10);\n let w51 = w35 +% rot(w36, 07) ^ rot(w36, 18) ^ (w36 >> 03) +% w44 +% rot(w49, 17) ^ rot(w49, 19) ^ (w49 >> 10);\n let w52 = w36 +% rot(w37, 07) ^ rot(w37, 18) ^ (w37 >> 03) +% w45 +% rot(w50, 17) ^ rot(w50, 19) ^ (w50 >> 10);\n let w53 = w37 +% rot(w38, 07) ^ rot(w38, 18) ^ (w38 >> 03) +% w46 +% rot(w51, 17) ^ rot(w51, 19) ^ (w51 >> 10);\n let w54 = w38 +% rot(w39, 07) ^ rot(w39, 18) ^ (w39 >> 03) +% w47 +% rot(w52, 17) ^ rot(w52, 19) ^ (w52 >> 10);\n let w55 = w39 +% rot(w40, 07) ^ rot(w40, 18) ^ (w40 >> 03) +% w48 +% rot(w53, 17) ^ rot(w53, 19) ^ (w53 >> 10);\n let w56 = w40 +% rot(w41, 07) ^ rot(w41, 18) ^ (w41 >> 03) +% w49 +% rot(w54, 17) ^ rot(w54, 19) ^ (w54 >> 10);\n let w57 = w41 +% rot(w42, 07) ^ rot(w42, 18) ^ (w42 >> 03) +% w50 +% rot(w55, 17) ^ rot(w55, 19) ^ (w55 >> 10);\n let w58 = w42 +% rot(w43, 07) ^ rot(w43, 18) ^ (w43 >> 03) +% w51 +% rot(w56, 17) ^ rot(w56, 19) ^ (w56 >> 10);\n let w59 = w43 +% rot(w44, 07) ^ rot(w44, 18) ^ (w44 >> 03) +% w52 +% rot(w57, 17) ^ rot(w57, 19) ^ (w57 >> 10);\n let w60 = w44 +% rot(w45, 07) ^ rot(w45, 18) ^ (w45 >> 03) +% w53 +% rot(w58, 17) ^ rot(w58, 19) ^ (w58 >> 10);\n let w61 = w45 +% rot(w46, 07) ^ rot(w46, 18) ^ (w46 >> 03) +% w54 +% rot(w59, 17) ^ rot(w59, 19) ^ (w59 >> 10);\n let w62 = w46 +% rot(w47, 07) ^ rot(w47, 18) ^ (w47 >> 03) +% w55 +% rot(w60, 17) ^ rot(w60, 19) ^ (w60 >> 10);\n let w63 = w47 +% rot(w48, 07) ^ rot(w48, 18) ^ (w48 >> 03) +% w56 +% rot(w61, 17) ^ rot(w61, 19) ^ (w61 >> 10);\n\n /*\n for ((i, j, k, l, m) in expansion_rounds.values()) {\n // (j,k,l,m) = (i+1,i+9,i+14,i+16)\n let (v0, v1) = (msg[j], msg[l]);\n let s0 = rot(v0, 07) ^ rot(v0, 18) ^ (v0 >> 03);\n let s1 = rot(v1, 17) ^ rot(v1, 19) ^ (v1 >> 10);\n msg[m] := msg[i] +% s0 +% msg[k] +% s1;\n };\n */\n // compress\n var a = s0;\n var b = s1;\n var c = s2;\n var d = s3;\n var e = s4;\n var f = s5;\n var g = s6;\n var h = s7;\n var t = 0 : Nat32;\n\n t := h +% K00 +% w00 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K01 +% w01 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K02 +% w02 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K03 +% w03 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K04 +% w04 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K05 +% w05 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K06 +% w06 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K07 +% w07 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K08 +% w08 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K09 +% w09 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K10 +% w10 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K11 +% w11 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K12 +% w12 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K13 +% w13 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K14 +% w14 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K15 +% w15 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K16 +% w16 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K17 +% w17 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K18 +% w18 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K19 +% w19 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K20 +% w20 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K21 +% w21 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K22 +% w22 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K23 +% w23 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K24 +% w24 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K25 +% w25 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K26 +% w26 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K27 +% w27 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K28 +% w28 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K29 +% w29 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K30 +% w30 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K31 +% w31 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K32 +% w32 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K33 +% w33 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K34 +% w34 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K35 +% w35 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K36 +% w36 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K37 +% w37 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K38 +% w38 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K39 +% w39 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K40 +% w40 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K41 +% w41 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K42 +% w42 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K43 +% w43 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K44 +% w44 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K45 +% w45 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K46 +% w46 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K47 +% w47 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K48 +% w48 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K49 +% w49 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K50 +% w50 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K51 +% w51 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K52 +% w52 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K53 +% w53 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K54 +% w54 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K55 +% w55 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K56 +% w56 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K57 +% w57 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K58 +% w58 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K59 +% w59 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K60 +% w60 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K61 +% w61 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K62 +% w62 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K63 +% w63 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n\n /*\n for (i in compression_rounds.keys()) {\n let ch = (e & f) ^ (^ e & g);\n let maj = (a & b) ^ (a & c) ^ (b & c);\n let sigma0 = rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n let sigma1 = rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n let t = h +% K[i] +% msg[i] +% ch +% sigma1;\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% maj +% sigma0;\n };\n */\n // final addition\n s0 +%= a;\n s1 +%= b;\n s2 +%= c;\n s3 +%= d;\n s4 +%= e;\n s5 +%= f;\n s6 +%= g;\n s7 +%= h\n };\n\n public func writeIter(iter : { next() : ?Nat8 }) : () {\n label reading loop {\n switch (iter.next()) {\n case (?val) {\n writeByte(val);\n continue reading\n };\n case (null) {\n break reading\n }\n }\n }\n };\n\n public func writeArray(arr : [Nat8]) : () = writeIter(arr.vals());\n public func writeBlob(blob : Blob) : () = writeIter(blob.vals());\n\n public func sum() : Blob {\n // calculate padding\n // t = bytes in the last incomplete block (0-63)\n let t : Nat8 = (i_msg << 2) +% 4 -% i_byte;\n // p = length of padding (1-64)\n var p : Nat8 = if (t < 56) (56 -% t) else (120 -% t);\n // n_bits = length of message in bits\n let n_bits : Nat64 = ((i_block << 6) +% Nat64.fromIntWrap(Nat8.toNat(t))) << 3;\n\n // write padding\n writeByte(0x80);\n p -%= 1;\n while (p != 0) {\n writeByte(0x00);\n p -%= 1\n };\n\n // write length (8 bytes)\n // Note: this exactly fills the block buffer, hence process_block will get\n // triggered by the last writeByte\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 56) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 48) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 40) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 32) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 24) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 16) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 8) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat(n_bits & 0xff)));\n\n // retrieve sum\n digest[0] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 24) & 0xff));\n digest[1] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 16) & 0xff));\n digest[2] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 8) & 0xff));\n digest[3] := Nat8.fromIntWrap(Nat32.toNat(s0 & 0xff));\n digest[4] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 24) & 0xff));\n digest[5] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 16) & 0xff));\n digest[6] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 8) & 0xff));\n digest[7] := Nat8.fromIntWrap(Nat32.toNat(s1 & 0xff));\n digest[8] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 24) & 0xff));\n digest[9] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 16) & 0xff));\n digest[10] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 8) & 0xff));\n digest[11] := Nat8.fromIntWrap(Nat32.toNat(s2 & 0xff));\n digest[12] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 24) & 0xff));\n digest[13] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 16) & 0xff));\n digest[14] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 8) & 0xff));\n digest[15] := Nat8.fromIntWrap(Nat32.toNat(s3 & 0xff));\n digest[16] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 24) & 0xff));\n digest[17] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 16) & 0xff));\n digest[18] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 8) & 0xff));\n digest[19] := Nat8.fromIntWrap(Nat32.toNat(s4 & 0xff));\n digest[20] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 24) & 0xff));\n digest[21] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 16) & 0xff));\n digest[22] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 8) & 0xff));\n digest[23] := Nat8.fromIntWrap(Nat32.toNat(s5 & 0xff));\n digest[24] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 24) & 0xff));\n digest[25] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 16) & 0xff));\n digest[26] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 8) & 0xff));\n digest[27] := Nat8.fromIntWrap(Nat32.toNat(s6 & 0xff));\n\n return Blob.fromVarArray(digest)\n }\n }; // class SHA224\n\n func nat32ToByteArray(n : Nat32) : [Nat8] {\n func byte(n : Nat32) : Nat8 {\n Nat8.fromNat(Nat32.toNat(n & 0xff))\n };\n [byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)]\n };\n\n func toByteArray(p : Principal) : [Nat8] = Blob.toArray(toBlob(p));\n\n func isLastByte(byteArray : [Nat8], byte : Nat8) : Bool {\n let size = byteArray.size();\n size > 0 and byteArray[size - 1] == byte\n }\n}\n"},"VarArray.mo":{"content":"/// Provides extended utility functions on mutable Arrays (`[var]`).\n///\n/// Note the difference between mutable (`[var]`) and immutable (`[]`) arrays.\n/// Mutable arrays allow their elements to be modified after creation, while\n/// immutable arrays are fixed once created.\n///\n/// WARNING: If you are looking for a list that can grow and shrink in size,\n/// it is recommended you use `List` for those purposes.\n/// Arrays must be created with a fixed size.\n///\n/// Import from the core library to use this module.\n/// ```motoko name=import\n/// import VarArray \"mo:core/VarArray\";\n/// ```\n\nimport Types \"Types\";\nimport Order \"Order\";\nimport Result \"Result\";\nimport Option \"Option\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Creates an empty mutable array (equivalent to `[var]`).\n ///\n /// ```motoko include=import\n /// let array = VarArray.empty<Text>();\n /// assert array.size() == 0;\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func empty<T>() : [var T] = [var];\n\n /// Creates a mutable array containing `item` repeated `size` times.\n ///\n /// ```motoko include=import\n /// import Text \"mo:core/Text\";\n ///\n /// let array = VarArray.repeat<Text>(\"Echo\", 3);\n /// assert VarArray.equal(array, [var \"Echo\", \"Echo\", \"Echo\"], Text.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func repeat<T>(item : T, size : Nat) : [var T] = Prim.Array_init<T>(size, item);\n\n /// Duplicates `array`, returning a shallow copy of the original.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array1 = [var 1, 2, 3];\n /// let array2 = VarArray.clone<Nat>(array1);\n /// array2[0] := 0;\n /// assert VarArray.equal(array1, [var 1, 2, 3], Nat.equal);\n /// assert VarArray.equal(array2, [var 0, 2, 3], Nat.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func clone<T>(array : [var T]) : [var T] = Prim.Array_tabulateVar<T>(array.size(), func i = array[i]);\n\n /// Creates a mutable array of size `size`. Each element at index i\n /// is created by applying `generator` to i.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array : [var Nat] = VarArray.tabulate<Nat>(4, func i = i * 2);\n /// assert VarArray.equal(array, [var 0, 2, 4, 6], Nat.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `generator` runs in O(1) time and space.\n public func tabulate<T>(size : Nat, generator : Nat -> T) : [var T] = Prim.Array_tabulateVar(size, generator);\n\n /// Tests if two arrays contain equal values (i.e. they represent the same\n /// list of elements). Uses `equal` to compare elements in the arrays.\n ///\n /// ```motoko include=import\n /// // Use the equal function from the Nat module to compare Nats\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array1 = [var 0, 1, 2, 3];\n /// let array2 = [var 0, 1, 2, 3];\n /// assert VarArray.equal(array1, array2, Nat.equal);\n /// ```\n ///\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func equal<T>(array1 : [var T], array2 : [var T], equal : (T, T) -> Bool) : Bool {\n let size1 = array1.size();\n let size2 = array2.size();\n if (size1 != size2) {\n return false\n };\n var i = 0;\n while (i < size1) {\n if (not equal(array1[i], array2[i])) {\n return false\n };\n i += 1\n };\n true\n };\n\n /// Returns the first value in `array` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let array = [var 1, 9, 4, 8];\n /// let found = VarArray.find<Nat>(array, func x = x > 8);\n /// assert found == ?9;\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func find<T>(array : [var T], predicate : T -> Bool) : ?T {\n for (element in array.vals()) {\n if (predicate element) {\n return ?element\n }\n };\n null\n };\n\n /// Returns the first index in `array` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let array = [var 'A', 'B', 'C', 'D'];\n /// let found = VarArray.findIndex<Char>(array, func(x) { x == 'C' });\n /// assert found == ?2;\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func findIndex<T>(array : [var T], predicate : T -> Bool) : ?Nat {\n for ((index, element) in enumerate(array)) {\n if (predicate element) {\n return ?index\n }\n };\n null\n };\n\n /// Create a new mutable array by concatenating the values of `array1` and `array2`.\n /// Note that `VarArray.concat` copies its arguments and has linear complexity.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array1 = [var 1, 2, 3];\n /// let array2 = [var 4, 5, 6];\n /// let result = VarArray.concat<Nat>(array1, array2);\n /// assert VarArray.equal(result, [var 1, 2, 3, 4, 5, 6], Nat.equal);\n /// ```\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(size1 + size2)\n public func concat<T>(array1 : [var T], array2 : [var T]) : [var T] {\n let size1 = array1.size();\n let size2 = array2.size();\n tabulate<T>(\n size1 + size2,\n func i {\n if (i < size1) {\n array1[i]\n } else {\n array2[i - size1]\n }\n }\n )\n };\n\n /// Creates a new sorted copy of the mutable array according to `compare`.\n /// Sort is deterministic and stable.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 4, 2, 6];\n /// let sorted = VarArray.sort(array, Nat.compare);\n /// assert VarArray.equal(sorted, [var 2, 4, 6], Nat.equal);\n /// ```\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func sort<T>(array : [var T], compare : (T, T) -> Order.Order) : [var T] {\n let newArray = clone(array);\n sortInPlace(newArray, compare);\n newArray\n };\n\n /// Sorts the elements in a mutable array in place according to `compare`.\n /// Sort is deterministic and stable. This modifies the original array.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 4, 2, 6];\n /// VarArray.sortInPlace(array, Nat.compare);\n /// assert VarArray.equal(array, [var 2, 4, 6], Nat.equal);\n /// ```\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func sortInPlace<T>(array : [var T], compare : (T, T) -> Order.Order) : () {\n // Stable merge sort in a bottom-up iterative style. Same algorithm as the sort in Buffer.\n let size = array.size();\n if (size == 0) {\n return\n };\n let scratchSpace = Prim.Array_init<T>(size, array[0]);\n\n let sizeDec = size - 1 : Nat;\n var currSize = 1; // current size of the subarrays being merged\n // when the current size == size, the array has been merged into a single sorted array\n while (currSize < size) {\n var leftStart = 0; // selects the current left subarray being merged\n while (leftStart < sizeDec) {\n let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n leftStart + currSize - 1\n } else { sizeDec };\n let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n leftStart + (2 * currSize) - 1\n } else { sizeDec };\n\n // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n var left = leftStart;\n var right = mid + 1;\n var nextSorted = leftStart;\n while (left < mid + 1 and right < rightEnd + 1) {\n let leftElement = array[left];\n let rightElement = array[right];\n switch (compare(leftElement, rightElement)) {\n case (#less or #equal) {\n scratchSpace[nextSorted] := leftElement;\n left += 1\n };\n case (#greater) {\n scratchSpace[nextSorted] := rightElement;\n right += 1\n }\n };\n nextSorted += 1\n };\n while (left < mid + 1) {\n scratchSpace[nextSorted] := array[left];\n nextSorted += 1;\n left += 1\n };\n while (right < rightEnd + 1) {\n scratchSpace[nextSorted] := array[right];\n nextSorted += 1;\n right += 1\n };\n\n // Copy over merged elements\n var i = leftStart;\n while (i < rightEnd + 1) {\n array[i] := scratchSpace[i];\n i += 1\n };\n\n leftStart += 2 * currSize\n };\n currSize *= 2\n }\n };\n\n /// Creates a new mutable array by reversing the order of elements in `array`.\n /// The original array is not modified.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 10, 11, 12];\n /// let reversed = VarArray.reverse(array);\n /// assert VarArray.equal(reversed, [var 12, 11, 10], Nat.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func reverse<T>(array : [var T]) : [var T] {\n let size = array.size();\n tabulate<T>(size, func i = array[size - i - 1])\n };\n\n /// Reverses the order of elements in a mutable array in place.\n /// This modifies the original array.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 10, 11, 12];\n /// VarArray.reverseInPlace(array);\n /// assert VarArray.equal(array, [var 12, 11, 10], Nat.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func reverseInPlace<T>(array : [var T]) : () {\n let size = array.size();\n if (size == 0) {\n return\n };\n var i = 0;\n var j = (size - 1) : Nat;\n while (i < j) {\n let temp = array[i];\n array[i] := array[j];\n array[j] := temp;\n i += 1;\n j -= 1\n }\n };\n\n /// Calls `f` with each element in `array`.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n /// var sum = 0;\n /// let array = [var 0, 1, 2, 3];\n /// VarArray.forEach<Nat>(array, func(x) {\n /// sum += x;\n /// });\n /// assert sum == 6;\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func forEach<T>(array : [var T], f : T -> ()) {\n for (item in array.vals()) {\n f(item)\n }\n };\n\n /// Creates a new mutable array by applying `f` to each element in `array`. `f` \"maps\"\n /// each element it is applied to of type `T` to an element of type `R`.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 0, 1, 2, 3];\n /// let array2 = VarArray.map<Nat, Nat>(array, func x = x * 2);\n /// assert VarArray.equal(array2, [var 0, 2, 4, 6], Nat.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<T, R>(array : [var T], f : T -> R) : [var R] {\n tabulate<R>(\n array.size(),\n func(index) {\n f(array[index])\n }\n )\n };\n\n /// Applies `f` to each element of `array` in place,\n /// retaining the original ordering of elements.\n /// This modifies the original array.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 0, 1, 2, 3];\n /// VarArray.mapInPlace<Nat>(array, func x = x * 3);\n /// assert VarArray.equal(array, [var 0, 3, 6, 9], Nat.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapInPlace<T>(array : [var T], f : T -> T) {\n var index = 0;\n let size = array.size();\n while (index < size) {\n array[index] := f(array[index]);\n index += 1\n }\n };\n\n /// Creates a new mutable array by applying `predicate` to every element\n /// in `array`, retaining the elements for which `predicate` returns true.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 4, 2, 6, 1, 5];\n /// let evenElements = VarArray.filter<Nat>(array, func x = x % 2 == 0);\n /// assert VarArray.equal(evenElements, [var 4, 2, 6], Nat.equal);\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func filter<T>(array : [var T], f : T -> Bool) : [var T] {\n var count = 0;\n let keep = Prim.Array_tabulate<Bool>(\n array.size(),\n func i {\n if (f(array[i])) {\n count += 1;\n true\n } else {\n false\n }\n }\n );\n var nextKeep = 0;\n tabulate<T>(\n count,\n func _ {\n while (not keep[nextKeep]) {\n nextKeep += 1\n };\n nextKeep += 1;\n array[nextKeep - 1]\n }\n )\n };\n\n /// Creates a new mutable array by applying `f` to each element in `array`,\n /// and keeping all non-null elements. The ordering is retained.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// let array = [var 4, 2, 0, 1];\n /// let newArray =\n /// VarArray.filterMap<Nat, Text>( // mapping from Nat to Text values\n /// array,\n /// func x = if (x == 0) { null } else { ?Nat.toText(100 / x) } // can't divide by 0, so return null\n /// );\n /// assert VarArray.equal(newArray, [var \"25\", \"50\", \"100\"], Text.equal);\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func filterMap<T, R>(array : [var T], f : T -> ?R) : [var R] {\n var count = 0;\n let options = Prim.Array_tabulate<?R>(\n array.size(),\n func i {\n let result = f(array[i]);\n switch (result) {\n case (?element) {\n count += 1;\n result\n };\n case null {\n null\n }\n }\n }\n );\n\n var nextSome = 0;\n tabulate<R>(\n count,\n func _ {\n while (Option.isNull(options[nextSome])) {\n nextSome += 1\n };\n nextSome += 1;\n switch (options[nextSome - 1]) {\n case (?element) element;\n case null {\n Prim.trap \"VarArray.filterMap(): malformed array\"\n }\n }\n }\n )\n };\n\n /// Creates a new mutable array by applying `f` to each element in `array`.\n /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n /// returns an `#ok` containing the new array.\n ///\n /// ```motoko include=import\n /// import Result \"mo:core/Result\";\n ///\n /// let array = [var 4, 3, 2, 1, 0];\n /// // divide 100 by every element in the array\n /// let result = VarArray.mapResult<Nat, Nat, Text>(array, func x {\n /// if (x > 0) {\n /// #ok(100 / x)\n /// } else {\n /// #err \"Cannot divide by zero\"\n /// }\n /// });\n /// assert Result.isErr(result);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapResult<T, R, E>(array : [var T], f : T -> Result.Result<R, E>) : Result.Result<[var R], E> {\n let size = array.size();\n\n var error : ?Result.Result<[var R], E> = null;\n let results = tabulate<?R>(\n size,\n func i {\n switch (f(array[i])) {\n case (#ok element) {\n ?element\n };\n case (#err e) {\n switch (error) {\n case null {\n // only take the first error\n error := ?(#err e)\n };\n case _ {}\n };\n null\n }\n }\n }\n );\n\n switch error {\n case null {\n // unpack the option\n #ok(\n map<?R, R>(\n results,\n func element {\n switch element {\n case (?element) {\n element\n };\n case null {\n Prim.trap \"VarArray.mapResults(): malformed array\"\n }\n }\n }\n )\n )\n };\n case (?error) {\n error\n }\n }\n };\n\n /// Creates a new array by applying `f` to each element in `array` and its index.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 10, 10, 10, 10];\n /// let newArray = VarArray.mapEntries<Nat, Nat>(array, func (x, i) = i * x);\n /// assert VarArray.equal(newArray, [var 0, 10, 20, 30], Nat.equal);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapEntries<T, R>(array : [var T], f : (T, Nat) -> R) : [var R] {\n tabulate<R>(array.size(), func i = f(array[i], i))\n };\n\n /// Creates a new mutable array by applying `k` to each element in `array`,\n /// and concatenating the resulting arrays in order.\n ///\n /// ```motoko include=import\n /// import Int \"mo:core/Int\"\n ///\n /// let array = [var 1, 2, 3, 4];\n /// let newArray = VarArray.flatMap<Nat, Int>(array, func x = [x, -x].vals());\n /// assert VarArray.equal(newArray, [var 1, -1, 2, -2, 3, -3, 4, -4], Int.equal);\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `k` runs in O(1) time and space.\n public func flatMap<T, R>(array : [var T], k : T -> Types.Iter<R>) : [var R] {\n var flatSize = 0;\n let arrays = Prim.Array_tabulate<[var R]>(\n array.size(),\n func i {\n let subArray = fromIter<R>(k(array[i])); // TODO: optimize\n flatSize += subArray.size();\n subArray\n }\n );\n\n // could replace with a call to flatten,\n // but it would require an extra pass (to compute `flatSize`)\n var outer = 0;\n var inner = 0;\n tabulate<R>(\n flatSize,\n func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n }\n )\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// ```motoko include=import\n /// import {add} \"mo:core/Nat\";\n ///\n /// let array = [var 4, 2, 0, 1];\n /// let sum =\n /// VarArray.foldLeft<Nat, Nat>(\n /// array,\n /// 0, // start the sum at 0\n /// func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!\n /// );\n /// assert sum == 7;\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldLeft<T, A>(array : [var T], base : A, combine : (A, T) -> A) : A {\n var acc = base;\n for (element in array.vals()) {\n acc := combine(acc, element)\n };\n acc\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:core/Nat\";\n ///\n /// let array = [var 1, 9, 4, 8];\n /// let bookTitle = VarArray.foldRight<Nat, Text>(array, \"\", func(x, acc) = toText(x) # acc);\n /// assert bookTitle == \"1948\";\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldRight<T, A>(array : [var T], base : A, combine : (T, A) -> A) : A {\n var acc = base;\n let size = array.size();\n var i = size;\n while (i > 0) {\n i -= 1;\n acc := combine(array[i], acc)\n };\n acc\n };\n\n /// Combines an iterator of mutable arrays into a single mutable array.\n /// Retains the original ordering of the elements.\n ///\n /// Consider using `VarArray.flatten()` for better performance.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let arrays : [[var Nat]] = [[var 0, 1, 2], [var 2, 3], [var], [var 4]];\n /// let joinedArray = VarArray.join<Nat>(arrays.vals());\n /// assert VarArray.equal(joinedArray, [var 0, 1, 2, 2, 3, 4], Nat.equal);\n /// ```\n ///\n /// Runtime: O(number of elements in array)\n ///\n /// Space: O(number of elements in array)\n public func join<T>(arrays : Types.Iter<[var T]>) : [var T] {\n flatten<T>(fromIter(arrays))\n };\n\n /// Combines a mutable array of mutable arrays into a single mutable array. Retains the original\n /// ordering of the elements.\n ///\n /// This has better performance compared to `VarArray.join()`.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let arrays : [var [var Nat]] = [var [var 0, 1, 2], [var 2, 3], [var], [var 4]];\n /// let flatArray = VarArray.flatten<Nat>(arrays);\n /// assert VarArray.equal(flatArray, [var 0, 1, 2, 2, 3, 4], Nat.equal);\n /// ```\n ///\n /// Runtime: O(number of elements in array)\n ///\n /// Space: O(number of elements in array)\n public func flatten<T>(arrays : [var [var T]]) : [var T] {\n var flatSize = 0;\n for (subArray in arrays.vals()) {\n flatSize += subArray.size()\n };\n\n var outer = 0;\n var inner = 0;\n tabulate<T>(\n flatSize,\n func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n }\n )\n };\n\n /// Create an array containing a single value.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = VarArray.singleton<Nat>(2);\n /// assert VarArray.equal(array, [var 2], Nat.equal);\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func singleton<T>(element : T) : [var T] = [var element];\n\n /// Returns the size of a mutable array. Equivalent to `array.size()`.\n public func size<T>(array : [var T]) : Nat = array.size();\n\n /// Returns whether a mutable array is empty, i.e. contains zero elements.\n public func isEmpty<T>(array : [var T]) : Bool = array.size() == 0;\n\n /// Converts an iterator to a mutable array.\n public func fromIter<T>(iter : Types.Iter<T>) : [var T] {\n var list : Types.Pure.List<T> = null;\n var size = 0;\n label l loop {\n switch (iter.next()) {\n case (?element) {\n list := ?(element, list);\n size += 1\n };\n case null { break l }\n }\n };\n if (size == 0) { return [var] };\n let array = Prim.Array_init<T>(\n size,\n switch list {\n case (?(h, _)) h;\n case null {\n Prim.trap(\"VarArray.fromIter(): unreachable\")\n }\n }\n );\n var i = size;\n while (i > 0) {\n i -= 1;\n switch list {\n case (?(h, t)) {\n array[i] := h;\n list := t\n };\n case null {\n Prim.trap(\"VarArray.fromIter(): unreachable\")\n }\n }\n };\n array\n };\n\n /// Returns an iterator (`Iter`) over the indices of `array`.\n /// An iterator provides a single method `next()`, which returns\n /// indices in order, or `null` when out of index to iterate over.\n ///\n /// NOTE: You can also use `array.keys()` instead of this function. See example\n /// below.\n ///\n /// ```motoko include=import\n /// let array = [var 10, 11, 12];\n ///\n /// var sum = 0;\n /// for (element in array.keys()) {\n /// sum += element;\n /// };\n /// assert sum == 3; // 0 + 1 + 2\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func keys<T>(array : [var T]) : Types.Iter<Nat> = array.keys();\n\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n ///\n /// Note: You can also use `array.values()` instead of this function. See example\n /// below.\n ///\n /// ```motoko include=import\n /// let array = [var 10, 11, 12];\n ///\n /// var sum = 0;\n /// for (element in array.values()) {\n /// sum += element;\n /// };\n /// assert sum == 33; // 10 + 11 + 12\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func values<T>(array : [var T]) : Types.Iter<T> = array.vals();\n\n /// Returns an iterator that provides pairs of (index, element) in order, or `null`\n /// when out of elements to iterate over.\n ///\n /// ```motoko include=import\n /// let array = [var 10, 11, 12];\n ///\n /// var sum = 0;\n /// for ((index, element) in VarArray.enumerate(array)) {\n /// sum += element;\n /// };\n /// assert sum == 33;\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func enumerate<T>(array : [var T]) : Types.Iter<(Nat, T)> = object {\n let size = array.size();\n var index = 0;\n public func next() : ?(Nat, T) {\n if (index >= size) {\n return null\n };\n let i = index;\n index += 1;\n ?(i, array[i])\n }\n };\n\n /// Returns true if all elements in `array` satisfy the predicate function.\n ///\n /// ```motoko include=import\n /// let array = [var 1, 2, 3, 4];\n /// assert VarArray.all<Nat>(array, func x = x > 0);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func all<T>(array : [var T], predicate : T -> Bool) : Bool {\n for (element in array.vals()) {\n if (not predicate(element)) {\n return false\n }\n };\n true\n };\n\n /// Returns true if any element in `array` satisfies the predicate function.\n ///\n /// ```motoko include=import\n /// let array = [var 1, 2, 3, 4];\n /// assert VarArray.any<Nat>(array, func x = x > 3);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func any<T>(array : [var T], predicate : T -> Bool) : Bool {\n for (element in array.vals()) {\n if (predicate(element)) {\n return true\n }\n };\n false\n };\n\n /// Returns the index of the first `element` in the `array`.\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n ///\n /// let array = [var 'c', 'o', 'f', 'f', 'e', 'e'];\n /// assert VarArray.indexOf<Char>('c', array, Char.equal) == ?0;\n /// assert VarArray.indexOf<Char>('f', array, Char.equal) == ?2;\n /// assert VarArray.indexOf<Char>('g', array, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size())\n ///\n /// Space: O(1)\n public func indexOf<T>(element : T, array : [var T], equal : (T, T) -> Bool) : ?Nat = nextIndexOf<T>(element, array, 0, equal);\n\n /// Returns the index of the next occurence of `element` in the `array` starting from the `from` index (inclusive).\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n ///\n /// let array = [var 'c', 'o', 'f', 'f', 'e', 'e'];\n /// assert VarArray.nextIndexOf<Char>('c', array, 0, Char.equal) == ?0;\n /// assert VarArray.nextIndexOf<Char>('f', array, 0, Char.equal) == ?2;\n /// assert VarArray.nextIndexOf<Char>('f', array, 2, Char.equal) == ?2;\n /// assert VarArray.nextIndexOf<Char>('f', array, 3, Char.equal) == ?3;\n /// assert VarArray.nextIndexOf<Char>('f', array, 4, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size())\n ///\n /// Space: O(1)\n public func nextIndexOf<T>(element : T, array : [var T], fromInclusive : Nat, equal : (T, T) -> Bool) : ?Nat {\n var index = fromInclusive;\n let size = array.size();\n while (index < size) {\n if (equal(array[index], element)) {\n return ?index\n } else {\n index += 1\n }\n };\n null\n };\n\n /// Returns the index of the last `element` in the `array`.\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n ///\n /// let array = [var 'c', 'o', 'f', 'f', 'e', 'e'];\n /// assert VarArray.lastIndexOf<Char>('c', array, Char.equal) == ?0;\n /// assert VarArray.lastIndexOf<Char>('f', array, Char.equal) == ?3;\n /// assert VarArray.lastIndexOf<Char>('e', array, Char.equal) == ?5;\n /// assert VarArray.lastIndexOf<Char>('g', array, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size())\n ///\n /// Space: O(1)\n public func lastIndexOf<T>(element : T, array : [var T], equal : (T, T) -> Bool) : ?Nat = prevIndexOf<T>(element, array, array.size(), equal);\n\n /// Returns the index of the previous occurence of `element` in the `array` starting from the `from` index (exclusive).\n ///\n /// ```motoko include=import\n /// import Char \"mo:core/Char\";\n /// let array = [var 'c', 'o', 'f', 'f', 'e', 'e'];\n /// assert VarArray.prevIndexOf<Char>('c', array, array.size(), Char.equal) == ?0;\n /// assert VarArray.prevIndexOf<Char>('e', array, array.size(), Char.equal) == ?5;\n /// assert VarArray.prevIndexOf<Char>('e', array, 5, Char.equal) == ?4;\n /// assert VarArray.prevIndexOf<Char>('e', array, 4, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size());\n /// Space: O(1);\n public func prevIndexOf<T>(element : T, array : [var T], fromExclusive : Nat, equal : (T, T) -> Bool) : ?Nat {\n var i = fromExclusive;\n while (i > 0) {\n i -= 1;\n if (equal(array[i], element)) {\n return ?i\n }\n };\n null\n };\n\n /// Returns an iterator over a slice of `array` starting at `fromInclusive` up to (but not including) `toExclusive`.\n ///\n /// Negative indices are relative to the end of the array. For example, `-1` corresponds to the last element in the array.\n ///\n /// If the indices are out of bounds, they are clamped to the array bounds.\n /// If the first index is greater than the second, the function returns an empty iterator.\n ///\n /// ```motoko include=import\n /// let array = [var 1, 2, 3, 4, 5];\n /// let iter1 = VarArray.range<Nat>(array, 3, array.size());\n /// assert iter1.next() == ?4;\n /// assert iter1.next() == ?5;\n /// assert iter1.next() == null;\n ///\n /// let iter2 = VarArray.range<Nat>(array, 3, -1);\n /// assert iter2.next() == ?4;\n /// assert iter2.next() == null;\n ///\n /// let iter3 = VarArray.range<Nat>(array, 0, 0);\n /// assert iter3.next() == null;\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func range<T>(array : [var T], fromInclusive : Int, toExclusive : Int) : Types.Iter<T> {\n let size = array.size();\n // Convert negative indices to positive and handle bounds\n let startInt = if (fromInclusive < 0) {\n let s = size + fromInclusive;\n if (s < 0) { 0 } else { s }\n } else {\n if (fromInclusive > size) { size } else { fromInclusive }\n };\n let endInt = if (toExclusive < 0) {\n let e = size + toExclusive;\n if (e < 0) { 0 } else { e }\n } else {\n if (toExclusive > size) { size } else { toExclusive }\n };\n // Convert to Nat (values are non-negative due to bounds checking above)\n let start = Prim.abs(startInt);\n let end = Prim.abs(endInt);\n object {\n var pos = start;\n public func next() : ?T {\n if (pos >= end) {\n null\n } else {\n let elem = array[pos];\n pos += 1;\n ?elem\n }\n }\n }\n };\n\n /// Returns a new array containing elements from `array` starting at index `fromInclusive` up to (but not including) index `toExclusive`.\n /// If the indices are out of bounds, they are clamped to the array bounds.\n ///\n /// ```motoko include=import\n /// let array = [var 1, 2, 3, 4, 5];\n ///\n /// let slice1 = VarArray.sliceToArray<Nat>(array, 1, 4);\n /// assert slice1 == [2, 3, 4];\n ///\n /// let slice2 = VarArray.sliceToArray<Nat>(array, 1, -1);\n /// assert slice2 == [2, 3, 4];\n /// ```\n ///\n /// Runtime: O(toExclusive - fromInclusive)\n ///\n /// Space: O(toExclusive - fromInclusive)\n public func sliceToArray<T>(array : [var T], fromInclusive : Int, toExclusive : Int) : [T] {\n let size = array.size();\n // Convert negative indices to positive and handle bounds\n let startInt = if (fromInclusive < 0) {\n let s = size + fromInclusive;\n if (s < 0) { 0 } else { s }\n } else {\n if (fromInclusive > size) { size } else { fromInclusive }\n };\n let endInt = if (toExclusive < 0) {\n let e = size + toExclusive;\n if (e < 0) { 0 } else { e }\n } else {\n if (toExclusive > size) { size } else { toExclusive }\n };\n // Convert to Nat (always non-negative due to bounds checking above)\n let start = Prim.abs(startInt);\n let end = Prim.abs(endInt);\n Prim.Array_tabulate<T>(end - start, func i = array[start + i])\n };\n\n /// Converts the mutable array to its textual representation using `f` to convert each element to `Text`.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let array = [var 1, 2, 3];\n /// assert VarArray.toText<Nat>(array, Nat.toText) == \"[var 1, 2, 3]\";\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func toText<T>(array : [var T], f : T -> Text) : Text {\n let size = array.size();\n if (size == 0) { return \"[var]\" };\n var text = \"[var \";\n var i = 0;\n while (i < size) {\n if (i != 0) {\n text #= \", \"\n };\n text #= f(array[i]);\n i += 1\n };\n text #= \"]\";\n text\n };\n\n /// Compares two mutable arrays using the provided comparison function for elements.\n /// Returns #less, #equal, or #greater if `array1` is less than, equal to,\n /// or greater than `array2` respectively.\n ///\n /// If arrays have different sizes but all elements up to the shorter length are equal,\n /// the shorter array is considered #less than the longer array.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// let array1 = [var 1, 2, 3];\n /// let array2 = [var 1, 2, 4];\n /// assert VarArray.compare<Nat>(array1, array2, Nat.compare) == #less;\n ///\n /// let array3 = [var 1, 2];\n /// let array4 = [var 1, 2, 3];\n /// assert VarArray.compare<Nat>(array3, array4, Nat.compare) == #less;\n /// ```\n ///\n /// Runtime: O(min(size1, size2))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func compare<T>(array1 : [var T], array2 : [var T], compare : (T, T) -> Order.Order) : Order.Order {\n let size1 = array1.size();\n let size2 = array2.size();\n var i = 0;\n let minSize = if (size1 < size2) { size1 } else { size2 };\n while (i < minSize) {\n switch (compare(array1[i], array2[i])) {\n case (#less) { return #less };\n case (#greater) { return #greater };\n case (#equal) { i += 1 }\n }\n };\n if (size1 < size2) { #less } else if (size1 > size2) { #greater } else {\n #equal\n }\n };\n\n}\n"},"List.mo":{"content":"/// A mutable list data structure with efficient random access and dynamic resizing.\n/// Provides O(1) access time and O(sqrt(n)) memory overhead.\n/// Can be declared `stable` for orthogonal persistence.\n///\n/// This implementation is adapted with permission from the `vector` Mops package created by Research AG.\n///\n/// Copyright: 2023 MR Research AG\n/// Main author: Andrii Stepanov\n/// Contributors: Timo Hanke (timohanke), Andy Gura (andygura), react0r-com\n///\n/// ```motoko name=import\n/// import List \"mo:core/List\";\n/// ```\n\nimport PureList \"pure/List\";\nimport Prim \"mo:⛔\";\nimport Nat32 \"Nat32\";\nimport Array \"Array\";\nimport Iter \"Iter\";\nimport Nat \"Nat\";\nimport Order \"Order\";\nimport Option \"Option\";\nimport VarArray \"VarArray\";\nimport Types \"Types\";\n\nmodule {\n /// `List<T>` provides a mutable list of elements of type `T`.\n /// Based on the paper \"Resizable Arrays in Optimal Time and Space\" by Brodnik, Carlsson, Demaine, Munro and Sedgewick (1999).\n /// Since this is internally a two-dimensional array the access times for put and get operations\n /// will naturally be 2x slower than Buffer and Array. However, Array is not resizable and Buffer\n /// has `O(size)` memory waste.\n ///\n /// The maximum number of elements in a `List` is 2^32.\n public type List<T> = Types.List<T>;\n\n let INTERNAL_ERROR = \"List: internal error\";\n\n /// Creates a new empty List for elements of type T.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>(); // Creates a new List\n /// ```\n public func empty<T>() : List<T> = {\n var blocks = [var [var]];\n var blockIndex = 1;\n var elementIndex = 0\n };\n\n /// Returns a new list with capacity and size 1, containing `element`.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.singleton<Nat>(1);\n /// assert List.toText<Nat>(list, Nat.toText) == \"List[1]\";\n /// ```\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func singleton<T>(element : T) : List<T> = repeat(element, 1);\n\n /// Creates a new List with `size` copies of the initial value.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.repeat<Nat>(2, 4);\n /// assert List.toArray(list) == [2, 2, 2, 2];\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n public func repeat<T>(initValue : T, size : Nat) : List<T> {\n let (blockIndex, elementIndex) = locate(size);\n\n let blocks = new_index_block_length(Nat32.fromNat(if (elementIndex == 0) { blockIndex - 1 } else blockIndex));\n let data_blocks = VarArray.repeat<[var ?T]>([var], blocks);\n var i = 1;\n while (i < blockIndex) {\n data_blocks[i] := VarArray.repeat<?T>(?initValue, data_block_size(i));\n i += 1\n };\n if (elementIndex != 0 and blockIndex < blocks) {\n let block = VarArray.repeat<?T>(null, data_block_size(i));\n var j = 0;\n while (j < elementIndex) {\n block[j] := ?initValue;\n j += 1\n };\n data_blocks[i] := block\n };\n\n {\n var blocks = data_blocks;\n var blockIndex = blockIndex;\n var elementIndex = elementIndex\n }\n };\n\n /// Converts a mutable `List` to a purely functional `PureList`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.fromArray<Nat>([1, 2, 3]);\n /// let pureList = List.toPure<Nat>(list); // converts to immutable PureList\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n public func toPure<T>(list : List<T>) : PureList.List<T> {\n PureList.fromIter(values(list)) // TODO: optimize\n };\n\n /// Converts a purely functional `List` to a mutable `List`.\n ///\n /// Example:\n /// ```motoko include=import\n /// import PureList \"mo:core/pure/List\";\n ///\n /// let pureList = PureList.fromArray<Nat>([1, 2, 3]);\n /// let list = List.fromPure<Nat>(pureList); // converts to mutable List\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n public func fromPure<T>(pure : PureList.List<T>) : List<T> {\n let list = empty<T>();\n PureList.forEach<T>(pure, func(x) = add(list, x));\n list\n };\n\n /// Add to list `count` copies of the initial value.\n ///\n /// ```motoko include=import\n /// let list = List.repeat<Nat>(2, 4); // [2, 2, 2, 2]\n /// List.addRepeat(list, 2, 1); // [2, 2, 2, 2, 1, 1]\n /// ```\n ///\n /// The maximum number of elements in a `List` is 2^32.\n ///\n /// Runtime: `O(count)`\n public func addRepeat<T>(list : List<T>, initValue : T, count : Nat) {\n let (blockIndex, elementIndex) = locate(size(list) + count);\n let blocks = new_index_block_length(Nat32.fromNat(if (elementIndex == 0) { blockIndex - 1 } else blockIndex));\n\n let old_blocks = list.blocks.size();\n if (old_blocks < blocks) {\n let old_data_blocks = list.blocks;\n list.blocks := VarArray.repeat<[var ?T]>([var], blocks);\n var i = 0;\n while (i < old_blocks) {\n list.blocks[i] := old_data_blocks[i];\n i += 1\n }\n };\n\n var cnt = count;\n while (cnt > 0) {\n let db_size = data_block_size(list.blockIndex);\n if (list.elementIndex == 0 and db_size <= cnt) {\n list.blocks[list.blockIndex] := VarArray.repeat<?T>(?initValue, db_size);\n cnt -= db_size;\n list.blockIndex += 1\n } else {\n if (list.blocks[list.blockIndex].size() == 0) {\n list.blocks[list.blockIndex] := VarArray.repeat<?T>(null, db_size)\n };\n let from = list.elementIndex;\n let to = Nat.min(list.elementIndex + cnt, db_size);\n\n let block = list.blocks[list.blockIndex];\n var i = from;\n while (i < to) {\n block[i] := ?initValue;\n i += 1\n };\n\n list.elementIndex := to;\n if (list.elementIndex == db_size) {\n list.elementIndex := 0;\n list.blockIndex += 1\n };\n cnt -= to - from\n }\n }\n };\n\n /// Resets the list to size 0, de-referencing all elements.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.add(list, 11);\n /// List.add(list, 12);\n /// List.clear(list); // list is now empty\n /// assert List.toArray(list) == [];\n /// ```\n ///\n /// Runtime: `O(1)`\n public func clear<T>(list : List<T>) {\n list.blocks := [var [var]];\n list.blockIndex := 1;\n list.elementIndex := 0\n };\n\n /// Returns a copy of a List, with the same size.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 1);\n ///\n /// let clone = List.clone(list);\n /// assert List.toArray(clone) == [1];\n /// ```\n ///\n /// Runtime: `O(size)`\n public func clone<T>(list : List<T>) : List<T> = {\n var blocks = VarArray.tabulate<[var ?T]>(\n list.blocks.size(),\n func(i) = VarArray.tabulate<?T>(\n list.blocks[i].size(),\n func(j) = list.blocks[i][j]\n )\n );\n var blockIndex = list.blockIndex;\n var elementIndex = list.elementIndex\n };\n\n /// Creates a new list by applying the provided function to each element in the input list.\n /// The resulting list has the same size as the input list.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.singleton<Nat>(123);\n /// let textList = List.map<Nat, Text>(list, Nat.toText);\n /// assert List.toArray(textList) == [\"123\"];\n /// ```\n ///\n /// Runtime: `O(size)`\n public func map<T, R>(list : List<T>, f : T -> R) : List<R> = {\n var blocks = VarArray.tabulate<[var ?R]>(\n list.blocks.size(),\n func(i) {\n let db = list.blocks[i];\n VarArray.tabulate<?R>(\n db.size(),\n func(j) = switch (db[j]) {\n case (?item) ?f(item);\n case (null) null\n }\n )\n }\n );\n var blockIndex = list.blockIndex;\n var elementIndex = list.elementIndex\n };\n\n /// Returns a new list containing only the elements from `list` for which the predicate returns true.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.fromArray<Nat>([1, 2, 3, 4]);\n /// let evenNumbers = List.filter<Nat>(list, func x = x % 2 == 0);\n /// assert List.toArray(evenNumbers) == [2, 4];\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `predicate` runs in `O(1)` time and space.\n public func filter<T>(list : List<T>, predicate : T -> Bool) : List<T> {\n let filtered = empty<T>();\n forEach<T>(\n list,\n func(x) {\n if (predicate(x)) add(filtered, x)\n }\n );\n filtered\n };\n\n /// Returns a new list containing all elements from `list` for which the function returns ?element.\n /// Discards all elements for which the function returns null.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.fromArray<Nat>([1, 2, 3, 4]);\n /// let doubled = List.filterMap<Nat, Nat>(list, func x = if (x % 2 == 0) ?(x * 2) else null);\n /// assert List.toArray(doubled) == [4, 8];\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in `O(1)` time and space.\n public func filterMap<T, R>(list : List<T>, f : T -> ?R) : List<R> {\n let filtered = empty<R>();\n forEach<T>(\n list,\n func(x) {\n switch (f(x)) {\n case (?y) add(filtered, y);\n case null {}\n }\n }\n );\n filtered\n };\n\n /// Returns the current number of elements in the list.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// assert List.size(list) == 0\n /// ```\n ///\n /// Runtime: `O(1)` (with some internal calculations)\n public func size<T>(list : List<T>) : Nat {\n let d = Nat32.fromNat(list.blockIndex);\n let i = Nat32.fromNat(list.elementIndex);\n\n // We call all data blocks of the same capacity an \"epoch\". We number the epochs 0,1,2,...\n // A data block is in epoch e iff the data block has capacity 2 ** e.\n // Each epoch starting with epoch 1 spans exactly two super blocks.\n // Super block s falls in epoch ceil(s/2).\n\n // epoch of last data block\n // e = 32 - lz\n let lz = Nat32.bitcountLeadingZero(d / 3);\n\n // capacity of all prior epochs combined\n // capacity_before_e = 2 * 4 ** (e - 1) - 1\n\n // data blocks in all prior epochs combined\n // blocks_before_e = 3 * 2 ** (e - 1) - 2\n\n // then size = d * 2 ** e + i - c\n // where c = blocks_before_e * 2 ** e - capacity_before_e\n\n // there can be overflows, but the result is without overflows, so use addWrap and subWrap\n // we don't erase bits by >>, so to use <>> is ok\n Nat32.toNat((d -% (1 <>> lz)) <>> lz +% i)\n };\n\n func data_block_size(blockIndex : Nat) : Nat {\n // formula for the size of given blockIndex\n // don't call it for blockIndex == 0\n Nat32.toNat(1 <>> Nat32.bitcountLeadingZero(Nat32.fromNat(blockIndex) / 3))\n };\n\n func new_index_block_length(blockIndex : Nat32) : Nat {\n if (blockIndex <= 1) 2 else {\n let s = 30 - Nat32.bitcountLeadingZero(blockIndex);\n Nat32.toNat(((blockIndex >> s) +% 1) << s)\n }\n };\n\n func grow_index_block_if_needed<T>(list : List<T>) {\n if (list.blocks.size() == list.blockIndex) {\n let new_blocks = VarArray.repeat<[var ?T]>([var], new_index_block_length(Nat32.fromNat(list.blockIndex)));\n var i = 0;\n while (i < list.blockIndex) {\n new_blocks[i] := list.blocks[i];\n i += 1\n };\n list.blocks := new_blocks\n }\n };\n\n func shrink_index_block_if_needed<T>(list : List<T>) {\n let blockIndex = Nat32.fromNat(list.blockIndex);\n // kind of index of the first block in the super block\n if ((blockIndex << Nat32.bitcountLeadingZero(blockIndex)) << 2 == 0) {\n let new_length = new_index_block_length(blockIndex);\n if (new_length < list.blocks.size()) {\n let new_blocks = VarArray.repeat<[var ?T]>([var], new_length);\n var i = 0;\n while (i < new_length) {\n new_blocks[i] := list.blocks[i];\n i += 1\n };\n list.blocks := new_blocks\n }\n }\n };\n\n /// Adds a single element to the end of a List,\n /// allocating a new internal data block if needed,\n /// and resizing the internal index block if needed.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 0); // add 0 to list\n /// List.add(list, 1);\n /// List.add(list, 2);\n /// List.add(list, 3);\n /// assert List.toArray(list) == [0, 1, 2, 3];\n /// ```\n ///\n /// The maximum number of elements in a `List` is 2^32.\n ///\n /// Amortized Runtime: `O(1)`, Worst Case Runtime: `O(sqrt(n))`\n public func add<T>(list : List<T>, element : T) {\n var elementIndex = list.elementIndex;\n if (elementIndex == 0) {\n grow_index_block_if_needed(list);\n let blockIndex = list.blockIndex;\n\n // When removing last we keep one more data block, so can be not empty\n if (list.blocks[blockIndex].size() == 0) {\n list.blocks[blockIndex] := VarArray.repeat<?T>(\n null,\n data_block_size(blockIndex)\n )\n }\n };\n\n let last_data_block = list.blocks[list.blockIndex];\n\n last_data_block[elementIndex] := ?element;\n\n elementIndex += 1;\n if (elementIndex == last_data_block.size()) {\n elementIndex := 0;\n list.blockIndex += 1\n };\n list.elementIndex := elementIndex\n };\n\n /// Removes and returns the last item in the list or `null` if\n /// the list is empty.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.add(list, 11);\n /// assert List.removeLast(list) == ?11;\n /// assert List.removeLast(list) == ?10;\n /// assert List.removeLast(list) == null;\n /// ```\n ///\n /// Amortized Runtime: `O(1)`, Worst Case Runtime: `O(sqrt(n))`\n ///\n /// Amortized Space: `O(1)`, Worst Case Space: `O(sqrt(n))`\n public func removeLast<T>(list : List<T>) : ?T {\n var elementIndex = list.elementIndex;\n if (elementIndex == 0) {\n shrink_index_block_if_needed(list);\n\n var blockIndex = list.blockIndex;\n if (blockIndex == 1) {\n return null\n };\n blockIndex -= 1;\n elementIndex := list.blocks[blockIndex].size();\n\n // Keep one totally empty block when removing\n if (blockIndex + 2 < list.blocks.size()) {\n if (list.blocks[blockIndex + 2].size() == 0) {\n list.blocks[blockIndex + 2] := [var]\n }\n };\n list.blockIndex := blockIndex\n };\n elementIndex -= 1;\n\n var last_data_block = list.blocks[list.blockIndex];\n\n let element = last_data_block[elementIndex];\n last_data_block[elementIndex] := null;\n\n list.elementIndex := elementIndex;\n return element\n };\n\n func locate(index : Nat) : (Nat, Nat) {\n // see comments in tests\n let i = Nat32.fromNat(index);\n let lz = Nat32.bitcountLeadingZero(i);\n let lz2 = lz >> 1;\n if (lz & 1 == 0) {\n (Nat32.toNat(((i << lz2) >> 16) ^ (0x10000 >> lz2)), Nat32.toNat(i & (0xFFFF >> lz2)))\n } else {\n (Nat32.toNat(((i << lz2) >> 15) ^ (0x18000 >> lz2)), Nat32.toNat(i & (0x7FFF >> lz2)))\n }\n };\n\n /// Returns the element at index `index`. Indexing is zero-based.\n /// Traps if `index >= size`, error message may not be descriptive.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.add(list, 11);\n /// assert List.get(list, 0) == 10;\n /// ```\n ///\n /// Runtime: `O(1)`\n public func get<T>(list : List<T>, index : Nat) : T {\n // inlined version of:\n // let (a,b) = locate(index);\n // switch(list.blocks[a][b]) {\n // case (?element) element;\n // case (null) Prim.trap \"\";\n // };\n let i = Nat32.fromNat(index);\n let lz = Nat32.bitcountLeadingZero(i);\n let lz2 = lz >> 1;\n switch (\n if (lz & 1 == 0) {\n list.blocks[Nat32.toNat(((i << lz2) >> 16) ^ (0x10000 >> lz2))][Nat32.toNat(i & (0xFFFF >> lz2))]\n } else {\n list.blocks[Nat32.toNat(((i << lz2) >> 15) ^ (0x18000 >> lz2))][Nat32.toNat(i & (0x7FFF >> lz2))]\n }\n ) {\n case (?result) return result;\n case (_) Prim.trap \"List index out of bounds in get\"\n }\n };\n\n /// Returns the element at index `index` as an option.\n /// Returns `null` when `index >= size`. Indexing is zero-based.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.add(list, 11);\n /// assert List.getOpt(list, 0) == ?10;\n /// assert List.getOpt(list, 2) == null;\n /// ```\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func getOpt<T>(list : List<T>, index : Nat) : ?T {\n let (a, b) = locate(index);\n if (a < list.blockIndex or list.elementIndex != 0 and a == list.blockIndex) {\n list.blocks[a][b]\n } else {\n null\n }\n };\n\n /// Overwrites the current element at `index` with `element`.\n /// Traps if `index` >= size. Indexing is zero-based.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.put(list, 0, 20); // overwrites 10 at index 0 with 20\n /// assert List.toArray(list) == [20];\n /// ```\n ///\n /// Runtime: `O(1)`\n public func put<T>(list : List<T>, index : Nat, value : T) {\n let (a, b) = locate(index);\n if (a < list.blockIndex or a == list.blockIndex and b < list.elementIndex) {\n list.blocks[a][b] := ?value\n } else Prim.trap \"List index out of bounds in put\"\n };\n\n /// Sorts the elements in the list according to `compare`.\n /// Sort is deterministic, stable, and in-place.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.empty<Nat>();\n /// List.add(list, 3);\n /// List.add(list, 1);\n /// List.add(list, 2);\n /// List.sort(list, Nat.compare);\n /// assert List.toArray(list) == [1, 2, 3];\n /// ```\n ///\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func sort<T>(list : List<T>, compare : (T, T) -> Order.Order) {\n if (size(list) < 2) return;\n let arr = toVarArray(list);\n VarArray.sortInPlace(arr, compare);\n for (i in arr.keys()) {\n put(list, i, arr[i])\n }\n };\n\n /// Finds the first index of `element` in `list` using equality of elements defined\n /// by `equal`. Returns `null` if `element` is not found.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.empty<Nat>();\n /// List.add(list, 1);\n /// List.add(list, 2);\n /// List.add(list, 3);\n /// List.add(list, 4);\n ///\n /// assert List.indexOf<Nat>(list, Nat.equal, 3) == ?2;\n /// assert List.indexOf<Nat>(list, Nat.equal, 5) == null;\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// *Runtime and space assumes that `equal` runs in `O(1)` time and space.\n public func indexOf<T>(list : List<T>, equal : (T, T) -> Bool, element : T) : ?Nat {\n // inlining would save 10 instructions per entry\n findIndex<T>(list, func(x) = equal(element, x))\n };\n\n /// Finds the last index of `element` in `list` using equality of elements defined\n /// by `equal`. Returns `null` if `element` is not found.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.fromArray<Nat>([1, 2, 3, 4, 2, 2]);\n ///\n /// assert List.lastIndexOf<Nat>(list, Nat.equal, 2) == ?5;\n /// assert List.lastIndexOf<Nat>(list, Nat.equal, 5) == null;\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// *Runtime and space assumes that `equal` runs in `O(1)` time and space.\n public func lastIndexOf<T>(list : List<T>, equal : (T, T) -> Bool, element : T) : ?Nat {\n // inlining would save 10 instructions per entry\n findLastIndex<T>(list, func(x) = equal(element, x))\n };\n\n /// Returns the first value in `list` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let list = List.fromArray<Nat>([1, 9, 4, 8]);\n /// let found = List.find<Nat>(list, func(x) { x > 8 });\n /// assert found == ?9;\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func find<T>(list : List<T>, predicate : T -> Bool) : ?T {\n for (element in values(list)) {\n if (predicate element) {\n return ?element\n }\n };\n null\n };\n\n /// Finds the index of the first element in `list` for which `predicate` is true.\n /// Returns `null` if no such element is found.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 1);\n /// List.add(list, 2);\n /// List.add(list, 3);\n /// List.add(list, 4);\n ///\n /// assert List.findIndex<Nat>(list, func(i) { i % 2 == 0 }) == ?1;\n /// assert List.findIndex<Nat>(list, func(i) { i > 5 }) == null;\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// *Runtime and space assumes that `predicate` runs in `O(1)` time and space.\n public func findIndex<T>(list : List<T>, predicate : T -> Bool) : ?Nat {\n let blocks = list.blocks.size();\n var blockIndex = 0;\n var elementIndex = 0;\n var size = 0;\n var db : [var ?T] = [var];\n var i = 0;\n\n loop {\n if (elementIndex == size) {\n blockIndex += 1;\n if (blockIndex >= blocks) return null;\n db := list.blocks[blockIndex];\n size := db.size();\n if (size == 0) return null;\n elementIndex := 0\n };\n switch (db[elementIndex]) {\n case (?x) if (predicate(x)) return ?i;\n case (_) return null\n };\n elementIndex += 1;\n i += 1\n }\n };\n\n /// Finds the index of the last element in `list` for which `predicate` is true.\n /// Returns `null` if no such element is found.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 1);\n /// List.add(list, 2);\n /// List.add(list, 3);\n /// List.add(list, 4);\n ///\n /// assert List.findLastIndex<Nat>(list, func(i) { i % 2 == 0 }) == ?3;\n /// assert List.findLastIndex<Nat>(list, func(i) { i > 5 }) == null;\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// *Runtime and space assumes that `predicate` runs in `O(1)` time and space.\n public func findLastIndex<T>(list : List<T>, predicate : T -> Bool) : ?Nat {\n var i = size(list);\n var blockIndex = list.blockIndex;\n var elementIndex = list.elementIndex;\n var db : [var ?T] = if (blockIndex < list.blocks.size()) {\n list.blocks[blockIndex]\n } else { [var] };\n\n loop {\n if (blockIndex == 1) {\n return null\n };\n if (elementIndex == 0) {\n blockIndex -= 1;\n db := list.blocks[blockIndex];\n elementIndex := db.size() - 1\n } else {\n elementIndex -= 1\n };\n switch (db[elementIndex]) {\n case (?x) {\n i -= 1;\n if (predicate(x)) return ?i\n };\n case (_) Prim.trap(INTERNAL_ERROR)\n }\n }\n };\n\n /// Returns true iff every element in `list` satisfies `predicate`.\n /// In particular, if `list` is empty the function returns `true`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 2);\n /// List.add(list, 3);\n /// List.add(list, 4);\n ///\n /// assert List.all<Nat>(list, func x { x > 1 });\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func all<T>(list : List<T>, predicate : T -> Bool) : Bool {\n not any<T>(list, func(x) : Bool = not predicate(x))\n };\n\n /// Returns true iff some element in `list` satisfies `predicate`.\n /// In particular, if `list` is empty the function returns `false`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 2);\n /// List.add(list, 3);\n /// List.add(list, 4);\n ///\n /// assert List.any<Nat>(list, func x { x > 3 });\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func any<T>(list : List<T>, predicate : T -> Bool) : Bool {\n switch (findIndex(list, predicate)) {\n case (null) false;\n case (_) true\n }\n };\n\n /// Returns an Iterator (`Iter`) over the elements of a List.\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n ///\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.add(list, 11);\n /// List.add(list, 12);\n ///\n /// var sum = 0;\n /// for (element in List.values(list)) {\n /// sum += element;\n /// };\n /// assert sum == 33;\n /// ```\n ///\n /// Note: This does not create a snapshot. If the returned iterator is not consumed at once,\n /// and instead the consumption of the iterator is interleaved with other operations on the\n /// List, then this may lead to unexpected results.\n ///\n /// Runtime: `O(1)`\n public func values<T>(list : List<T>) : Iter.Iter<T> = values_(list);\n\n /// Returns an Iterator (`Iter`) over the items (index-value pairs) in the list.\n /// Each item is a tuple of `(index, value)`. The iterator provides a single method\n /// `next()` which returns elements in order, or `null` when out of elements.\n ///\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.add(list, 11);\n /// List.add(list, 12);\n /// assert Iter.toArray(List.enumerate(list)) == [(0, 10), (1, 11), (2, 12)];\n /// ```\n ///\n /// Note: This does not create a snapshot. If the returned iterator is not consumed at once,\n /// and instead the consumption of the iterator is interleaved with other operations on the\n /// List, then this may lead to unexpected results.\n ///\n /// Runtime: `O(1)`\n ///\n /// Warning: Allocates memory on the heap to store ?(Nat, T).\n public func enumerate<T>(list : List<T>) : Iter.Iter<(Nat, T)> = object {\n let blocks = list.blocks.size();\n var blockIndex = 0;\n var elementIndex = 0;\n var size = 0;\n var db : [var ?T] = [var];\n var i = 0;\n\n public func next() : ?(Nat, T) {\n if (elementIndex == size) {\n blockIndex += 1;\n if (blockIndex >= blocks) return null;\n db := list.blocks[blockIndex];\n size := db.size();\n if (size == 0) return null;\n elementIndex := 0\n };\n switch (db[elementIndex]) {\n case (?x) {\n let ret = ?(i, x);\n elementIndex += 1;\n i += 1;\n return ret\n };\n case (_) return null\n }\n }\n };\n\n /// Returns an Iterator (`Iter`) over the elements of the list in reverse order.\n /// The iterator provides a single method `next()` which returns elements from\n /// last to first, or `null` when out of elements.\n ///\n /// ```motoko include=import\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.add(list, 11);\n /// List.add(list, 12);\n ///\n /// var sum = 0;\n /// for (element in List.reverseValues(list)) {\n /// sum += element;\n /// };\n /// assert sum == 33;\n /// ```\n ///\n /// Note: This does not create a snapshot. If the returned iterator is not consumed at once,\n /// and instead the consumption of the iterator is interleaved with other operations on the\n /// List, then this may lead to unexpected results.\n ///\n /// Runtime: `O(1)`\n public func reverseValues<T>(list : List<T>) : Iter.Iter<T> = object {\n var blockIndex = list.blockIndex;\n var elementIndex = list.elementIndex;\n var db : [var ?T] = if (blockIndex < list.blocks.size()) {\n list.blocks[blockIndex]\n } else { [var] };\n\n public func next() : ?T {\n if (blockIndex == 1) {\n return null\n };\n if (elementIndex == 0) {\n blockIndex -= 1;\n db := list.blocks[blockIndex];\n elementIndex := db.size() - 1\n } else {\n elementIndex -= 1\n };\n\n db[elementIndex]\n }\n };\n\n /// Returns an Iterator (`Iter`) over the items in reverse order, i.e. pairs of index and value.\n /// Iterator provides a single method `next()`, which returns\n /// elements in reverse order, or `null` when out of elements to iterate over.\n ///\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let list = List.empty<Nat>();\n /// List.add(list, 10);\n /// List.add(list, 11);\n /// List.add(list, 12);\n /// assert Iter.toArray(List.reverseEnumerate(list)) == [(2, 12), (1, 11), (0, 10)];\n /// ```\n ///\n /// Note: This does not create a snapshot. If the returned iterator is not consumed at once,\n /// and instead the consumption of the iterator is interleaved with other operations on the\n /// List, then this may lead to unexpected results.\n ///\n /// Runtime: `O(1)`\n ///\n /// Warning: Allocates memory on the heap to store ?(T, Nat).\n public func reverseEnumerate<T>(list : List<T>) : Iter.Iter<(Nat, T)> = object {\n var i = size(list);\n var blockIndex = list.blockIndex;\n var elementIndex = list.elementIndex;\n var db : [var ?T] = if (blockIndex < list.blocks.size()) {\n list.blocks[blockIndex]\n } else { [var] };\n\n public func next() : ?(Nat, T) {\n if (blockIndex == 1) {\n return null\n };\n if (elementIndex == 0) {\n blockIndex -= 1;\n db := list.blocks[blockIndex];\n elementIndex := db.size() - 1\n } else {\n elementIndex -= 1\n };\n switch (db[elementIndex]) {\n case (?x) {\n i -= 1;\n return ?(i, x)\n };\n case (_) Prim.trap(INTERNAL_ERROR)\n }\n }\n };\n\n /// Returns an Iterator (`Iter`) over the indices (keys) of the list.\n /// The iterator provides a single method `next()` which returns indices\n /// from 0 to size-1, or `null` when out of elements.\n ///\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// let list = List.empty<Text>();\n /// List.add(list, \"A\");\n /// List.add(list, \"B\");\n /// List.add(list, \"C\");\n /// Iter.toArray(List.keys(list)) // [0, 1, 2]\n /// ```\n ///\n /// Note: This does not create a snapshot. If the returned iterator is not consumed at once,\n /// and instead the consumption of the iterator is interleaved with other operations on the\n /// List, then this may lead to unexpected results.\n ///\n /// Runtime: `O(1)`\n public func keys<T>(list : List<T>) : Iter.Iter<Nat> = Nat.range(0, size(list));\n\n /// Creates a new List containing all elements from the provided iterator.\n /// Elements are added in the order they are returned by the iterator.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// let array = [1, 1, 1];\n /// let iter = array.vals();\n ///\n /// let list = List.fromIter<Nat>(iter);\n /// assert Iter.toArray(List.values(list)) == [1, 1, 1];\n /// ```\n ///\n /// Runtime: `O(size)`\n public func fromIter<T>(iter : Iter.Iter<T>) : List<T> {\n let list = empty<T>();\n for (element in iter) add(list, element);\n list\n };\n\n /// Adds all elements from the provided iterator to the end of the list.\n /// Elements are added in the order they are returned by the iterator.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// let array = [1, 1, 1];\n /// let iter = array.vals();\n /// let list = List.repeat<Nat>(2, 1);\n ///\n /// List.addAll<Nat>(list, iter);\n /// assert Iter.toArray(List.values(list)) == [2, 1, 1, 1];\n /// ```\n ///\n /// The maximum number of elements in a `List` is 2^32.\n ///\n /// Runtime: `O(size)`, where n is the size of iter.\n public func addAll<T>(list : List<T>, iter : Iter.Iter<T>) {\n for (element in iter) add(list, element)\n };\n\n /// Creates a new immutable array containing all elements from the list.\n /// Elements appear in the same order as in the list.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.fromArray<Nat>([1, 2, 3]);\n ///\n /// assert List.toArray<Nat>(list) == [1, 2, 3];\n /// ```\n ///\n /// Runtime: `O(size)`\n public func toArray<T>(list : List<T>) : [T] = Array.tabulate<T>(size(list), values_(list).unsafe_next_i);\n\n private func values_<T>(list : List<T>) : {\n next : () -> ?T;\n unsafe_next : () -> T;\n unsafe_next_i : Nat -> T\n } = object {\n let blocks = list.blocks.size();\n var blockIndex = 0;\n var elementIndex = 0;\n var db_size = 0;\n var db : [var ?T] = [var];\n\n public func next() : ?T {\n if (elementIndex == db_size) {\n blockIndex += 1;\n if (blockIndex >= blocks) return null;\n db := list.blocks[blockIndex];\n db_size := db.size();\n if (db_size == 0) return null;\n elementIndex := 0\n };\n switch (db[elementIndex]) {\n case (?x) {\n elementIndex += 1;\n return ?x\n };\n case (_) return null\n }\n };\n\n // version of next() without option type\n // inlined version of\n // public func unsafe_next() : T = {\n // let ?x = next() else Prim.trap(INTERNAL_ERROR);\n // x;\n // };\n public func unsafe_next() : T {\n if (elementIndex == db_size) {\n blockIndex += 1;\n if (blockIndex >= blocks) Prim.trap(INTERNAL_ERROR);\n db := list.blocks[blockIndex];\n db_size := db.size();\n if (db_size == 0) Prim.trap(INTERNAL_ERROR);\n elementIndex := 0\n };\n switch (db[elementIndex]) {\n case (?x) {\n elementIndex += 1;\n return x\n };\n case (_) Prim.trap(INTERNAL_ERROR)\n }\n };\n\n // version of next() without option type and throw-away argument\n // inlined version of\n // public func unsafe_next_(i : Nat) : T = unsafe_next();\n public func unsafe_next_i(i : Nat) : T {\n if (elementIndex == db_size) {\n blockIndex += 1;\n if (blockIndex >= blocks) Prim.trap(INTERNAL_ERROR);\n db := list.blocks[blockIndex];\n db_size := db.size();\n if (db_size == 0) Prim.trap(INTERNAL_ERROR);\n elementIndex := 0\n };\n switch (db[elementIndex]) {\n case (?x) {\n elementIndex += 1;\n return x\n };\n case (_) Prim.trap(INTERNAL_ERROR)\n }\n }\n };\n\n /// Creates a List containing elements from an Array.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// let array = [2, 3];\n /// let list = List.fromArray<Nat>(array);\n /// assert Iter.toArray(List.values(list)) == [2, 3];\n /// ```\n ///\n /// Runtime: `O(size)`\n public func fromArray<T>(array : [T]) : List<T> {\n let (blockIndex, elementIndex) = locate(array.size());\n\n let blocks = new_index_block_length(Nat32.fromNat(if (elementIndex == 0) { blockIndex - 1 } else blockIndex));\n let data_blocks = VarArray.repeat<[var ?T]>([var], blocks);\n var i = 1;\n var pos = 0;\n\n func make_block(len : Nat, fill : Nat) : [var ?T] {\n let block = VarArray.repeat<?T>(null, len);\n var j = 0;\n while (j < fill) {\n block[j] := ?array[pos];\n j += 1;\n pos += 1\n };\n block\n };\n\n while (i < blockIndex) {\n let len = data_block_size(i);\n data_blocks[i] := make_block(len, len);\n i += 1\n };\n if (elementIndex != 0 and blockIndex < blocks) {\n data_blocks[i] := make_block(data_block_size(i), elementIndex)\n };\n\n {\n var blocks = data_blocks;\n var blockIndex = blockIndex;\n var elementIndex = elementIndex\n };\n\n };\n\n /// Creates a new mutable array containing all elements from the list.\n /// Elements appear in the same order as in the list.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:core/Array\";\n ///\n /// let list = List.fromArray<Nat>([1, 2, 3]);\n ///\n /// let varArray = List.toVarArray<Nat>(list);\n /// assert Array.fromVarArray(varArray) == [1, 2, 3];\n /// ```\n ///\n /// Runtime: `O(size)`\n public func toVarArray<T>(list : List<T>) : [var T] {\n let s = size(list);\n if (s == 0) return [var];\n let arr = VarArray.repeat<T>(Option.unwrap(first(list)), s);\n var i = 0;\n let next = values_(list).unsafe_next;\n while (i < s) {\n arr[i] := next();\n i += 1\n };\n arr\n };\n\n /// Creates a new List containing all elements from the mutable array.\n /// Elements appear in the same order as in the array.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// let array = [var 2, 3];\n /// let list = List.fromVarArray<Nat>(array);\n /// assert Iter.toArray(List.values(list)) == [2, 3];\n /// ```\n ///\n /// Runtime: `O(size)`\n public func fromVarArray<T>(array : [var T]) : List<T> {\n let (blockIndex, elementIndex) = locate(array.size());\n\n let blocks = new_index_block_length(Nat32.fromNat(if (elementIndex == 0) { blockIndex - 1 } else blockIndex));\n let data_blocks = VarArray.repeat<[var ?T]>([var], blocks);\n var i = 1;\n var pos = 0;\n\n func make_block(len : Nat, fill : Nat) : [var ?T] {\n let block = VarArray.repeat<?T>(null, len);\n var j = 0;\n while (j < fill) {\n block[j] := ?array[pos];\n j += 1;\n pos += 1\n };\n block\n };\n\n while (i < blockIndex) {\n let len = data_block_size(i);\n data_blocks[i] := make_block(len, len);\n i += 1\n };\n if (elementIndex != 0 and blockIndex < blocks) {\n data_blocks[i] := make_block(data_block_size(i), elementIndex)\n };\n\n {\n var blocks = data_blocks;\n var blockIndex = blockIndex;\n var elementIndex = elementIndex\n };\n\n };\n\n /// Returns the first element of `list`, or `null` if the list is empty.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert List.first(List.fromArray<Nat>([1, 2, 3])) == ?1;\n /// assert List.first(List.empty<Nat>()) == null;\n /// ```\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func first<T>(list : List<T>) : ?T {\n if (isEmpty(list)) null else list.blocks[1][0]\n };\n\n /// Returns the last element of `list`. Traps if `list` is empty.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert List.last(List.fromArray<Nat>([1, 2, 3])) == ?3;\n /// assert List.last(List.empty<Nat>()) == null;\n /// ```\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func last<T>(list : List<T>) : ?T {\n let e = list.elementIndex;\n if (e > 0) return list.blocks[list.blockIndex][e - 1];\n\n let b = list.blockIndex - 1 : Nat;\n if (b == 0) null else {\n let block = list.blocks[b];\n block[block.size() - 1]\n }\n };\n\n /// Applies `f` to each element in `list`.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Debug \"mo:core/Debug\";\n ///\n /// let list = List.fromArray<Nat>([1, 2, 3]);\n ///\n /// List.forEach<Nat>(list, func(x) {\n /// Debug.print(Nat.toText(x)); // prints each element in list\n /// });\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func forEach<T>(list : List<T>, f : T -> ()) {\n let blocks = list.blocks.size();\n var blockIndex = 0;\n var elementIndex = 0;\n var size = 0;\n var db : [var ?T] = [var];\n\n loop {\n if (elementIndex == size) {\n blockIndex += 1;\n if (blockIndex >= blocks) return;\n db := list.blocks[blockIndex];\n size := db.size();\n if (size == 0) return;\n elementIndex := 0\n };\n switch (db[elementIndex]) {\n case (?x) {\n f(x);\n elementIndex += 1\n };\n case (_) return\n }\n }\n };\n\n /// Applies `f` to each item `(i, x)` in `list` where `i` is the key\n /// and `x` is the value.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Debug \"mo:core/Debug\";\n ///\n /// let list = List.fromArray<Nat>([1, 2, 3]);\n ///\n /// List.forEachEntry<Nat>(list, func (i,x) {\n /// // prints each item (i,x) in list\n /// Debug.print(Nat.toText(i) # Nat.toText(x));\n /// });\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func forEachEntry<T>(list : List<T>, f : (Nat, T) -> ()) {\n /* Inlined version of\n let o = object {\n var i = 0;\n public func fx(x : T) { f(i, x); i += 1; };\n };\n iterate<T>(list, o.fx);\n */\n let blocks = list.blocks.size();\n var blockIndex = 0;\n var elementIndex = 0;\n var size = 0;\n var db : [var ?T] = [var];\n var i = 0;\n\n loop {\n if (elementIndex == size) {\n blockIndex += 1;\n if (blockIndex >= blocks) return;\n db := list.blocks[blockIndex];\n size := db.size();\n if (size == 0) return;\n elementIndex := 0\n };\n switch (db[elementIndex]) {\n case (?x) {\n f(i, x);\n elementIndex += 1;\n i += 1\n };\n case (_) return\n }\n }\n };\n\n /// Like `forEachEntryRev` but iterates through the list in reverse order,\n /// from end to beginning.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Debug \"mo:core/Debug\";\n ///\n /// let list = List.fromArray<Nat>([1, 2, 3]);\n ///\n /// List.reverseForEachEntry<Nat>(list, func (i,x) {\n /// // prints each item (i,x) in list\n /// Debug.print(Nat.toText(i) # Nat.toText(x));\n /// });\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func reverseForEachEntry<T>(list : List<T>, f : (Nat, T) -> ()) {\n var blockIndex = list.blockIndex;\n var elementIndex = list.elementIndex;\n var db : [var ?T] = if (blockIndex < list.blocks.size()) {\n list.blocks[blockIndex]\n } else { [var] };\n var i = size(list);\n\n loop {\n if (blockIndex == 1) {\n return\n };\n if (elementIndex == 0) {\n blockIndex -= 1;\n db := list.blocks[blockIndex];\n elementIndex := db.size() - 1\n } else {\n elementIndex -= 1\n };\n i -= 1;\n switch (db[elementIndex]) {\n case (?x) f(i, x);\n case (_) Prim.trap(INTERNAL_ERROR)\n }\n }\n };\n\n /// Applies `f` to each element in `list` in reverse order.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Debug \"mo:core/Debug\";\n ///\n /// let list = List.fromArray<Nat>([1, 2, 3]);\n ///\n /// List.reverseForEach<Nat>(list, func (x) {\n /// Debug.print(Nat.toText(x)); // prints each element in list in reverse order\n /// });\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func reverseForEach<T>(list : List<T>, f : T -> ()) {\n var blockIndex = list.blockIndex;\n var elementIndex = list.elementIndex;\n var db : [var ?T] = if (blockIndex < list.blocks.size()) {\n list.blocks[blockIndex]\n } else { [var] };\n\n loop {\n if (blockIndex == 1) {\n return\n };\n if (elementIndex == 0) {\n blockIndex -= 1;\n db := list.blocks[blockIndex];\n elementIndex := db.size() - 1\n } else {\n elementIndex -= 1\n };\n switch (db[elementIndex]) {\n case (?x) f(x);\n case (_) Prim.trap(INTERNAL_ERROR)\n }\n }\n };\n\n /// Returns true if the list contains the specified element according to the provided\n /// equality function. Uses the provided `equal` function to compare elements.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.empty<Nat>();\n /// List.add(list, 2);\n /// List.add(list, 0);\n /// List.add(list, 3);\n ///\n /// assert List.contains<Nat>(list, Nat.equal, 2);\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func contains<T>(list : List<T>, equal : (T, T) -> Bool, element : T) : Bool {\n Option.isSome(indexOf(list, equal, element))\n };\n\n /// Returns the greatest element in the list according to the ordering defined by `compare`.\n /// Returns `null` if the list is empty.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.empty<Nat>();\n /// List.add(list, 1);\n /// List.add(list, 2);\n ///\n /// assert List.max<Nat>(list, Nat.compare) == ?2;\n /// assert List.max<Nat>(List.empty<Nat>(), Nat.compare) == null;\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func max<T>(list : List<T>, compare : (T, T) -> Order.Order) : ?T {\n if (isEmpty(list)) return null;\n\n var maxSoFar = get(list, 0);\n forEach<T>(\n list,\n func(x) = switch (compare(x, maxSoFar)) {\n case (#greater) maxSoFar := x;\n case _ {}\n }\n );\n\n return ?maxSoFar\n };\n\n /// Returns the least element in the list according to the ordering defined by `compare`.\n /// Returns `null` if the list is empty.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.empty<Nat>();\n /// List.add(list, 1);\n /// List.add(list, 2);\n ///\n /// assert List.min<Nat>(list, Nat.compare) == ?1;\n /// assert List.min<Nat>(List.empty<Nat>(), Nat.compare) == null;\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func min<T>(list : List<T>, compare : (T, T) -> Order.Order) : ?T {\n if (isEmpty(list)) return null;\n\n var minSoFar = get(list, 0);\n forEach<T>(\n list,\n func(x) = switch (compare(x, minSoFar)) {\n case (#less) minSoFar := x;\n case _ {}\n }\n );\n\n return ?minSoFar\n };\n\n /// Tests if two lists are equal by comparing their elements using the provided `equal` function.\n /// Returns true if and only if both lists have the same size and all corresponding elements\n /// are equal according to the provided function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list1 = List.fromArray<Nat>([1,2]);\n /// let list2 = List.empty<Nat>();\n /// List.add(list2, 1);\n /// List.add(list2, 2);\n ///\n /// assert List.equal<Nat>(list1, list2, Nat.equal);\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func equal<T>(list1 : List<T>, list2 : List<T>, equal : (T, T) -> Bool) : Bool {\n let size1 = size(list1);\n\n if (size1 != size(list2)) return false;\n\n let next1 = values_(list1).unsafe_next;\n let next2 = values_(list2).unsafe_next;\n var i = 0;\n while (i < size1) {\n if (not equal(next1(), next2())) return false;\n i += 1\n };\n\n return true\n };\n\n /// Compares two lists lexicographically using the provided `compare` function.\n /// Elements are compared pairwise until a difference is found or one list ends.\n /// If all elements compare equal, the shorter list is considered less than the longer list.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list1 = List.fromArray<Nat>([0, 1]);\n /// let list2 = List.fromArray<Nat>([2]);\n /// let list3 = List.fromArray<Nat>([0, 1, 2]);\n ///\n /// assert List.compare<Nat>(list1, list2, Nat.compare) == #less;\n /// assert List.compare<Nat>(list1, list3, Nat.compare) == #less;\n /// assert List.compare<Nat>(list2, list3, Nat.compare) == #greater;\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func compare<T>(list1 : List<T>, list2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {\n let size1 = size(list1);\n let size2 = size(list2);\n let minSize = if (size1 < size2) { size1 } else { size2 };\n\n let next1 = values_(list1).unsafe_next;\n let next2 = values_(list2).unsafe_next;\n var i = 0;\n while (i < minSize) {\n switch (compare(next1(), next2())) {\n case (#less) return #less;\n case (#greater) return #greater;\n case _ {}\n };\n i += 1\n };\n Nat.compare(size1, size2)\n };\n\n /// Creates a textual representation of `list`, using `toText` to recursively\n /// convert the elements into Text.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.fromArray<Nat>([1,2,3,4]);\n ///\n /// assert List.toText<Nat>(list, Nat.toText) == \"List[1, 2, 3, 4]\";\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `toText` runs in O(1) time and space.\n public func toText<T>(list : List<T>, f : T -> Text) : Text {\n let vsize : Int = size(list);\n let next = values_(list).unsafe_next;\n var i = 0;\n var text = \"\";\n while (i < vsize - 1) {\n text := text # f(next()) # \", \"; // Text implemented as rope\n i += 1\n };\n if (vsize > 0) {\n // avoid the trailing comma\n text := text # f(get<T>(list, i))\n };\n\n \"List[\" # text # \"]\"\n };\n\n /// Collapses the elements in `list` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.fromArray<Nat>([1,2,3]);\n ///\n /// assert List.foldLeft<Text, Nat>(list, \"\", func (acc, x) { acc # Nat.toText(x)}) == \"123\";\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `combine` runs in O(1)` time and space.\n public func foldLeft<A, T>(list : List<T>, base : A, combine : (A, T) -> A) : A {\n var accumulation = base;\n\n forEach<T>(\n list,\n func(x) = accumulation := combine(accumulation, x)\n );\n\n accumulation\n };\n\n /// Collapses the elements in `list` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// let list = List.fromArray<Nat>([1,2,3]);\n ///\n /// assert List.foldRight<Nat, Text>(list, \"\", func (x, acc) { Nat.toText(x) # acc }) == \"123\";\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n ///\n /// *Runtime and space assumes that `combine` runs in O(1)` time and space.\n public func foldRight<T, A>(list : List<T>, base : A, combine : (T, A) -> A) : A {\n var accumulation = base;\n\n reverseForEach<T>(\n list,\n func(x) = accumulation := combine(x, accumulation)\n );\n\n accumulation\n };\n\n /// Reverses the order of elements in `list` by overwriting in place.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// let list = List.fromArray<Nat>([1,2,3]);\n ///\n /// List.reverseInPlace<Nat>(list);\n /// assert Iter.toArray(List.values(list)) == [3, 2, 1];\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n public func reverseInPlace<T>(list : List<T>) {\n let vsize = size(list);\n if (vsize == 0) return;\n\n var i = 0;\n var j = vsize - 1 : Nat;\n var temp = get(list, 0);\n while (i < vsize / 2) {\n temp := get(list, j);\n put(list, j, get(list, i));\n put(list, i, temp);\n i += 1;\n j -= 1\n }\n };\n\n /// Returns a new List with the elements from `list` in reverse order.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// let list = List.fromArray<Nat>([1,2,3]);\n ///\n /// let rlist = List.reverse<Nat>(list);\n /// assert Iter.toArray(List.values(rlist)) == [3, 2, 1];\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n public func reverse<T>(list : List<T>) : List<T> {\n let rlist = empty<T>();\n\n reverseForEach<T>(\n list,\n func(x) = add(rlist, x)\n );\n\n rlist\n };\n\n /// Returns true if and only if the list is empty.\n ///\n /// Example:\n /// ```motoko include=import\n /// let list = List.fromArray<Nat>([2,0,3]);\n /// assert not List.isEmpty<Nat>(list);\n /// assert List.isEmpty<Nat>(List.empty<Nat>());\n /// ```\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func isEmpty<T>(list : List<T>) : Bool {\n list.blockIndex == 1 and list.elementIndex == 0\n }\n}\n"},"pure/Set.mo":{"content":"/// Pure (immutable) sets based on order/comparison of elements.\n/// A set is a collection of elements without duplicates.\n/// The set data structure type is stable and can be used for orthogonal persistence.\n///\n/// Example:\n/// ```motoko\n/// import Set \"mo:core/pure/Set\";\n/// import Nat \"mo:core/Nat\";\n///\n/// persistent actor {\n/// let set = Set.fromIter([3, 1, 2, 3].values(), Nat.compare);\n/// assert Set.size(set) == 3;\n/// assert not Set.contains(set, Nat.compare, 4);\n/// let diff = Set.difference(set, set, Nat.compare);\n/// assert Set.isEmpty(diff);\n/// }\n/// ```\n///\n/// These sets are implemented as red-black trees, a balanced binary search tree of ordered elements.\n///\n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during modifying operations.\n///\n/// Performance:\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Space: `O(n)` for storing the entire tree.\n/// `n` denotes the number of elements (i.e. nodes) stored in the tree.\n///\n/// Credits:\n///\n/// The core of this implementation is derived from:\n///\n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n\nimport Runtime \"../Runtime\";\nimport List \"../List\"; // NB: imperative!\nimport Iter \"../Iter\";\nimport Types \"../Types\";\nimport Nat \"../Nat\";\nimport Order \"../Order\";\n\nmodule {\n\n /// Ordered collection of unique elements of the generic type `T`.\n /// If type `T` is stable then `Set<T>` is also stable.\n /// To ensure that property the `Set<T>` does not have any methods,\n /// instead they are gathered in the functor-like class `Operations` (see example there).\n public type Set<T> = Types.Pure.Set<T>;\n\n /// Red-black tree of nodes with ordered set elements.\n /// Leaves are considered implicitly black.\n type Tree<T> = Types.Pure.Set.Tree<T>;\n\n /// Create a set with the elements obtained from an iterator.\n /// Potential duplicate elements in the iterator are ignored, i.e.\n /// multiple occurrences of an equal element only occur once in the set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([3, 1, 2, 1].values(), Nat.compare);\n /// assert Iter.toArray(Set.values(set)) == [1, 2, 3];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of elements returned by the iterator and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func fromIter<T>(iter : Iter.Iter<T>, compare : (T, T) -> Order.Order) : Set<T> {\n var set = empty() : Set<T>;\n for (val in iter) {\n set := Internal.add(set, compare, val)\n };\n set\n };\n\n /// Given a `set` ordered by `compare`, insert the new `element`,\n /// returning the new set.\n ///\n /// Return the set unchanged if the element already exists in the set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set0 = Set.empty<Nat>();\n /// let set1 = Set.add(set0, Nat.compare, 2);\n /// let set2 = Set.add(set1, Nat.compare, 1);\n /// let set3 = Set.add(set2, Nat.compare, 2);\n /// assert Iter.toArray(Set.values(set0)) == [];\n /// assert Iter.toArray(Set.values(set1)) == [2];\n /// assert Iter.toArray(Set.values(set2)) == [1, 2];\n /// assert Iter.toArray(Set.values(set3)) == [1, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned set shares with the `set` most of the tree nodes.\n /// Garbage collecting one of the sets (e.g. after an assignment `m := Set.add(m, c, e)`)\n /// causes collecting `O(log(n))` nodes.\n public func add<T>(set : Set<T>, compare : (T, T) -> Order.Order, elem : T) : Set<T> = Internal.add(set, compare, elem);\n\n /// Given `set` ordered by `compare`, insert the new `element`,\n /// returning the set extended with `element` and a Boolean indicating\n /// if the element was already present in `set`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set0 = Set.empty();\n /// do {\n /// let (set1, new1) = Set.insert(set0, Nat.compare, 2);\n /// assert new1;\n /// let (set2, new2) = Set.insert(set1, Nat.compare, 1);\n /// assert new2;\n /// let (set3, new3) = Set.insert(set2, Nat.compare, 2);\n /// assert not new3;\n /// assert Iter.toArray(Set.values(set3)) == [1, 2]\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned set shares with the `set` most of the tree nodes.\n /// Garbage collecting one of the sets (e.g. after an assignment `m := Set.add(m, c, e)`)\n /// causes collecting `O(log(n))` nodes.\n public func insert<T>(set : Set<T>, compare : (T, T) -> Order.Order, elem : T) : (Set<T>, Bool) = Internal.insert<T>(set, compare, elem);\n\n /// Given `set` ordered by `compare` return the set with `element` removed.\n /// Return the set unchanged if the element was absent.\n ///\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([1, 2, 3].values(), Nat.compare);\n ///\n /// let set1 = Set.remove(set, Nat.compare, 2);\n /// let set2 = Set.remove(set1, Nat.compare, 4);\n /// assert Iter.toArray(Set.values(set2)) == [1, 3];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` including garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` objects that will be collected as garbage.\n /// Note: The returned set shares with `set` most of the tree nodes.\n /// Garbage collecting one of the sets (e.g. after an assignment `m := Set.delete(m, c, e)`)\n /// causes collecting `O(log(n))` nodes.\n public func remove<T>(set : Set<T>, compare : (T, T) -> Order.Order, element : T) : Set<T> = Internal.remove(set, compare, element);\n\n /// Given `set` ordered by `compare`, delete `element` from the set, returning\n /// either the set without the element and a Boolean indicating whether\n /// whether `element` was contained in `set`.\n ///\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// do {\n /// let (set1, contained1) = Set.delete(set, Nat.compare, 2);\n /// assert contained1;\n /// assert Iter.toArray(Set.values(set1)) == [1, 3];\n /// let (set2, contained2) = Set.delete(set1, Nat.compare, 4);\n /// assert not contained2;\n /// assert Iter.toArray(Set.values(set2)) == [1, 3];\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` including garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` objects that will be collected as garbage.\n /// Note: The returned set shares with `set` most of the tree nodes.\n /// Garbage collecting one of the sets (e.g. after an assignment `m := Set.delete(m, c, e)`)\n /// causes collecting `O(log(n))` nodes.\n public func delete<T>(set : Set<T>, compare : (T, T) -> Order.Order, element : T) : (Set<T>, Bool) = Internal.delete(set, compare, element);\n\n /// Tests whether the set contains the provided element.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Bool \"mo:core/Bool\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([3, 1, 2].values(), Nat.compare);\n ///\n /// assert Set.contains(set, Nat.compare, 1);\n /// assert not Set.contains(set, Nat.compare, 4);\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func contains<T>(set : Set<T>, compare : (T, T) -> Order.Order, element : T) : Bool = Internal.contains(set.root, compare, element);\n\n /// Get the maximal element of the set `set` if it is not empty, otherwise returns `null`\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter<Nat>([0, 2, 1].values(), Nat.compare);\n /// let set2 = Set.empty<Nat>();\n /// assert Set.max(set1) == ?2;\n /// assert Set.max(set2) == null;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements in the set\n public func max<T>(s : Set<T>) : ?T = Internal.max(s.root);\n\n /// Retrieves the minimum element from the set.\n /// If the set is empty, returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter<Nat>([2, 0, 1].values(), Nat.compare);\n /// let set2 = Set.empty<Nat>();\n /// assert Set.min(set1) == ?0;\n /// assert Set.min(set2) == null;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements stored in the set.\n public func min<T>(s : Set<T>) : ?T = Internal.min(s.root);\n\n /// Returns a new set that is the union of `set1` and `set2`,\n /// i.e. a new set that all the elements that exist in at least on of the two sets.\n /// Potential duplicates are ignored, i.e. if the same element occurs in both `set1`\n /// and `set2`, it only occurs once in the returned set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let set2 = Set.fromIter([3, 4, 5].values(), Nat.compare);\n /// let union = Set.union(set1, set2, Nat.compare);\n /// assert Iter.toArray(Set.values(union)) == [1, 2, 3, 4, 5];\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(m)`, retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements in the sets, and `m <= n`.\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(m * log(n))` temporary objects that will be collected as garbage.\n public func union<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Set<T> {\n if (size(set1) < size(set2)) {\n foldLeft(set1, set2, func(acc : Set<T>, elem : T) : Set<T> { Internal.add(acc, compare, elem) })\n } else {\n foldLeft(set2, set1, func(acc : Set<T>, elem : T) : Set<T> { Internal.add(acc, compare, elem) })\n }\n };\n\n /// Returns a new set that is the intersection of `set1` and `set2`,\n /// i.e. a new set that contains all the elements that exist in both sets.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([0, 1, 2].values(), Nat.compare);\n /// let set2 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let intersection = Set.intersection(set1, set2, Nat.compare);\n /// assert Iter.toArray(Set.values(intersection)) == [1, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(m)` temporary objects that will be collected as garbage.\n public func intersection<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Set<T> {\n let elems = List.empty<T>();\n if (set1.size < set2.size) {\n Internal.iterate(\n set1.root,\n func(x : T) {\n if (Internal.contains(set2.root, compare, x)) {\n List.add(elems, x)\n }\n }\n )\n } else {\n Internal.iterate(\n set2.root,\n func(x : T) {\n if (Internal.contains(set1.root, compare, x)) {\n List.add(elems, x)\n }\n }\n )\n };\n { root = Internal.buildFromSorted(elems); size = List.size(elems) }\n };\n\n /// Returns a new set that is the difference between `set1` and `set2` (`set1` minus `set2`),\n /// i.e. a new set that contains all the elements of `set1` that do not exist in `set2`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let set2 = Set.fromIter([3, 4, 5].values(), Nat.compare);\n /// let difference = Set.difference(set1, set2, Nat.compare);\n /// assert Iter.toArray(Set.values(difference)) == [1, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(m * log(n))` temporary objects that will be collected as garbage.\n public func difference<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Set<T> {\n if (size(set1) < size(set2)) {\n let elems = List.empty<T>(); /* imperative! */\n Internal.iterate(\n set1.root,\n func(x : T) {\n if (not Internal.contains(set2.root, compare, x)) {\n List.add(elems, x)\n }\n }\n );\n { root = Internal.buildFromSorted(elems); size = List.size(elems) }\n } else {\n foldLeft(\n set2,\n set1,\n func(acc : Set<T>, elem : T) : Set<T> {\n if (Internal.contains(acc.root, compare, elem)) {\n Internal.remove(acc, compare, elem)\n } else { acc }\n }\n )\n }\n };\n\n /// Project all elements of the set in a new set.\n /// Apply a mapping function to each element in the set and\n /// collect the mapped elements in a new mutable set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let numbers = Set.fromIter([3, 1, 2].values(), Nat.compare);\n ///\n /// let textNumbers =\n /// Set.map<Nat, Text>(numbers, Text.compare, Nat.toText);\n /// assert Iter.toArray(Set.values(textNumbers)) == [\"1\", \"2\", \"3\"];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func map<T1, T2>(s : Set<T1>, compare : (T2, T2) -> Order.Order, project : T1 -> T2) : Set<T2> = Internal.foldLeft(s.root, empty<T2>(), func(acc : Set<T2>, elem : T1) : Set<T2> { Internal.add(acc, compare, project(elem)) });\n\n /// Apply an operation on each element contained in the set.\n /// The operation is applied in ascending order of the elements.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let numbers = Set.fromIter([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// var text = \"\";\n /// Set.forEach<Nat>(numbers, func (element) {\n /// text #= \" \" # Nat.toText(element)\n /// });\n /// assert text == \" 0 1 2 3\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory.\n /// where `n` denotes the number of elements stored in the set.\n ///\n public func forEach<T>(set : Set<T>, operation : T -> ()) {\n ignore foldLeft<T, Null>(set, null, func(acc, e) : Null { operation(e); null })\n };\n\n /// Filter elements in a new set.\n /// Create a copy of the mutable set that only contains the elements\n /// that fulfil the criterion function.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let numbers = Set.fromIter([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// let evenNumbers = Set.filter<Nat>(numbers, Nat.compare, func (number) {\n /// number % 2 == 0\n /// });\n /// assert Iter.toArray(Set.values(evenNumbers)) == [0, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func filter<T>(set : Set<T>, compare : (T, T) -> Order.Order, criterion : T -> Bool) : Set<T> {\n foldLeft<T, Set<T>>(\n set,\n empty(),\n func(acc, e) {\n if (criterion(e)) (add(acc, compare, e)) else acc\n }\n )\n };\n\n /// Filter all elements in the set by also applying a projection to the elements.\n /// Apply a mapping function `project` to all elements in the set and collect all\n /// elements, for which the function returns a non-null new element. Collect all\n /// non-discarded new elements in a new mutable set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let numbers = Set.fromIter([3, 0, 2, 1].values(), Nat.compare);\n ///\n /// let evenTextNumbers = Set.filterMap<Nat, Text>(numbers, Text.compare, func (number) {\n /// if (number % 2 == 0) {\n /// ?Nat.toText(number)\n /// } else {\n /// null // discard odd numbers\n /// }\n /// });\n /// assert Iter.toArray(Set.values(evenTextNumbers)) == [\"0\", \"2\"];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func filterMap<T1, T2>(set : Set<T1>, compare : (T2, T2) -> Order.Order, project : T1 -> ?T2) : Set<T2> {\n func combine(acc : Set<T2>, elem : T1) : Set<T2> {\n switch (project(elem)) {\n case null { acc };\n case (?elem2) {\n Internal.add(acc, compare, elem2)\n }\n }\n };\n Internal.foldLeft(set.root, empty(), combine)\n };\n\n /// Test whether `set1` is a sub-set of `set2`, i.e. each element in `set1` is\n /// also contained in `set2`. Returns `true` if both sets are equal.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2].values(), Nat.compare);\n /// let set2 = Set.fromIter([2, 1, 0].values(), Nat.compare);\n /// let set3 = Set.fromIter([3, 4].values(), Nat.compare);\n /// assert Set.isSubset(set1, set2, Nat.compare);\n /// assert not Set.isSubset(set1, set3, Nat.compare);\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets set1 and set2, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func isSubset<T>(s1 : Set<T>, s2 : Set<T>, compare : (T, T) -> Order.Order) : Bool {\n if (s1.size > s2.size) { return false };\n isSubsetHelper(s1.root, s2.root, compare)\n };\n\n /// Test whether two sets are equal.\n /// Both sets have to be constructed by the same comparison function.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2].values(), Nat.compare);\n /// let set2 = Set.fromIter([2, 1].values(), Nat.compare);\n /// let set3 = Set.fromIter([2, 1, 0].values(), Nat.compare);\n /// assert Set.equal(set1, set2, Nat.compare);\n /// assert not Set.equal(set1, set3, Nat.compare);\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets set1 and set2, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func equal<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Bool {\n if (set1.size != set2.size) { return false };\n isSubsetHelper(set1.root, set2.root, compare)\n };\n\n func isSubsetHelper<T>(t1 : Tree<T>, t2 : Tree<T>, compare : (T, T) -> Order.Order) : Bool {\n switch (t1, t2) {\n case (#leaf, _) { true };\n case (_, #leaf) { false };\n case ((#red(t1l, x1, t1r) or #black(t1l, x1, t1r)), (#red(t2l, x2, t2r)) or #black(t2l, x2, t2r)) {\n switch (compare(x1, x2)) {\n case (#equal) {\n isSubsetHelper(t1l, t2l, compare) and isSubsetHelper(t1r, t2r, compare)\n };\n // x1 < x2 ==> x1 \\in t2l /\\ t1l \\subset t2l\n case (#less) {\n Internal.contains(t2l, compare, x1) and isSubsetHelper(t1l, t2l, compare) and isSubsetHelper(t1r, t2, compare)\n };\n // x2 < x1 ==> x1 \\in t2r /\\ t1r \\subset t2r\n case (#greater) {\n Internal.contains(t2r, compare, x1) and isSubsetHelper(t1l, t2, compare) and isSubsetHelper(t1r, t2r, compare)\n }\n }\n }\n }\n };\n\n /// Compare two sets by comparing the elements.\n /// Both sets must have been created by the same comparison function.\n /// The two sets are iterated by the ascending order of their creation and\n /// order is determined by the following rules:\n /// Less:\n /// `set1` is less than `set2` if:\n /// * the pairwise iteration hits an element pair `element1` and `element2` where\n /// `element1` is less than `element2` and all preceding elements are equal, or,\n /// * `set1` is a strict prefix of `set2`, i.e. `set2` has more elements than `set1`\n /// and all elements of `set1` occur at the beginning of iteration `set2`.\n /// Equal:\n /// `set1` and `set2` have same series of equal elements by pairwise iteration.\n /// Greater:\n /// `set1` is neither less nor equal `set2`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([0, 1].values(), Nat.compare);\n /// let set2 = Set.fromIter([0, 2].values(), Nat.compare);\n ///\n /// assert Set.compare(set1, set2, Nat.compare) == #less;\n /// assert Set.compare(set1, set1, Nat.compare) == #equal;\n /// assert Set.compare(set2, set1, Nat.compare) == #greater;\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that `compare` has runtime and space costs of `O(1)`.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func compare<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Order.Order {\n // TODO: optimize using recursion on set1?\n let iterator1 = values(set1);\n let iterator2 = values(set2);\n loop {\n switch (iterator1.next(), iterator2.next()) {\n case (null, null) return #equal;\n case (null, _) return #less;\n case (_, null) return #greater;\n case (?element1, ?element2) {\n let comparison = compare(element1, element2);\n if (comparison != #equal) {\n return comparison\n }\n }\n }\n }\n };\n\n /// Returns an iterator over the elements in the set,\n /// traversing the elements in the ascending order.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 2, 3, 1].values(), Nat.compare);\n ///\n /// var text = \"\";\n /// for (number in Set.values(set)) {\n /// text #= \" \" # Nat.toText(number);\n /// };\n /// assert text == \" 0 1 2 3\";\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func values<T>(set : Set<T>) : Iter.Iter<T> = Internal.iter(set.root, #fwd);\n\n /// Returns an iterator over the elements in the set,\n /// traversing the elements in the descending order.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 2, 3, 1].values(), Nat.compare);\n ///\n /// var tmp = \"\";\n /// for (number in Set.reverseValues(set)) {\n /// tmp #= \" \" # Nat.toText(number);\n /// };\n /// assert tmp == \" 3 2 1 0\";\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func reverseValues<T>(set : Set<T>) : Iter.Iter<T> = Internal.iter(set.root, #bwd);\n\n /// Create a new empty set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// assert Iter.toArray(Set.values(set)) == [];\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func empty<T>() : Set<T> = { root = #leaf; size = 0 };\n\n /// Create a new set with a single element.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.singleton(0);\n /// assert Iter.toArray(Set.values(set)) == [0];\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func singleton<T>(element : T) : Set<T> {\n {\n size = 1;\n root = #red(#leaf, element, #leaf)\n }\n };\n\n /// Return the number of elements in a set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 3, 2, 1, 3].values(), Nat.compare);\n ///\n /// assert Set.size(set) == 4;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func size<T>(set : Set<T>) : Nat = set.size;\n\n /// Iterate all elements in ascending order,\n /// and accumulate the elements by applying the combine function, starting from a base value.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 3, 2, 1].values(), Nat.compare);\n ///\n /// let text = Set.foldLeft<Nat, Text>(\n /// set,\n /// \"\",\n /// func (accumulator, element) {\n /// accumulator # \" \" # Nat.toText(element)\n /// }\n /// );\n /// assert text == \" 0 1 2 3\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n public func foldLeft<T, A>(\n set : Set<T>,\n base : A,\n combine : (A, T) -> A\n ) : A = Internal.foldLeft(set.root, base, combine);\n\n /// Iterate all elements in descending order,\n /// and accumulate the elements by applying the combine function, starting from a base value.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 3, 2, 1].values(), Nat.compare);\n ///\n /// let text = Set.foldRight<Nat, Text>(\n /// set,\n /// \"\",\n /// func (element, accumulator) {\n /// accumulator # \" \" # Nat.toText(element)\n /// }\n /// );\n /// assert text == \" 3 2 1 0\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n public func foldRight<T, A>(\n set : Set<T>,\n base : A,\n combine : (T, A) -> A\n ) : A = Internal.foldRight(set.root, base, combine);\n\n /// Determines whether a set is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.empty<Nat>();\n /// let set2 = Set.singleton<Nat>(1);\n ///\n /// assert Set.isEmpty(set1);\n /// assert not Set.isEmpty(set2);\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func isEmpty<T>(set : Set<T>) : Bool {\n switch (set.root) {\n case (#leaf) { true };\n case _ { false }\n }\n };\n\n /// Check whether all element in the set satisfy a predicate, i.e.\n /// the `predicate` function returns `true` for all elements in the set.\n /// Returns `true` for an empty set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter<Nat>([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// let belowTen = Set.all<Nat>(set, func (number) {\n /// number < 10\n /// });\n /// assert belowTen;\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements stored in the set.\n public func all<T>(set : Set<T>, predicate : T -> Bool) : Bool = Internal.all(set.root, predicate);\n\n /// Check whether at least one element in the set satisfies a predicate, i.e.\n /// the `predicate` function returns `true` for at least one element in the set.\n /// Returns `false` for an empty set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter<Nat>([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// let aboveTen = Set.any<Nat>(set, func (number) {\n /// number > 10\n /// });\n /// assert not aboveTen;\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n public func any<T>(s : Set<T>, pred : T -> Bool) : Bool = Internal.any(s.root, pred);\n\n /// Test helper that check internal invariant for the given set `s`.\n /// Raise an error (for a stack trace) if invariants are violated.\n public func assertValid<T>(set : Set<T>, compare : (T, T) -> Order.Order) : () {\n Internal.assertValid(set, compare)\n };\n\n /// Generate a textual representation of all the elements in the set.\n /// Primarily to be used for testing and debugging.\n /// The elements are formatted according to `elementFormat`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter<Nat>([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// assert Set.toText(set, Nat.toText) == \"PureSet{0, 1, 2, 3}\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that `elementFormat` has runtime and space costs of `O(1)`.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func toText<T>(set : Set<T>, elementFormat : T -> Text) : Text {\n var text = \"PureSet{\";\n var sep = \"\";\n for (element in values(set)) {\n text #= sep # elementFormat(element);\n sep := \", \"\n };\n text # \"}\"\n };\n\n /// Construct the union of a set of element sets, i.e. all elements of\n /// each element set are included in the result set.\n /// Any duplicates are ignored, i.e. if the same element occurs in multiple element sets,\n /// it only occurs once in the result set.\n ///\n /// Assumes all sets are ordered by `compare`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Order \"mo:core/Order\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// func setCompare(first: Set.Set<Nat>, second: Set.Set<Nat>) : Order.Order {\n /// Set.compare(first, second, Nat.compare)\n /// };\n ///\n /// let set1 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let set2 = Set.fromIter([3, 4, 5].values(), Nat.compare);\n /// let set3 = Set.fromIter([5, 6, 7].values(), Nat.compare);\n /// let setOfSets = Set.fromIter([set1, set2, set3].values(), setCompare);\n /// let flatSet = Set.flatten(setOfSets, Nat.compare);\n /// assert Iter.toArray(Set.values(flatSet)) == [1, 2, 3, 4, 5, 6, 7];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in all the sub-sets,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func flatten<T>(setOfSets : Set<Set<T>>, compare : (T, T) -> Order.Order) : Set<T> {\n var result = empty<T>();\n for (set in values(setOfSets)) {\n result := union(result, set, compare)\n };\n result\n };\n\n /// Construct the union of a series of sets, i.e. all elements of\n /// each set are included in the result set.\n /// Any duplicates are ignored, i.e. if an element occurs\n /// in several of the iterated sets, it only occurs once in the result set.\n ///\n /// Assumes all sets are ordered by `compare`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let set2 = Set.fromIter([3, 4, 5].values(), Nat.compare);\n /// let set3 = Set.fromIter([5, 6, 7].values(), Nat.compare);\n /// let combined = Set.join([set1, set2, set3].values(), Nat.compare);\n /// assert Iter.toArray(Set.values(combined)) == [1, 2, 3, 4, 5, 6, 7];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the iterated sets,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func join<T>(setIterator : Iter.Iter<Set<T>>, compare : (T, T) -> Order.Order) : Set<T> {\n var result = empty<T>();\n for (set in setIterator) {\n result := union(result, set, compare)\n };\n result\n };\n\n module Internal {\n public func contains<T>(tree : Tree<T>, compare : (T, T) -> Order.Order, elem : T) : Bool {\n func f(t : Tree<T>, x : T) : Bool {\n switch t {\n case (#black(l, x1, r)) {\n switch (compare(x, x1)) {\n case (#less) { f(l, x) };\n case (#equal) { true };\n case (#greater) { f(r, x) }\n }\n };\n case (#red(l, x1, r)) {\n switch (compare(x, x1)) {\n case (#less) { f(l, x) };\n case (#equal) { true };\n case (#greater) { f(r, x) }\n }\n };\n case (#leaf) { false }\n }\n };\n f(tree, elem)\n };\n\n public func max<V>(m : Tree<V>) : ?V {\n func rightmost(m : Tree<V>) : V {\n switch m {\n case (#red(_, v, #leaf)) { v };\n case (#red(_, _, r)) { rightmost(r) };\n case (#black(_, v, #leaf)) { v };\n case (#black(_, _, r)) { rightmost(r) };\n case (#leaf) { Runtime.trap \"pure/Set.max() impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?rightmost(m) }\n }\n };\n\n public func min<V>(m : Tree<V>) : ?V {\n func leftmost(m : Tree<V>) : V {\n switch m {\n case (#red(#leaf, v, _)) { v };\n case (#red(l, _, _)) { leftmost(l) };\n case (#black(#leaf, v, _)) { v };\n case (#black(l, _, _)) { leftmost(l) };\n case (#leaf) { Runtime.trap \"pure/Set.min() impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?leftmost(m) }\n }\n };\n\n public func all<V>(m : Tree<V>, pred : V -> Bool) : Bool {\n switch m {\n case (#red(l, v, r)) {\n pred(v) and all(l, pred) and all(r, pred)\n };\n case (#black(l, v, r)) {\n pred(v) and all(l, pred) and all(r, pred)\n };\n case (#leaf) { true }\n }\n };\n\n public func any<V>(m : Tree<V>, pred : V -> Bool) : Bool {\n switch m {\n case (#red(l, v, r)) {\n pred(v) or any(l, pred) or any(r, pred)\n };\n case (#black(l, v, r)) {\n pred(v) or any(l, pred) or any(r, pred)\n };\n case (#leaf) { false }\n }\n };\n\n public func iterate<V>(m : Tree<V>, f : V -> ()) {\n switch m {\n case (#leaf) {};\n case (#black(l, v, r)) { iterate(l, f); f(v); iterate(r, f) };\n case (#red(l, v, r)) { iterate(l, f); f(v); iterate(r, f) }\n }\n };\n\n // build tree from elements arr[l]..arr[r-1]\n public func buildFromSorted<V>(buf : List.List<V>) : Tree<V> {\n var maxDepth = 0;\n var maxSize = 1;\n while (maxSize < List.size(buf)) {\n maxDepth += 1;\n maxSize += maxSize + 1\n };\n maxDepth := if (maxDepth == 0) { 1 } else { maxDepth }; // keep root black for 1 element tree\n func buildFromSortedHelper(l : Nat, r : Nat, depth : Nat) : Tree<V> {\n if (l + 1 == r) {\n if (depth == maxDepth) {\n return #red(#leaf, List.get(buf, l), #leaf)\n } else {\n return #black(#leaf, List.get(buf, l), #leaf)\n }\n };\n if (l >= r) {\n return #leaf\n };\n let m = (l + r) / 2;\n return #black(\n buildFromSortedHelper(l, m, depth + 1),\n List.get(buf, m),\n buildFromSortedHelper(m + 1, r, depth + 1)\n )\n };\n buildFromSortedHelper(0, List.size(buf), 0)\n };\n\n type IterRep<T> = Types.Pure.List<{ #tr : Tree<T>; #x : T }>;\n\n type SetTraverser<T> = (Tree<T>, T, Tree<T>, IterRep<T>) -> IterRep<T>;\n\n class IterSet<T>(tree : Tree<T>, setTraverser : SetTraverser<T>) {\n var trees : IterRep<T> = ?(#tr(tree), null);\n public func next() : ?T {\n switch (trees) {\n case (null) { null };\n case (?(#tr(#leaf), ts)) {\n trees := ts;\n next()\n };\n case (?(#x(x), ts)) {\n trees := ts;\n ?x\n };\n case (?(#tr(#black(l, x, r)), ts)) {\n trees := setTraverser(l, x, r, ts);\n next()\n };\n case (?(#tr(#red(l, x, r)), ts)) {\n trees := setTraverser(l, x, r, ts);\n next()\n }\n }\n }\n };\n\n public func iter<T>(s : Tree<T>, direction : { #fwd; #bwd }) : Iter.Iter<T> {\n let turnLeftFirst : SetTraverser<T> = func(l, x, r, ts) {\n ?(#tr(l), ?(#x(x), ?(#tr(r), ts)))\n };\n\n let turnRightFirst : SetTraverser<T> = func(l, x, r, ts) {\n ?(#tr(r), ?(#x(x), ?(#tr(l), ts)))\n };\n\n switch direction {\n case (#fwd) IterSet(s, turnLeftFirst);\n case (#bwd) IterSet(s, turnRightFirst)\n }\n };\n\n public func foldLeft<T, Accum>(\n tree : Tree<T>,\n base : Accum,\n combine : (Accum, T) -> Accum\n ) : Accum {\n switch (tree) {\n case (#leaf) { base };\n case (#black(l, x, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, x);\n foldLeft(r, middle, combine)\n };\n case (#red(l, x, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, x);\n foldLeft(r, middle, combine)\n }\n }\n };\n\n public func foldRight<T, Accum>(\n tree : Tree<T>,\n base : Accum,\n combine : (T, Accum) -> Accum\n ) : Accum {\n switch (tree) {\n case (#leaf) { base };\n case (#black(l, x, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(x, right);\n foldRight(l, middle, combine)\n };\n case (#red(l, x, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(x, right);\n foldRight(l, middle, combine)\n }\n }\n };\n\n func redden<T>(t : Tree<T>) : Tree<T> {\n switch t {\n case (#black(l, x, r)) { (#red(l, x, r)) };\n case _ {\n Runtime.trap \"pure/Set.redden() impossible\"\n }\n }\n };\n\n func lbalance<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#red(#red(l1, x1, r1), x2, r2), r) {\n #red(\n #black(l1, x1, r1),\n x2,\n #black(r2, x, r)\n )\n };\n case (#red(l1, x1, #red(l2, x2, r2)), r) {\n #red(\n #black(l1, x1, l2),\n x2,\n #black(r2, x, r)\n )\n };\n case _ {\n #black(left, x, right)\n }\n }\n };\n\n func rbalance<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (l, #red(l1, x1, #red(l2, x2, r2))) {\n #red(\n #black(l, x, l1),\n x1,\n #black(l2, x2, r2)\n )\n };\n case (l, #red(#red(l1, x1, r1), x2, r2)) {\n #red(\n #black(l, x, l1),\n x1,\n #black(r1, x2, r2)\n )\n };\n case _ {\n #black(left, x, right)\n }\n }\n };\n\n public func add<T>(\n set : Set<T>,\n compare : (T, T) -> Order.Order,\n elem : T\n ) : Set<T> {\n insert(set, compare, elem).0\n };\n\n public func insert<T>(\n s : Set<T>,\n compare : (T, T) -> Order.Order,\n elem : T\n ) : (Set<T>, Bool) {\n var newNodeIsCreated : Bool = false;\n func ins(tree : Tree<T>) : Tree<T> {\n switch tree {\n case (#black(left, x, right)) {\n switch (compare(elem, x)) {\n case (#less) {\n lbalance(ins left, x, right)\n };\n case (#greater) {\n rbalance(left, x, ins right)\n };\n case (#equal) {\n #black(left, x, right)\n }\n }\n };\n case (#red(left, x, right)) {\n switch (compare(elem, x)) {\n case (#less) {\n #red(ins left, x, right)\n };\n case (#greater) {\n #red(left, x, ins right)\n };\n case (#equal) {\n #red(left, x, right)\n }\n }\n };\n case (#leaf) {\n newNodeIsCreated := true;\n #red(#leaf, elem, #leaf)\n }\n }\n };\n let newRoot = switch (ins(s.root)) {\n case (#red(left, x, right)) {\n #black(left, x, right)\n };\n case other { other }\n };\n if newNodeIsCreated ({ root = newRoot; size = s.size + 1 }, true) else (s, false)\n };\n\n func balLeft<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#red(l1, x1, r1), r) {\n #red(#black(l1, x1, r1), x, r)\n };\n case (_, #black(l2, x2, r2)) {\n rbalance(left, x, #red(l2, x2, r2))\n };\n case (_, #red(#black(l2, x2, r2), x3, r3)) {\n #red(\n #black(left, x, l2),\n x2,\n rbalance(r2, x3, redden r3)\n )\n };\n case _ { Runtime.trap \"pure/Set.balLeft() impossible\" }\n }\n };\n\n func balRight<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (l, #red(l1, x1, r1)) {\n #red(l, x, #black(l1, x1, r1))\n };\n case (#black(l1, x1, r1), r) {\n lbalance(#red(l1, x1, r1), x, r)\n };\n case (#red(l1, x1, #black(l2, x2, r2)), r3) {\n #red(\n lbalance(redden l1, x1, l2),\n x2,\n #black(r2, x, r3)\n )\n };\n case _ { Runtime.trap \"pure/Set.balRight() impossible\" }\n }\n };\n\n func append<T>(left : Tree<T>, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#leaf, _) { right };\n case (_, #leaf) { left };\n case (\n #red(l1, x1, r1),\n #red(l2, x2, r2)\n ) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, r3)) {\n #red(\n #red(l1, x1, l3),\n x3,\n #red(r3, x2, r2)\n )\n };\n case r1l2 {\n #red(l1, x1, #red(r1l2, x2, r2))\n }\n }\n };\n case (t1, #red(l2, x2, r2)) {\n #red(append(t1, l2), x2, r2)\n };\n case (#red(l1, x1, r1), t2) {\n #red(l1, x1, append(r1, t2))\n };\n case (#black(l1, x1, r1), #black(l2, x2, r2)) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, r3)) {\n #red(\n #black(l1, x1, l3),\n x3,\n #black(r3, x2, r2)\n )\n };\n case r1l2 {\n balLeft(\n l1,\n x1,\n #black(r1l2, x2, r2)\n )\n }\n }\n }\n }\n };\n\n public func remove<T>(set : Set<T>, compare : (T, T) -> Order.Order, elem : T) : Set<T> {\n delete(set, compare, elem).0\n };\n\n public func delete<T>(s : Set<T>, compare : (T, T) -> Order.Order, x : T) : (Set<T>, Bool) {\n var changed : Bool = false;\n func delNode(left : Tree<T>, x1 : T, right : Tree<T>) : Tree<T> {\n switch (compare(x, x1)) {\n case (#less) {\n let newLeft = del left;\n switch left {\n case (#black(_, _, _)) {\n balLeft(newLeft, x1, right)\n };\n case _ {\n #red(newLeft, x1, right)\n }\n }\n };\n case (#greater) {\n let newRight = del right;\n switch right {\n case (#black(_, _, _)) {\n balRight(left, x1, newRight)\n };\n case _ {\n #red(left, x1, newRight)\n }\n }\n };\n case (#equal) {\n changed := true;\n append(left, right)\n }\n }\n };\n func del(tree : Tree<T>) : Tree<T> {\n switch tree {\n case (#black(left, x1, right)) {\n delNode(left, x1, right)\n };\n case (#red(left, x1, right)) {\n delNode(left, x1, right)\n };\n case (#leaf) {\n tree\n }\n }\n };\n let newRoot = switch (del(s.root)) {\n case (#red(left, x1, right)) {\n #black(left, x1, right)\n };\n case other { other }\n };\n if changed ({ root = newRoot; size = s.size - 1 }, true) else (s, false)\n };\n\n // check binary search tree order of elements and black depth invariant of the RB-tree\n public func assertValid<T>(s : Set<T>, comp : (T, T) -> Order.Order) {\n ignore blackDepth(s.root, comp)\n };\n\n func blackDepth<T>(node : Tree<T>, comp : (T, T) -> Order.Order) : Nat {\n func checkNode(left : Tree<T>, x1 : T, right : Tree<T>) : Nat {\n checkElem(left, func(x : T) : Bool { comp(x, x1) == #less });\n checkElem(right, func(x : T) : Bool { comp(x, x1) == #greater });\n let leftBlacks = blackDepth(left, comp);\n let rightBlacks = blackDepth(right, comp);\n assert (leftBlacks == rightBlacks);\n leftBlacks\n };\n switch node {\n case (#leaf) 0;\n case (#red(left, x1, right)) {\n assert (not isRed(left));\n assert (not isRed(right));\n checkNode(left, x1, right)\n };\n case (#black(left, x1, right)) {\n checkNode(left, x1, right) + 1\n }\n }\n };\n\n func isRed<T>(node : Tree<T>) : Bool {\n switch node {\n case (#red(_, _, _)) true;\n case _ false\n }\n };\n\n func checkElem<T>(node : Tree<T>, isValid : T -> Bool) {\n switch node {\n case (#leaf) {};\n case (#black(_, elem, _)) {\n assert (isValid(elem))\n };\n case (#red(_, elem, _)) {\n assert (isValid(elem))\n }\n }\n }\n };\n\n}\n"},"pure/Map.mo":{"content":"/// Immutable, ordered key-value maps.\n///\n/// The map type is stable whenever the key and value types are stable, allowing\n/// map values to be stored in stable variables.\n///\n/// Keys are ordered by an explicit `compare` function, which *must* be the same\n/// across all operations on a given map.\n///\n///\n/// Example:\n/// ```motoko\n/// import Map \"mo:core/pure/Map\";\n/// import Nat \"mo:core/Nat\";\n///\n/// persistent actor {\n/// // creation\n/// let empty = Map.empty<Nat, Text>();\n/// // insertion\n/// let map1 = Map.add(empty, Nat.compare, 0, \"Zero\");\n/// // retrieval\n/// assert Map.get(empty, Nat.compare, 0) == null;\n/// assert Map.get(map1, Nat.compare, 0) == ?\"Zero\";\n/// // removal\n/// let map2 = Map.remove(map1, Nat.compare, 0);\n/// assert not Map.isEmpty(map1);\n/// assert Map.isEmpty(map2);\n/// }\n/// ```\n///\n/// The internal representation is a red-black tree.\n///\n/// A red-black tree is a balanced binary search tree ordered by the keys.\n///\n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n///\n/// Performance:\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Space: `O(n)` for storing the entire tree.\n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n///\n/// Note:\n/// * Map operations, such as retrieval, insertion, and removal create `O(log(n))` temporary objects that become garbage.\n///\n/// Credits:\n///\n/// The core of this implementation is derived from:\n///\n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n\nimport Order \"../Order\";\nimport Iter \"../Iter\";\nimport Types \"../Types\";\nimport Runtime \"../Runtime\";\n\n// TODO: inline Internal?\n// TODO: Do we want clone or clear, just to match imperative API?\n// inline Tree type, remove Types.Pure.Tree?\n\nmodule {\n\n public type Map<K, V> = Types.Pure.Map<K, V>;\n\n type Tree<K, V> = Types.Pure.Map.Tree<K, V>;\n\n /// Create a new empty immutable key-value map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.empty<Nat, Text>();\n /// assert Map.size(map) == 0;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func empty<K, V>() : Map<K, V> {\n Internal.empty<K, V>()\n };\n\n /// Determines whether a key-value map is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map0 = Map.empty<Nat, Text>();\n /// let map1 = Map.add(map0, Nat.compare, 0, \"Zero\");\n ///\n /// assert Map.isEmpty(map0);\n /// assert not Map.isEmpty(map1);\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func isEmpty<K, V>(map : Map<K, V>) : Bool {\n map.size == 0\n };\n\n /// Determine the size of the map as the number of key-value entries.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Map.size(map) == 3;\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n public func size<K, V>(map : Map<K, V>) : Nat = map.size;\n\n /// Test whether the map `map`, ordered by `compare`, contains a binding for the given `key`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Map.containsKey(map, Nat.compare, 1);\n /// assert not Map.containsKey(map, Nat.compare, 42);\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func containsKey<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : Bool = Internal.contains(map.root, compare, key);\n\n /// Given, `map` ordered by `compare`, return the value associated with key `key` if present and `null` otherwise.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Map.get(map, Nat.compare, 1) == ?\"One\";\n /// assert Map.get(map, Nat.compare, 42) == null;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func get<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : ?V = Internal.get(map.root, compare, key);\n\n /// Given `map` ordered by `compare`, insert a mapping from `key` to `value`.\n /// Returns the modified map and `true` if the key is new to map, otherwise `false`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map0 = Map.empty<Nat, Text>();\n ///\n /// do {\n /// let (map1, new1) = Map.insert(map0, Nat.compare, 0, \"Zero\");\n /// assert Iter.toArray(Map.entries(map1)) == [(0, \"Zero\")];\n /// assert new1;\n /// let (map2, new2) = Map.insert(map1, Nat.compare, 0, \"Nil\");\n /// assert Iter.toArray(Map.entries(map2)) == [(0, \"Nil\")];\n /// assert not new2\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes.\n /// Garbage collecting one of maps (e.g. after an assignment `m := Map.add(m, cmp, k, v)`)\n /// causes collecting `O(log(n))` nodes.\n public func insert<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K, value : V) : (Map<K, V>, Bool) {\n switch (swap(map, compare, key, value)) {\n case (map1, null) (map1, true);\n case (map1, _) (map1, false)\n }\n };\n\n /// Given `map` ordered by `compare`, add a new mapping from `key` to `value`.\n /// Replaces any existing entry with key `key`.\n /// Returns the modified map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// var map = Map.empty<Nat, Text>();\n ///\n /// map := Map.add(map, Nat.compare, 0, \"Zero\");\n /// map := Map.add(map, Nat.compare, 1, \"One\");\n /// map := Map.add(map, Nat.compare, 0, \"Nil\");\n ///\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Nil\"), (1, \"One\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes.\n /// Garbage collecting one of maps (e.g. after an assignment `m := Map.add(m, cmp, k, v)`)\n /// causes collecting `O(log(n))` nodes.\n public func add<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K, value : V) : Map<K, V> {\n swap(map, compare, key, value).0\n };\n\n /// Given `map` ordered by `compare`, add a mapping from `key` to `value`. Overwrites any existing entry with key `key`.\n /// Returns the modified map and the previous value associated with key `key`\n /// or `null` if no such value exists.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map0 = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// do {\n /// let (map1, old1) = Map.swap(map0, Nat.compare, 0, \"Nil\");\n /// assert Iter.toArray(Map.entries(map1)) == [(0, \"Nil\"), (1, \"One\"), (2, \"Two\")];\n /// assert old1 == ?\"Zero\";\n ///\n /// let (map2, old2) = Map.swap(map0, Nat.compare, 3, \"Three\");\n /// assert Iter.toArray(Map.entries(map2)) == [(0, \"Zero\"), (1, \"One\"), (2, \"Two\"), (3, \"Three\")];\n /// assert old2 == null;\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes.\n /// Garbage collecting one of maps (e.g. after an assignment `m := Map.swap(m, Nat.compare, k, v).0`)\n /// causes collecting `O(log(n))` nodes.\n public func swap<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K, value : V) : (Map<K, V>, ?V) {\n switch (Internal.swap(map.root, compare, key, value)) {\n case (t, null) { ({ root = t; size = map.size + 1 }, null) };\n case (t, v) { ({ root = t; size = map.size }, v) }\n }\n };\n\n /// Overwrites the value of an existing key and returns the updated map and previous value.\n /// If the key does not exist, returns the original map and `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let singleton = Map.singleton(0, \"Zero\");\n ///\n /// do {\n /// let (map1, prev1) = Map.replace(singleton, Nat.compare, 0, \"Nil\"); // overwrites the value for existing key.\n /// assert prev1 == ?\"Zero\";\n /// assert Map.get(map1, Nat.compare, 0) == ?\"Nil\";\n ///\n /// let (map2, prev2) = Map.replace(map1, Nat.compare, 1, \"One\"); // no effect, key is absent\n /// assert prev2 == null;\n /// assert Map.get(map2, Nat.compare, 1) == null;\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func replace<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K, value : V) : (Map<K, V>, ?V) {\n // TODO: Could be optimized in future\n if (containsKey(map, compare, key)) {\n swap(map, compare, key, value)\n } else { (map, null) }\n };\n\n /// Given a `map`, ordered by `compare`, deletes any entry for `key` from `map`.\n /// Has no effect if `key` is not present in the map.\n /// Returns the updated map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map0 =\n /// Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// let map1 = Map.remove(map0, Nat.compare, 1);\n /// assert Iter.toArray(Map.entries(map1)) == [(0, \"Zero\"), (2, \"Two\")];\n /// let map2 = Map.remove(map0, Nat.compare, 42);\n /// assert Iter.toArray(Map.entries(map2)) == [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes.\n /// Garbage collecting one of maps (e.g. after an assignment `map := Map.delete(map, compare, k).0`)\n /// causes collecting `O(log(n))` nodes.\n public func remove<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : Map<K, V> {\n switch (Internal.remove(map.root, compare, key)) {\n case (_, null) map;\n case (t, ?_) { { root = t; size = map.size - 1 } }\n }\n };\n\n /// Given a `map`, ordered by `compare`, deletes any entry for `key` from `map`.\n /// Has no effect if `key` is not present in the map.\n /// Returns the updated map and `true` if the `key` was present in `map`, otherwise `false`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map0 =\n /// Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// do {\n /// let (map1, pres1) = Map.delete(map0, Nat.compare, 1);\n /// assert Iter.toArray(Map.entries(map1)) == [(0, \"Zero\"), (2, \"Two\")];\n /// assert pres1;\n /// let (map2, pres2) = Map.delete(map0, Nat.compare, 42);\n /// assert not pres2;\n /// assert Iter.toArray(Map.entries(map2)) == [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")];\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes.\n /// Garbage collecting one of maps (e.g. after an assignment `map := Map.delete(map, compare, k).0`)\n /// causes collecting `O(log(n))` nodes.\n public func delete<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : (Map<K, V>, Bool) {\n switch (Internal.remove(map.root, compare, key)) {\n case (_, null) { (map, false) };\n case (t, ?_) { ({ root = t; size = map.size - 1 }, true) }\n }\n };\n\n /// Given a `map`, ordered by `compare`, deletes the entry for `key`. Returns a modified map, leaving `map` unchanged, and the\n /// previous value associated with `key` or `null` if no such value exists.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map0 = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// do {\n /// let (map1, prev1) = Map.take(map0, Nat.compare, 0);\n /// assert Iter.toArray(Map.entries(map1)) == [(1, \"One\"), (2, \"Two\")];\n /// assert prev1 == ?\"Zero\";\n ///\n /// let (map2, prev2) = Map.take(map0, Nat.compare, 42);\n /// assert Iter.toArray(Map.entries(map2)) == [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")];\n /// assert prev2 == null;\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes.\n /// Garbage collecting one of maps (e.g. after an assignment `map := Map.remove(map, compare, key)`)\n /// causes collecting `O(log(n))` nodes.\n public func take<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : (Map<K, V>, ?V) {\n switch (Internal.remove(map.root, compare, key)) {\n case (t, null) { ({ root = t; size = map.size }, null) };\n case (t, v) { ({ root = t; size = map.size - 1 }, v) }\n }\n };\n\n /// Given a `map` retrieves the key-value pair in `map` with a maximal key. If `map` is empty returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Map.maxEntry(map) == ?(2, \"Two\");\n /// assert Map.maxEntry(Map.empty<Nat, Text>()) == null;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func maxEntry<K, V>(map : Map<K, V>) : ?(K, V) = Internal.maxEntry(map.root);\n\n /// Retrieves a key-value pair from `map` with the minimal key. If the map is empty returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Map.minEntry(map) == ?(0, \"Zero\");\n /// assert Map.minEntry(Map.empty()) == null;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func minEntry<K, V>(map : Map<K, V>) : ?(K, V) = Internal.minEntry(map.root);\n\n /// Returns an Iterator (`Iter`) over the key-value pairs in the map.\n /// Iterator provides a single method `next()`, which returns\n /// pairs in ascending order by keys, or `null` when out of pairs to iterate over.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")];\n /// var sum = 0;\n /// var text = \"\";\n /// for ((k, v) in Map.entries(map)) { sum += k; text #= v };\n /// assert sum == 3;\n /// assert text == \"ZeroOneTwo\"\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func entries<K, V>(map : Map<K, V>) : Iter.Iter<(K, V)> = Internal.iter(map.root, #fwd);\n\n /// Returns an Iterator (`Iter`) over the key-value pairs in the map.\n /// Iterator provides a single method `next()`, which returns\n /// pairs in descending order by keys, or `null` when out of pairs to iterate over.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Iter.toArray(Map.reverseEntries(map)) == [(2, \"Two\"), (1, \"One\"), (0, \"Zero\")];\n /// var sum = 0;\n /// var text = \"\";\n /// for ((k, v) in Map.reverseEntries(map)) { sum += k; text #= v };\n /// assert sum == 3;\n /// assert text == \"TwoOneZero\"\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func reverseEntries<K, V>(map : Map<K, V>) : Iter.Iter<(K, V)> = Internal.iter(map.root, #bwd);\n\n /// Given a `map`, returns an Iterator (`Iter`) over the keys of the `map`.\n /// Iterator provides a single method `next()`, which returns\n /// keys in ascending order, or `null` when out of keys to iterate over.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Iter.toArray(Map.keys(map)) == [0, 1, 2];\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func keys<K, V>(map : Map<K, V>) : Iter.Iter<K> = Iter.map(entries(map), func(kv : (K, V)) : K { kv.0 });\n\n /// Given a `map`, returns an Iterator (`Iter`) over the values of the map.\n /// Iterator provides a single method `next()`, which returns\n /// values in ascending order of associated keys, or `null` when out of values to iterate over.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Iter.toArray(Map.values(map)) == [\"Zero\", \"One\", \"Two\"];\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func values<K, V>(map : Map<K, V>) : Iter.Iter<V> = Iter.map(entries(map), func(kv : (K, V)) : V { kv.1 });\n\n /// Returns a new map, containing all entries given by the iterator `i`.\n /// If there are multiple entries with the same key the last one is taken.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// transient let iter =\n /// Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]);\n ///\n /// let map = Map.fromIter(iter, Nat.compare);\n ///\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func fromIter<K, V>(iter : Iter.Iter<(K, V)>, compare : (K, K) -> Order.Order) : Map<K, V> = Internal.fromIter(iter, compare);\n\n /// Given a `map` and function `f`, creates a new map by applying `f` to each entry in the map `m`. Each entry\n /// `(k, v)` in the old map is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is created by applying `f` to `(k, v)`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// func f(key : Nat, _val : Text) : Nat = key * 2;\n ///\n /// let resMap = Map.map(map, f);\n ///\n /// assert Iter.toArray(Map.entries(resMap)) == [(0, 0), (1, 2), (2, 4)];\n /// }\n /// ```\n ///\n /// Cost of mapping all the elements:\n /// Runtime: `O(n)`.\n /// Space: `O(n)` retained memory\n /// where `n` denotes the number of key-value entries stored in the map.\n public func map<K, V1, V2>(map : Map<K, V1>, f : (K, V1) -> V2) : Map<K, V2> = Internal.map(map, f);\n\n /// Collapses the elements in the `map` into a single value by starting with `base`\n /// and progressively combining keys and values into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// func folder(accum : (Nat, Text), key : Nat, val : Text) : ((Nat, Text))\n /// = (key + accum.0, accum.1 # val);\n ///\n /// assert Map.foldLeft(map, (0, \"\"), folder) == (3, \"ZeroOneTwo\");\n /// }\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: depends on `combine` function plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func foldLeft<K, V, A>(\n map : Map<K, V>,\n base : A,\n combine : (A, K, V) -> A\n ) : A = Internal.foldLeft(map.root, base, combine);\n\n /// Collapses the elements in the `map` into a single value by starting with `base`\n /// and progressively combining keys and values into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// func folder(key : Nat, val : Text, accum : (Nat, Text)) : ((Nat, Text))\n /// = (key + accum.0, accum.1 # val);\n ///\n /// assert Map.foldRight(map, (0, \"\"), folder) == (3, \"TwoOneZero\");\n /// }\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: depends on `combine` function plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func foldRight<K, V, A>(\n map : Map<K, V>,\n base : A,\n combine : (K, V, A) -> A\n ) : A = Internal.foldRight(map.root, base, combine);\n\n /// Test whether all key-value pairs in `map` satisfy the given predicate `pred`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"0\"), (2, \"2\"), (1, \"1\")].values(), Nat.compare);\n ///\n /// assert Map.all<Nat, Text>(map, func (k, v) = v == Nat.toText(k));\n /// assert not Map.all<Nat, Text>(map, func (k, v) = k < 2);\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func all<K, V>(map : Map<K, V>, pred : (K, V) -> Bool) : Bool = Internal.all(map.root, pred);\n\n /// Test if any key-value pair in `map` satisfies the given predicate `pred`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"0\"), (2, \"2\"), (1, \"1\")].values(), Nat.compare);\n ///\n /// assert Map.any<Nat, Text>(map, func (k, v) = (k >= 0));\n /// assert not Map.any<Nat, Text>(map, func (k, v) = (k >= 3));\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func any<K, V>(map : Map<K, V>, pred : (K, V) -> Bool) : Bool = Internal.any(map.root, pred);\n\n /// Create a new immutable key-value `map` with a single entry.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.singleton<Nat, Text>(0, \"Zero\");\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func singleton<K, V>(key : K, value : V) : Map<K, V> {\n {\n size = 1;\n root = #red(#leaf, key, value, #leaf)\n }\n };\n\n /// Apply an operation for each key-value pair contained in the map.\n /// The operation is applied in ascending order of the keys.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n /// var sum = 0;\n /// var text = \"\";\n /// Map.forEach<Nat, Text>(map, func (key, value) {\n /// sum += key;\n /// text #= value;\n /// });\n /// assert sum == 3;\n /// assert text == \"ZeroOneTwo\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func forEach<K, V>(map : Map<K, V>, operation : (K, V) -> ()) = Internal.forEach(map, operation);\n\n /// Filter entries in a new map.\n /// Returns a new map that only contains the key-value pairs\n /// that fulfil the criterion function.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let numberNames = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// let evenNames = Map.filter<Nat, Text>(numberNames, Nat.compare, func (key, value) {\n /// key % 2 == 0\n /// });\n ///\n /// assert Iter.toArray(Map.entries(evenNames)) == [(0, \"Zero\"), (2, \"Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func filter<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, criterion : (K, V) -> Bool) : Map<K, V> = Internal.filter(map, compare, criterion);\n\n /// Given a `map`, comparison `compare` and function `f`,\n /// constructs a new map ordered by `compare`, by applying `f` to each entry in `map`.\n /// For each entry `(k, v)` in the old map, if `f` evaluates to `null`, the entry is discarded.\n /// Otherwise, the entry is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is the result of applying `f` to `(k, v)`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// func f(key : Nat, val : Text) : ?Text {\n /// if(key == 0) {null}\n /// else { ?(\"Twenty \" # val)}\n /// };\n ///\n /// let newMap = Map.filterMap(map, Nat.compare, f);\n ///\n /// assert Iter.toArray(Map.entries(newMap)) == [(1, \"Twenty One\"), (2, \"Twenty Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func filterMap<K, V1, V2>(map : Map<K, V1>, compare : (K, K) -> Order.Order, f : (K, V1) -> ?V2) : Map<K, V2> = Internal.mapFilter(map, compare : (K, K) -> Order.Order, f);\n\n /// Validate the representation invariants of the given `map`.\n /// Assert if any invariants are violated.\n public func assertValid<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order) : () = Internal.validate(map, compare);\n\n /// Converts the `map` to its textual representation using `keyFormat` and `valueFormat` to convert each key and value to `Text`.\n ///\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n /// assert Map.toText<Nat, Text>(map, Nat.toText, func t { t }) == \"PureMap{(0, Zero), (1, One), (2, Two)}\";\n /// }\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `keyFormat` and `valueFormat` run in O(1) time and space.\n public func toText<K, V>(map : Map<K, V>, keyFormat : K -> Text, valueFormat : V -> Text) : Text {\n var text = \"PureMap{\";\n var sep = \"\";\n for ((k, v) in entries(map)) {\n text #= sep # \"(\" # keyFormat(k) # \", \" # valueFormat(v) # \")\";\n sep := \", \"\n };\n text # \"}\"\n };\n\n /// Test whether two immutable maps have equal entries.\n /// Assumes both maps are ordered equivalently.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// persistent actor {\n /// let map1 = Map.fromIter([(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(), Nat.compare);\n /// let map2 = Map.fromIter<Nat, Text>([(2, \"Two\"), (1, \"One\"), (0, \"Zero\")].values(), Nat.compare);\n /// assert(Map.equal(map1, map2, Nat.compare, Text.equal));\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n public func equal<K, V>(map1 : Map<K, V>, map2 : Map<K, V>, compareKey : (K, K) -> Order.Order, equalValue : (V, V) -> Bool) : Bool {\n if (map1.size != map2.size) {\n return false\n };\n let iterator1 = entries(map1);\n let iterator2 = entries(map2);\n loop {\n let next1 = iterator1.next();\n let next2 = iterator2.next();\n switch (next1, next2) {\n case (null, null) {\n return true\n };\n case (?(key1, value1), ?(key2, value2)) {\n if (not (compareKey(key1, key2) == #equal) or not equalValue(value1, value2)) {\n return false\n }\n };\n case _ { return false }\n }\n }\n };\n\n /// Compare two maps by primarily comparing keys and secondarily values.\n /// Both maps are iterated by the ascending order of their creation and\n /// order is determined by the following rules:\n /// Less:\n /// `map1` is less than `map2` if:\n /// * the pairwise iteration hits a entry pair `entry1` and `entry2` where\n /// `entry1` is less than `entry2` and all preceding entry pairs are equal, or,\n /// * `map1` is a strict prefix of `map2`, i.e. `map2` has more entries than `map1`\n /// and all entries of `map1` occur at the beginning of iteration `map2`.\n /// `entry1` is less than `entry2` if:\n /// * the key of `entry1` is less than the key of `entry2`, or\n /// * `entry1` and `entry2` have equal keys and the value of `entry1` is less than\n /// the value of `entry2`.\n /// Equal:\n /// `map1` and `map2` have same series of equal entries by pairwise iteration.\n /// Greater:\n /// `map1` is neither less nor equal `map2`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// persistent actor {\n /// let map1 = Map.fromIter([(0, \"Zero\"), (1, \"One\")].values(), Nat.compare);\n /// let map2 = Map.fromIter([(0, \"Zero\"), (2, \"Two\")].values(), Nat.compare);\n ///\n /// assert Map.compare(map1, map2, Nat.compare, Text.compare) == #less;\n /// assert Map.compare(map1, map1, Nat.compare, Text.compare) == #equal;\n /// assert Map.compare(map2, map1, Nat.compare, Text.compare) == #greater\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that `compareKey` and `compareValue` have runtime and space costs of `O(1)`.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func compare<K, V>(map1 : Map<K, V>, map2 : Map<K, V>, compareKey : (K, K) -> Order.Order, compareValue : (V, V) -> Order.Order) : Order.Order {\n let iterator1 = entries(map1);\n let iterator2 = entries(map2);\n loop {\n switch (iterator1.next(), iterator2.next()) {\n case (null, null) return #equal;\n case (null, _) return #less;\n case (_, null) return #greater;\n case (?(key1, value1), ?(key2, value2)) {\n let keyComparison = compareKey(key1, key2);\n if (keyComparison != #equal) {\n return keyComparison\n };\n let valueComparison = compareValue(value1, value2);\n if (valueComparison != #equal) {\n return valueComparison\n }\n }\n }\n }\n };\n\n module Internal {\n\n public func empty<K, V>() : Map<K, V> { { size = 0; root = #leaf } };\n\n public func fromIter<K, V>(i : Iter.Iter<(K, V)>, compare : (K, K) -> Order.Order) : Map<K, V> {\n var map = #leaf : Tree<K, V>;\n var size = 0;\n for (val in i) {\n map := add(map, compare, val.0, val.1);\n size += 1\n };\n { root = map; size }\n };\n\n type List<T> = Types.Pure.List<T>;\n\n type IterRep<K, V> = List<{ #tr : Tree<K, V>; #xy : (K, V) }>;\n\n public func iter<K, V>(map : Tree<K, V>, direction : { #fwd; #bwd }) : Iter.Iter<(K, V)> {\n let turnLeftFirst : MapTraverser<K, V> = func(l, x, y, r, ts) {\n ?(#tr(l), ?(#xy(x, y), ?(#tr(r), ts)))\n };\n\n let turnRightFirst : MapTraverser<K, V> = func(l, x, y, r, ts) {\n ?(#tr(r), ?(#xy(x, y), ?(#tr(l), ts)))\n };\n\n switch direction {\n case (#fwd) IterMap(map, turnLeftFirst);\n case (#bwd) IterMap(map, turnRightFirst)\n }\n };\n\n type MapTraverser<K, V> = (Tree<K, V>, K, V, Tree<K, V>, IterRep<K, V>) -> IterRep<K, V>;\n\n class IterMap<K, V>(tree : Tree<K, V>, mapTraverser : MapTraverser<K, V>) {\n var trees : IterRep<K, V> = ?(#tr(tree), null);\n public func next() : ?(K, V) {\n switch (trees) {\n case (null) { null };\n case (?(#tr(#leaf), ts)) {\n trees := ts;\n next()\n };\n case (?(#xy(xy), ts)) {\n trees := ts;\n ?xy\n };\n case (?(#tr(#red(l, x, y, r)), ts)) {\n trees := mapTraverser(l, x, y, r, ts);\n next()\n };\n case (?(#tr(#black(l, x, y, r)), ts)) {\n trees := mapTraverser(l, x, y, r, ts);\n next()\n }\n }\n }\n };\n\n public func map<K, V1, V2>(map : Map<K, V1>, f : (K, V1) -> V2) : Map<K, V2> {\n func mapRec(m : Tree<K, V1>) : Tree<K, V2> {\n switch m {\n case (#leaf) { #leaf };\n case (#red(l, x, y, r)) {\n #red(mapRec l, x, f(x, y), mapRec r)\n };\n case (#black(l, x, y, r)) {\n #black(mapRec l, x, f(x, y), mapRec r)\n }\n }\n };\n { size = map.size; root = mapRec(map.root) }\n };\n\n public func foldLeft<Key, Value, Accum>(\n map : Tree<Key, Value>,\n base : Accum,\n combine : (Accum, Key, Value) -> Accum\n ) : Accum {\n switch (map) {\n case (#leaf) { base };\n case (#red(l, k, v, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, k, v);\n foldLeft(r, middle, combine)\n };\n case (#black(l, k, v, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, k, v);\n foldLeft(r, middle, combine)\n }\n }\n };\n\n public func foldRight<Key, Value, Accum>(\n map : Tree<Key, Value>,\n base : Accum,\n combine : (Key, Value, Accum) -> Accum\n ) : Accum {\n switch (map) {\n case (#leaf) { base };\n case (#red(l, k, v, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(k, v, right);\n foldRight(l, middle, combine)\n };\n case (#black(l, k, v, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(k, v, right);\n foldRight(l, middle, combine)\n }\n }\n };\n\n public func forEach<K, V>(map : Map<K, V>, operation : (K, V) -> ()) {\n func combine(_acc : Null, key : K, value : V) : Null {\n operation(key, value);\n null\n };\n ignore foldLeft(map.root, null, combine)\n };\n\n public func filter<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, criterion : (K, V) -> Bool) : Map<K, V> {\n var size = 0;\n func combine(acc : Tree<K, V>, key : K, value : V) : Tree<K, V> {\n if (criterion(key, value)) {\n size += 1;\n add(acc, compare, key, value)\n } else acc\n };\n { root = foldLeft(map.root, #leaf, combine); size }\n };\n\n public func mapFilter<K, V1, V2>(map : Map<K, V1>, compare : (K, K) -> Order.Order, f : (K, V1) -> ?V2) : Map<K, V2> {\n var size = 0;\n func combine(acc : Tree<K, V2>, key : K, value1 : V1) : Tree<K, V2> {\n switch (f(key, value1)) {\n case null { acc };\n case (?value2) {\n size += 1;\n add(acc, compare, key, value2)\n }\n }\n };\n { root = foldLeft(map.root, #leaf, combine); size }\n };\n\n public func get<K, V>(t : Tree<K, V>, compare : (K, K) -> Order.Order, x : K) : ?V {\n switch t {\n case (#red(l, x1, y1, r)) {\n switch (compare(x, x1)) {\n case (#less) { get(l, compare, x) };\n case (#equal) { ?y1 };\n case (#greater) { get(r, compare, x) }\n }\n };\n case (#black(l, x1, y1, r)) {\n switch (compare(x, x1)) {\n case (#less) { get(l, compare, x) };\n case (#equal) { ?y1 };\n case (#greater) { get(r, compare, x) }\n }\n };\n case (#leaf) { null }\n }\n };\n\n public func contains<K, V>(m : Tree<K, V>, compare : (K, K) -> Order.Order, key : K) : Bool {\n switch (get(m, compare, key)) {\n case (null) { false };\n case (_) { true }\n }\n };\n\n public func maxEntry<K, V>(m : Tree<K, V>) : ?(K, V) {\n func rightmost(m : Tree<K, V>) : (K, V) {\n switch m {\n case (#red(_, k, v, #leaf)) { (k, v) };\n case (#red(_, _, _, r)) { rightmost(r) };\n case (#black(_, k, v, #leaf)) { (k, v) };\n case (#black(_, _, _, r)) { rightmost(r) };\n case (#leaf) { Runtime.trap \"pure/Map.maxEntry() impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?rightmost(m) }\n }\n };\n\n public func minEntry<K, V>(m : Tree<K, V>) : ?(K, V) {\n func leftmost(m : Tree<K, V>) : (K, V) {\n switch m {\n case (#red(#leaf, k, v, _)) { (k, v) };\n case (#red(l, _, _, _)) { leftmost(l) };\n case (#black(#leaf, k, v, _)) { (k, v) };\n case (#black(l, _, _, _)) { leftmost(l) };\n case (#leaf) { Runtime.trap \"pure/Map.minEntry() impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?leftmost(m) }\n }\n };\n\n public func all<K, V>(m : Tree<K, V>, pred : (K, V) -> Bool) : Bool {\n switch m {\n case (#red(l, k, v, r)) {\n pred(k, v) and all(l, pred) and all(r, pred)\n };\n case (#black(l, k, v, r)) {\n pred(k, v) and all(l, pred) and all(r, pred)\n };\n case (#leaf) { true }\n }\n };\n\n public func any<K, V>(m : Tree<K, V>, pred : (K, V) -> Bool) : Bool {\n switch m {\n case (#red(l, k, v, r)) {\n pred(k, v) or any(l, pred) or any(r, pred)\n };\n case (#black(l, k, v, r)) {\n pred(k, v) or any(l, pred) or any(r, pred)\n };\n case (#leaf) { false }\n }\n };\n\n func redden<K, V>(t : Tree<K, V>) : Tree<K, V> {\n switch t {\n case (#black(l, x, y, r)) { (#red(l, x, y, r)) };\n case _ {\n Runtime.trap \"pure/Map.redden() impossible\"\n }\n }\n };\n\n func lbalance<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#red(#red(l1, x1, y1, r1), x2, y2, r2), r) {\n #red(\n #black(l1, x1, y1, r1),\n x2,\n y2,\n #black(r2, x, y, r)\n )\n };\n case (#red(l1, x1, y1, #red(l2, x2, y2, r2)), r) {\n #red(\n #black(l1, x1, y1, l2),\n x2,\n y2,\n #black(r2, x, y, r)\n )\n };\n case _ {\n #black(left, x, y, right)\n }\n }\n };\n\n func rbalance<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (l, #red(l1, x1, y1, #red(l2, x2, y2, r2))) {\n #red(\n #black(l, x, y, l1),\n x1,\n y1,\n #black(l2, x2, y2, r2)\n )\n };\n case (l, #red(#red(l1, x1, y1, r1), x2, y2, r2)) {\n #red(\n #black(l, x, y, l1),\n x1,\n y1,\n #black(r1, x2, y2, r2)\n )\n };\n case _ {\n #black(left, x, y, right)\n }\n }\n };\n\n type ClashResolver<A> = { old : A; new : A } -> A;\n\n func insertWith<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> Order.Order,\n key : K,\n val : V,\n onClash : ClashResolver<V>\n ) : Tree<K, V> {\n func ins(tree : Tree<K, V>) : Tree<K, V> {\n switch tree {\n case (#black(left, x, y, right)) {\n switch (compare(key, x)) {\n case (#less) {\n lbalance(ins left, x, y, right)\n };\n case (#greater) {\n rbalance(left, x, y, ins right)\n };\n case (#equal) {\n let newVal = onClash({ new = val; old = y });\n #black(left, key, newVal, right)\n }\n }\n };\n case (#red(left, x, y, right)) {\n switch (compare(key, x)) {\n case (#less) {\n #red(ins left, x, y, right)\n };\n case (#greater) {\n #red(left, x, y, ins right)\n };\n case (#equal) {\n let newVal = onClash { new = val; old = y };\n #red(left, key, newVal, right)\n }\n }\n };\n case (#leaf) {\n #red(#leaf, key, val, #leaf)\n }\n }\n };\n switch (ins m) {\n case (#red(left, x, y, right)) {\n #black(left, x, y, right)\n };\n case other { other }\n }\n };\n\n public func swap<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> Order.Order,\n key : K,\n val : V\n ) : (Tree<K, V>, ?V) {\n var oldVal : ?V = null;\n func onClash(clash : { old : V; new : V }) : V {\n oldVal := ?clash.old;\n clash.new\n };\n let res = insertWith(m, compare, key, val, onClash);\n (res, oldVal)\n };\n\n public func add<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> Order.Order,\n key : K,\n val : V\n ) : Tree<K, V> = swap(m, compare, key, val).0;\n\n func balLeft<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#red(l1, x1, y1, r1), r) {\n #red(\n #black(l1, x1, y1, r1),\n x,\n y,\n r\n )\n };\n case (_, #black(l2, x2, y2, r2)) {\n rbalance(left, x, y, #red(l2, x2, y2, r2))\n };\n case (_, #red(#black(l2, x2, y2, r2), x3, y3, r3)) {\n #red(\n #black(left, x, y, l2),\n x2,\n y2,\n rbalance(r2, x3, y3, redden r3)\n )\n };\n case _ { Runtime.trap \"pure/Map.balLeft() impossible\" }\n }\n };\n\n func balRight<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (l, #red(l1, x1, y1, r1)) {\n #red(\n l,\n x,\n y,\n #black(l1, x1, y1, r1)\n )\n };\n case (#black(l1, x1, y1, r1), r) {\n lbalance(#red(l1, x1, y1, r1), x, y, r)\n };\n case (#red(l1, x1, y1, #black(l2, x2, y2, r2)), r3) {\n #red(\n lbalance(redden l1, x1, y1, l2),\n x2,\n y2,\n #black(r2, x, y, r3)\n )\n };\n case _ { Runtime.trap \"pure/Map.balRight() impossible\" }\n }\n };\n\n func append<K, V>(left : Tree<K, V>, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#leaf, _) { right };\n case (_, #leaf) { left };\n case (\n #red(l1, x1, y1, r1),\n #red(l2, x2, y2, r2)\n ) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, y3, r3)) {\n #red(\n #red(l1, x1, y1, l3),\n x3,\n y3,\n #red(r3, x2, y2, r2)\n )\n };\n case r1l2 {\n #red(l1, x1, y1, #red(r1l2, x2, y2, r2))\n }\n }\n };\n case (t1, #red(l2, x2, y2, r2)) {\n #red(append(t1, l2), x2, y2, r2)\n };\n case (#red(l1, x1, y1, r1), t2) {\n #red(l1, x1, y1, append(r1, t2))\n };\n case (#black(l1, x1, y1, r1), #black(l2, x2, y2, r2)) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, y3, r3)) {\n #red(\n #black(l1, x1, y1, l3),\n x3,\n y3,\n #black(r3, x2, y2, r2)\n )\n };\n case r1l2 {\n balLeft(\n l1,\n x1,\n y1,\n #black(r1l2, x2, y2, r2)\n )\n }\n }\n }\n }\n };\n\n public func delete<K, V>(m : Tree<K, V>, compare : (K, K) -> Order.Order, key : K) : Tree<K, V> = remove(m, compare, key).0;\n\n public func remove<K, V>(tree : Tree<K, V>, compare : (K, K) -> Order.Order, x : K) : (Tree<K, V>, ?V) {\n var y0 : ?V = null;\n func delNode(left : Tree<K, V>, x1 : K, y1 : V, right : Tree<K, V>) : Tree<K, V> {\n switch (compare(x, x1)) {\n case (#less) {\n let newLeft = del left;\n switch left {\n case (#black(_, _, _, _)) {\n balLeft(newLeft, x1, y1, right)\n };\n case _ {\n #red(newLeft, x1, y1, right)\n }\n }\n };\n case (#greater) {\n let newRight = del right;\n switch right {\n case (#black(_, _, _, _)) {\n balRight(left, x1, y1, newRight)\n };\n case _ {\n #red(left, x1, y1, newRight)\n }\n }\n };\n case (#equal) {\n y0 := ?y1;\n append(left, right)\n }\n }\n };\n func del(tree : Tree<K, V>) : Tree<K, V> {\n switch tree {\n case (#red(left, x, y, right)) {\n delNode(left, x, y, right)\n };\n case (#black(left, x, y, right)) {\n delNode(left, x, y, right)\n };\n case (#leaf) {\n tree\n }\n }\n };\n switch (del(tree)) {\n case (#red(left, x, y, right)) { (#black(left, x, y, right), y0) };\n case other { (other, y0) }\n }\n };\n\n // Test helper\n public func validate<K, V>(rbMap : Map<K, V>, comp : (K, K) -> Order.Order) {\n ignore blackDepth(rbMap.root, comp)\n };\n\n func blackDepth<K, V>(node : Tree<K, V>, comp : (K, K) -> Order.Order) : Nat {\n func checkNode(left : Tree<K, V>, key : K, right : Tree<K, V>) : Nat {\n checkKey(left, func(x : K) : Bool { comp(x, key) == #less });\n checkKey(right, func(x : K) : Bool { comp(x, key) == #greater });\n let leftBlacks = blackDepth(left, comp);\n let rightBlacks = blackDepth(right, comp);\n assert (leftBlacks == rightBlacks);\n leftBlacks\n };\n switch node {\n case (#leaf) 0;\n case (#red(left, key, _, right)) {\n let leftBlacks = checkNode(left, key, right);\n assert (not isRed(left));\n assert (not isRed(right));\n leftBlacks\n };\n case (#black(left, key, _, right)) {\n checkNode(left, key, right) + 1\n }\n }\n };\n\n func isRed<K, V>(node : Tree<K, V>) : Bool {\n switch node {\n case (#red(_, _, _, _)) true;\n case _ false\n }\n };\n\n func checkKey<K, V>(node : Tree<K, V>, isValid : K -> Bool) {\n switch node {\n case (#leaf) {};\n case (#red(_, key, _, _)) {\n assert (isValid(key))\n };\n case (#black(_, key, _, _)) {\n assert (isValid(key))\n }\n }\n }\n };\n\n}\n"},"pure/RealTimeQueue.mo":{"content":"/// Double-ended immutable queue with guaranteed `O(1)` push/pop operations (caveat: high constant factor).\n/// For a default immutable queue implementation, see `pure/Queue`.\n///\n/// This module provides an alternative implementation with better worst-case performance for single operations, e.g. `pushBack` and `popFront`.\n/// These operations are always constant time, `O(1)`, which eliminates spikes in performance of `pure/Queue` operations\n/// that are caused by the amortized nature of the `pure/Queue` implementation, which can lead to `O(n)` worst-case performance for a single operation.\n/// The spikes in performance can cause a single message to take multiple more rounds to complete than most other messages.\n///\n/// However, the `O(1)` operations come at a cost of higher constant factor than the `pure/Queue` implementation:\n/// - 'pop' operations are on average 3x more expensive\n/// - 'push' operations are on average 8x more expensive\n///\n/// For better performance across multiple operations and when the spikes in single operations are not a problem, use `pure/Queue`.\n/// For guaranteed `O(1)` operations, use `pure/RealTimeQueue`.\n///\n/// ---\n///\n/// The interface is purely functional, not imperative, and queues are immutable values.\n/// In particular, Queue operations such as push and pop do not update their input queue but, instead, return the\n/// value of the modified Queue, alongside any other data.\n/// The input queue is left unchanged.\n///\n/// Examples of use-cases:\n/// - Queue (FIFO) by using `pushBack()` and `popFront()`.\n/// - Stack (LIFO) by using `pushFront()` and `popFront()`.\n/// - Deque (double-ended queue) by using any combination of push/pop operations on either end.\n///\n/// A Queue is internally implemented as a real-time double-ended queue based on the paper\n/// \"Real-Time Double-Ended Queue Verified (Proof Pearl)\". The implementation maintains\n/// worst-case constant time `O(1)` for push/pop operations through gradual rebalancing steps.\n///\n/// Construction: Create a new queue with the `empty<T>()` function.\n///\n/// Note that some operations that traverse the elements of the queue (e.g. `forEach`, `values`) preserve the order of the elements,\n/// whereas others (e.g. `map`, `contains`) do NOT guarantee that the elements are visited in any order.\n/// The order is undefined to avoid allocations, making these operations more efficient.\n///\n/// ```motoko name=import\n/// import Queue \"mo:core/pure/RealTimeQueue\";\n/// ```\n\nimport Types \"../Types\";\nimport List \"List\";\nimport Option \"../Option\";\nimport { trap } \"../Runtime\";\nimport Iter \"../Iter\";\n\nmodule {\n /// The real-time queue data structure can be in one of the following states:\n ///\n /// - `#empty`: the queue is empty\n /// - `#one`: the queue contains a single element\n /// - `#two`: the queue contains two elements\n /// - `#three`: the queue contains three elements\n /// - `#idles`: the queue is in the idle state, where `l` and `r` are non-empty stacks of elements fulfilling the size invariant\n /// - `#rebal`: the queue is in the rebalancing state\n public type Queue<T> = {\n #empty;\n #one : T;\n #two : (T, T);\n #three : (T, T, T);\n #idles : (Idle<T>, Idle<T>);\n #rebal : States<T>\n };\n\n /// Create a new empty queue.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.empty<Nat>();\n /// assert Queue.isEmpty(queue);\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func empty<T>() : Queue<T> = #empty;\n\n /// Determine whether a queue is empty.\n /// Returns true if `queue` is empty, otherwise `false`.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.empty<Nat>();\n /// assert Queue.isEmpty(queue);\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func isEmpty<T>(queue : Queue<T>) : Bool = switch queue {\n case (#empty) true;\n case _ false\n };\n\n /// Create a new queue comprising a single element.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.singleton<Nat>(25);\n /// assert Queue.size(queue) == 1;\n /// assert Queue.peekFront(queue) == ?25;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func singleton<T>(element : T) : Queue<T> = #one(element);\n\n /// Determine the number of elements contained in a queue.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.singleton<Nat>(42);\n /// assert Queue.size(queue) == 1;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func size<T>(queue : Queue<T>) : Nat = switch queue {\n case (#empty) 0;\n case (#one _) 1;\n case (#two _) 2;\n case (#three _) 3;\n case (#idles((l, nL), (r, nR))) {\n debug assert Stacks.size(l) == nL and Stacks.size(r) == nR;\n nL + nR\n };\n case (#rebal(_, big, small)) BigState.size(big) + SmallState.size(small)\n };\n\n /// Test if a queue contains a given value.\n /// Returns true if the queue contains the item, otherwise false.\n ///\n /// Note: The order in which elements are visited is undefined, for performance reasons.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue = Queue.pushBack(Queue.pushBack(Queue.empty<Nat>(), 1), 2);\n /// assert Queue.contains(queue, Nat.equal, 1);\n /// assert not Queue.contains(queue, Nat.equal, 3);\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(1)`\n public func contains<T>(queue : Queue<T>, eq : (T, T) -> Bool, item : T) : Bool = switch queue {\n case (#empty) false;\n case (#one(x)) eq(x, item);\n case (#two(x, y)) eq(x, item) or eq(y, item);\n case (#three(x, y, z)) eq(x, item) or eq(y, item) or eq(z, item);\n case (#idles(((l1, l2), _), ((r1, r2), _))) List.contains(l1, eq, item) or List.contains(l2, eq, item) or List.contains(r2, eq, item) or List.contains(r1, eq, item); // note that the order of the right stack is reversed, but for this operation it does not matter\n case (#rebal(_, big, small)) {\n let (extraB, _, (oldB1, oldB2), _) = BigState.current(big);\n let (extraS, _, (oldS1, oldS2), _) = SmallState.current(small);\n // note that the order of one of the stacks is reversed (depending on the `direction` field), but for this operation it does not matter\n List.contains(extraB, eq, item) or List.contains(oldB1, eq, item) or List.contains(oldB2, eq, item) or List.contains(extraS, eq, item) or List.contains(oldS1, eq, item) or List.contains(oldS2, eq, item)\n }\n };\n\n /// Inspect the optional element on the front end of a queue.\n /// Returns `null` if `queue` is empty. Otherwise, the front element of `queue`.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.pushFront(Queue.pushFront(Queue.empty<Nat>(), 2), 1);\n /// assert Queue.peekFront(queue) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func peekFront<T>(queue : Queue<T>) : ?T = switch queue {\n case (#idles((l, _), _)) Stacks.first(l);\n case (#rebal(dir, big, small)) switch dir {\n case (#left) ?SmallState.peek(small);\n case (#right) ?BigState.peek(big)\n };\n case (#empty) null;\n case (#one(x)) ?x;\n case (#two(x, _)) ?x;\n case (#three(x, _, _)) ?x\n };\n\n /// Inspect the optional element on the back end of a queue.\n /// Returns `null` if `queue` is empty. Otherwise, the back element of `queue`.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.pushFront(Queue.pushFront(Queue.empty<Nat>(), 2), 1);\n /// assert Queue.peekBack(queue) == ?2;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func peekBack<T>(queue : Queue<T>) : ?T = switch queue {\n case (#idles(_, (r, _))) Stacks.first(r);\n case (#rebal(dir, big, small)) switch dir {\n case (#left) ?BigState.peek(big);\n case (#right) ?SmallState.peek(small)\n };\n case (#empty) null;\n case (#one(x)) ?x;\n case (#two(_, y)) ?y;\n case (#three(_, _, z)) ?z\n };\n\n /// Insert a new element on the front end of a queue.\n /// Returns the new queue with `element` in the front followed by the elements of `queue`.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.pushFront(Queue.pushFront(Queue.empty<Nat>(), 2), 1);\n /// assert Queue.peekFront(queue) == ?1;\n /// assert Queue.peekBack(queue) == ?2;\n /// assert Queue.size(queue) == 2;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)` worst-case!\n ///\n /// Space: `O(1)` worst-case!\n public func pushFront<T>(queue : Queue<T>, element : T) : Queue<T> = switch queue {\n case (#idles(l0, rnR)) {\n let lnL = Idle.push(l0, element); // enque the element to the left end\n // check if the size invariant still holds\n if (3 * rnR.1 >= lnL.1) {\n debug assert 3 * lnL.1 >= rnR.1;\n #idles(lnL, rnR)\n } else {\n // initiate the rebalancing process\n let (l, nL) = lnL;\n let (r, nR) = rnR;\n let targetSizeL = nL - nR - 1 : Nat;\n let targetSizeR = 2 * nR + 1;\n debug assert targetSizeL + targetSizeR == nL + nR;\n let big = #big1(Current.new(l, targetSizeL), l, null, targetSizeL);\n let small = #small1(Current.new(r, targetSizeR), r, null);\n let states = (#right, big, small);\n let states6 = States.step(States.step(States.step(States.step(States.step(States.step(states))))));\n #rebal(states6)\n }\n };\n // if the queue is in the middle of a rebalancing process: push the element and advance the rebalancing process by 4 steps\n // move back into the idle state if the rebalancing is done\n case (#rebal(dir, big0, small0)) switch dir {\n case (#right) {\n let big = BigState.push(big0, element);\n let states4 = States.step(States.step(States.step(States.step((#right, big, small0)))));\n debug assert states4.0 == #right;\n switch states4 {\n case (_, #big2(#idle(_, big)), #small3(#idle(_, small))) {\n debug assert idlesInvariant(big, small);\n #idles(big, small)\n };\n case _ #rebal(states4)\n }\n };\n case (#left) {\n let small = SmallState.push(small0, element);\n let states4 = States.step(States.step(States.step(States.step((#left, big0, small)))));\n debug assert states4.0 == #left;\n switch states4 {\n case (_, #big2(#idle(_, big)), #small3(#idle(_, small))) {\n debug assert idlesInvariant(small, big);\n #idles(small, big) // swapped because dir=left\n };\n case _ #rebal(states4)\n }\n }\n };\n case (#empty) #one(element);\n case (#one(y)) #two(element, y);\n case (#two(y, z)) #three(element, y, z);\n case (#three(a, b, c)) {\n let i1 = ((?(element, ?(a, null)), null), 2);\n let i2 = ((?(c, ?(b, null)), null), 2);\n #idles(i1, i2)\n }\n };\n\n /// Insert a new element on the back end of a queue.\n /// Returns the new queue with all the elements of `queue`, followed by `element` on the back.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.pushBack(Queue.pushBack(Queue.empty<Nat>(), 1), 2);\n /// assert Queue.peekBack(queue) == ?2;\n /// assert Queue.size(queue) == 2;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)` worst-case!\n ///\n /// Space: `O(1)` worst-case!\n public func pushBack<T>(queue : Queue<T>, element : T) : Queue<T> = switch queue {\n // Equivalent to: `reverse(pushFront(reverse(queue), element))`. Inlined for performance.\n case (#idles(rnR, l0)) {\n // ^ reversed input\n let lnL = Idle.push(l0, element);\n if (3 * rnR.1 >= lnL.1) {\n debug assert 3 * lnL.1 >= rnR.1;\n #idles(rnR, lnL) // reversed output\n } else {\n let (l, nL) = lnL;\n let (r, nR) = rnR;\n let targetSizeL = nL - nR - 1 : Nat;\n let targetSizeR = 2 * nR + 1;\n debug assert targetSizeL + targetSizeR == nL + nR;\n let big = #big1(Current.new(l, targetSizeL), l, null, targetSizeL);\n let small = #small1(Current.new(r, targetSizeR), r, null);\n let states = (#left, big, small); // reversed output\n let states6 = States.step(States.step(States.step(States.step(States.step(States.step(states))))));\n #rebal(states6)\n }\n };\n case (#rebal(dir, big0, small0)) switch dir {\n case (#left) {\n // ^ reversed input\n let big = BigState.push(big0, element);\n let states4 = States.step(States.step(States.step(States.step((#left, big, small0))))); // reversed output\n debug assert states4.0 == #left;\n switch states4 {\n case (_, #big2(#idle(_, big)), #small3(#idle(_, small))) {\n debug assert idlesInvariant(big, small);\n #idles(small, big) // reversed output\n };\n case _ #rebal(states4)\n }\n };\n case (#right) {\n // ^ reversed input\n let small = SmallState.push(small0, element);\n let states4 = States.step(States.step(States.step(States.step((#right, big0, small))))); // reversed output\n debug assert states4.0 == #right;\n switch states4 {\n case (_, #big2(#idle(_, big)), #small3(#idle(_, small))) {\n debug assert idlesInvariant(small, big);\n #idles(big, small) // reversed output\n };\n case _ #rebal(states4)\n }\n }\n };\n case (#empty) #one(element);\n case (#one(y)) #two(y, element);\n case (#two(y, z)) #three(y, z, element);\n case (#three(a, b, c)) {\n let i1 = ((?(a, ?(b, null)), null), 2);\n let i2 = ((?(element, ?(c, null)), null), 2);\n #idles(i1, i2)\n }\n };\n\n /// Remove the element on the front end of a queue.\n /// Returns `null` if `queue` is empty. Otherwise, it returns a pair of\n /// the first element and a new queue that contains all the remaining elements of `queue`.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Runtime \"mo:core/Runtime\";\n ///\n /// persistent actor {\n /// do {\n /// let initial = Queue.pushBack(Queue.pushBack(Queue.empty<Nat>(), 1), 2);\n /// let ?(frontElement, remainingQueue) = Queue.popFront(initial) else Runtime.trap \"Empty queue impossible\";\n /// assert frontElement == 1;\n /// assert Queue.size(remainingQueue) == 1;\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(1)` worst-case!\n ///\n /// Space: `O(1)` worst-case!\n public func popFront<T>(queue : Queue<T>) : ?(T, Queue<T>) = switch queue {\n case (#idles(l0, rnR)) {\n let (x, lnL) = Idle.pop(l0);\n if (3 * lnL.1 >= rnR.1) {\n ?(x, #idles(lnL, rnR))\n } else if (lnL.1 >= 1) {\n let (l, nL) = lnL;\n let (r, nR) = rnR;\n let targetSizeL = 2 * nL + 1;\n let targetSizeR = nR - nL - 1 : Nat;\n debug assert targetSizeL + targetSizeR == nL + nR;\n let small = #small1(Current.new(l, targetSizeL), l, null);\n let big = #big1(Current.new(r, targetSizeR), r, null, targetSizeR);\n let states = (#left, big, small);\n let states6 = States.step(States.step(States.step(States.step(States.step(States.step(states))))));\n ?(x, #rebal(states6))\n } else {\n ?(x, Stacks.smallqueue(rnR.0))\n }\n };\n case (#rebal(dir, big0, small0)) switch dir {\n case (#left) {\n let (x, small) = SmallState.pop(small0);\n let states4 = States.step(States.step(States.step(States.step((#left, big0, small)))));\n debug assert states4.0 == #left;\n switch states4 {\n case (_, #big2(#idle(_, big)), #small3(#idle(_, small))) {\n debug assert idlesInvariant(small, big);\n ?(x, #idles(small, big))\n };\n case _ ?(x, #rebal(states4))\n }\n };\n case (#right) {\n let (x, big) = BigState.pop(big0);\n let states4 = States.step(States.step(States.step(States.step((#right, big, small0)))));\n debug assert states4.0 == #right;\n switch states4 {\n case (_, #big2(#idle(_, big)), #small3(#idle(_, small))) {\n debug assert idlesInvariant(big, small);\n ?(x, #idles(big, small))\n };\n case _ ?(x, #rebal(states4))\n }\n }\n };\n case (#empty) null;\n case (#one(x)) ?(x, #empty);\n case (#two(x, y)) ?(x, #one(y));\n case (#three(x, y, z)) ?(x, #two(y, z))\n };\n\n /// Remove the element on the back end of a queue.\n /// Returns `null` if `queue` is empty. Otherwise, it returns a pair of\n /// a new queue that contains the remaining elements of `queue`\n /// and, as the second pair item, the removed back element.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Runtime \"mo:core/Runtime\";\n ///\n /// persistent actor {\n /// do {\n /// let initial = Queue.pushBack(Queue.pushBack(Queue.empty<Nat>(), 1), 2);\n /// let ?(reducedQueue, removedElement) = Queue.popBack(initial) else Runtime.trap \"Empty queue impossible\";\n /// assert removedElement == 2;\n /// assert Queue.size(reducedQueue) == 1;\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(1)` worst-case!\n ///\n /// Space: `O(1)` worst-case!\n public func popBack<T>(queue : Queue<T>) : ?(Queue<T>, T) = switch queue {\n // Equivalent to:\n // = do ? { let (x, queue2) = popFront(reverse(queue))!; (reverse(queue2), x) };\n // Inlined for performance.\n case (#idles(rnR, l0)) {\n // ^ reversed input\n let (x, lnL) = Idle.pop(l0);\n if (3 * lnL.1 >= rnR.1) {\n ?(#idles(rnR, lnL), x) // reversed output\n } else if (lnL.1 >= 1) {\n let (l, nL) = lnL;\n let (r, nR) = rnR;\n let targetSizeL = 2 * nL + 1;\n let targetSizeR = nR - nL - 1 : Nat;\n debug assert targetSizeL + targetSizeR == nL + nR;\n let small = #small1(Current.new(l, targetSizeL), l, null);\n let big = #big1(Current.new(r, targetSizeR), r, null, targetSizeR);\n let states = (#right, big, small); // reversed output\n let states6 = States.step(States.step(States.step(States.step(States.step(States.step(states))))));\n ?(#rebal(states6), x)\n } else {\n ?(Stacks.smallqueueReversed(rnR.0), x) // reversed output\n }\n };\n case (#rebal(dir, big0, small0)) switch dir {\n case (#right) {\n // ^ reversed input\n let (x, small) = SmallState.pop(small0);\n let states4 = States.step(States.step(States.step(States.step((#right, big0, small))))); // reversed output\n debug assert states4.0 == #right;\n switch states4 {\n case (_, #big2(#idle(_, big)), #small3(#idle(_, small))) {\n debug assert idlesInvariant(big, small);\n ?(#idles(big, small), x) // reversed output\n };\n case _ ?(#rebal(states4), x)\n }\n };\n case (#left) {\n // ^ reversed input\n let (x, big) = BigState.pop(big0);\n let states4 = States.step(States.step(States.step(States.step((#left, big, small0))))); // reversed output\n debug assert states4.0 == #left;\n switch states4 {\n case (_, #big2(#idle(_, big)), #small3(#idle(_, small))) {\n debug assert idlesInvariant(small, big);\n ?(#idles(small, big), x) // reversed output\n };\n case _ ?(#rebal(states4), x)\n }\n }\n };\n case (#empty) null;\n case (#one(x)) ?(#empty, x);\n case (#two(x, y)) ?(#one(x), y);\n case (#three(x, y, z)) ?(#two(x, y), z)\n };\n\n /// Turn an iterator into a queue, consuming it.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([0, 1, 2, 3, 4].values());\n /// assert Queue.peekFront(queue) == ?0;\n /// assert Queue.peekBack(queue) == ?4;\n /// assert Queue.size(queue) == 5;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n public func fromIter<T>(iter : Iter<T>) : Queue<T> {\n var queue = empty<T>();\n Iter.forEach(iter, func(t : T) = queue := pushBack(queue, t));\n queue\n };\n\n /// Create an iterator over the elements in the queue. The order of the elements is from front to back.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Iter.toArray(Queue.values(queue)) == [1, 2, 3];\n /// }\n /// ```\n ///\n /// Runtime: `O(1)` to create the iterator and for each `next()` call.\n ///\n /// Space: `O(1)` to create the iterator and for each `next()` call.\n public func values<T>(queue : Queue<T>) : Iter.Iter<T> {\n object {\n var current = queue;\n public func next() : ?T {\n switch (popFront(current)) {\n case null null;\n case (?result) {\n current := result.1;\n ?result.0\n }\n }\n }\n }\n };\n\n /// Compare two queues for equality using a provided equality function to compare their elements.\n /// Two queues are considered equal if they contain the same elements in the same order.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue1 = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let queue2 = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let queue3 = Queue.fromIter<Nat>([1, 3, 2].values());\n /// assert Queue.equal(queue1, queue2, Nat.equal);\n /// assert not Queue.equal(queue1, queue3, Nat.equal);\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n public func equal<T>(queue1 : Queue<T>, queue2 : Queue<T>, equality : (T, T) -> Bool) : Bool {\n if (size(queue1) != size(queue2)) {\n return false\n };\n func go(queue1 : Queue<T>, queue2 : Queue<T>, equality : (T, T) -> Bool) : Bool = switch (popFront queue1, popFront queue2) {\n case (null, null) true;\n case (?(x1, tail1), ?(x2, tail2)) equality(x1, x2) and go(tail1, tail2, equality); // Note that this is tail recursive (`and` is expanded to `if`).\n case _ false\n };\n go(queue1, queue2, equality)\n };\n\n /// Compare two queues lexicographically using a provided comparison function to compare their elements.\n /// Returns `#less` if `queue1` is lexicographically less than `queue2`, `#equal` if they are equal, and `#greater` otherwise.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue1 = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let queue2 = Queue.fromIter<Nat>([1, 2, 4].values());\n /// assert Queue.compare(queue1, queue2, Nat.compare) == #less;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n public func compare<T>(queue1 : Queue<T>, queue2 : Queue<T>, comparison : (T, T) -> Types.Order) : Types.Order = switch (popFront queue1, popFront queue2) {\n case (null, null) #equal;\n case (null, _) #less;\n case (_, null) #greater;\n case (?(x1, queue1Tail), ?(x2, queue2Tail)) {\n switch (comparison(x1, x2)) {\n case (#equal) compare(queue1Tail, queue2Tail, comparison);\n case order order\n }\n }\n };\n\n /// Return true if the given predicate is true for all queue elements.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([2, 4, 6].values());\n /// assert Queue.all<Nat>(queue, func n = n % 2 == 0);\n /// assert not Queue.all<Nat>(queue, func n = n > 4);\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)` as the current implementation uses `values` to iterate over the queue.\n ///\n /// *Runtime and space assumes that the `predicate` runs in `O(1)` time and space.\n public func all<T>(queue : Queue<T>, predicate : T -> Bool) : Bool = switch queue {\n case (#empty) true;\n case (#one(x)) predicate x;\n case (#two(x, y)) predicate x and predicate y;\n case (#three(x, y, z)) predicate x and predicate y and predicate z;\n case _ {\n for (item in values queue) if (not (predicate item)) return false;\n return true\n }\n };\n\n /// Return true if the given predicate is true for any queue element.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.any<Nat>(queue, func n = n > 2);\n /// assert not Queue.any<Nat>(queue, func n = n > 3);\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)` as the current implementation uses `values` to iterate over the queue.\n ///\n /// *Runtime and space assumes that the `predicate` runs in `O(1)` time and space.\n public func any<T>(queue : Queue<T>, predicate : T -> Bool) : Bool = switch queue {\n case (#empty) false;\n case (#one(x)) predicate x;\n case (#two(x, y)) predicate x or predicate y;\n case (#three(x, y, z)) predicate x or predicate y or predicate z;\n case _ {\n for (item in values queue) if (predicate item) return true;\n return false\n }\n };\n\n /// Call the given function for its side effect on each queue element in order: from front to back.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n /// persistent actor {\n /// var text = \"\";\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// Queue.forEach<Nat>(queue, func n = text #= Nat.toText(n));\n /// assert text == \"123\";\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in `O(1)` time and space.\n public func forEach<T>(queue : Queue<T>, f : T -> ()) = switch queue {\n case (#empty) ();\n case (#one(x)) f x;\n case (#two(x, y)) { f x; f y };\n case (#three(x, y, z)) { f x; f y; f z };\n // Preserve the order when visiting the elements. Note that the #idles case would require reversing the second stack.\n case _ {\n for (t in values queue) f t\n }\n };\n\n /// Create a new queue by applying the given function to each element of the original queue.\n ///\n /// Note: The order of visiting elements is undefined with the current implementation.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let mapped = Queue.map<Nat, Nat>(queue, func n = n * 2);\n /// assert Queue.size(mapped) == 3;\n /// assert Queue.peekFront(mapped) == ?2;\n /// assert Queue.peekBack(mapped) == ?6;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `f` runs in `O(1)` time and space.\n public func map<T1, T2>(queue : Queue<T1>, f : T1 -> T2) : Queue<T2> = switch queue {\n case (#empty) #empty;\n case (#one(x)) #one(f x);\n case (#two(x, y)) #two(f x, f y);\n case (#three(x, y, z)) #three(f x, f y, f z);\n case (#idles(l, r)) #idles(Idle.map(l, f), Idle.map(r, f));\n case (#rebal(_)) {\n // No reason to rebuild the #rebal state.\n // future work: It could be further optimized by building a balanced #idles state directly since we know the sizes.\n var q = empty<T2>();\n for (t in values queue) q := pushBack(q, f t);\n q\n }\n };\n\n /// Create a new queue with only those elements of the original queue for which\n /// the given predicate returns true.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3, 4].values());\n /// let filtered = Queue.filter<Nat>(queue, func n = n % 2 == 0);\n /// assert Queue.size(filtered) == 2;\n /// assert Queue.peekFront(filtered) == ?2;\n /// assert Queue.peekBack(filtered) == ?4;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that `predicate` runs in `O(1)` time and space.\n public func filter<T>(queue : Queue<T>, predicate : T -> Bool) : Queue<T> {\n var q = empty<T>();\n for (t in values queue) if (predicate t) q := pushBack(q, t);\n q\n };\n\n /// Create a new queue by applying the given function to each element of the original queue\n /// and collecting the results for which the function returns a non-null value.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3, 4].values());\n /// let filtered = Queue.filterMap<Nat, Nat>(queue, func n = if (n % 2 == 0) { ?n } else null);\n /// assert Queue.size(filtered) == 2;\n /// assert Queue.peekFront(filtered) == ?2;\n /// assert Queue.peekBack(filtered) == ?4;\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that f runs in `O(1)` time and space.\n public func filterMap<T, U>(queue : Queue<T>, f : T -> ?U) : Queue<U> {\n var q = empty<U>();\n for (t in values queue) {\n switch (f t) {\n case (?x) q := pushBack(q, x);\n case null ()\n }\n };\n q\n };\n\n /// Create a `Text` representation of a queue for debugging purposes.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// assert Queue.toText(queue, Nat.toText) == \"RealTimeQueue[1, 2, 3]\";\n /// }\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n ///\n /// *Runtime and space assumes that f runs in `O(1)` time and space.\n public func toText<T>(queue : Queue<T>, f : T -> Text) : Text {\n var text = \"RealTimeQueue[\";\n var first = true;\n for (t in values queue) {\n if (first) first := false else text #= \", \";\n text #= f(t)\n };\n text # \"]\"\n };\n\n /// Reverse the order of elements in a queue.\n /// This operation is cheap, it does NOT require copying the elements.\n ///\n /// Example:\n /// ```motoko include=import\n /// persistent actor {\n /// let queue = Queue.fromIter<Nat>([1, 2, 3].values());\n /// let reversed = Queue.reverse(queue);\n /// assert Queue.peekFront(reversed) == ?3;\n /// assert Queue.peekBack(reversed) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func reverse<T>(queue : Queue<T>) : Queue<T> = switch queue {\n case (#idles(l, r)) #idles(r, l);\n case (#rebal(#left, big, small)) #rebal(#right, big, small);\n case (#rebal(#right, big, small)) #rebal(#left, big, small);\n case (#empty) queue;\n case (#one(_)) queue;\n case (#two(x, y)) #two(y, x);\n case (#three(x, y, z)) #three(z, y, x)\n };\n\n type Stacks<T> = (left : List<T>, right : List<T>);\n\n module Stacks {\n public func push<T>((left, right) : Stacks<T>, t : T) : Stacks<T> = (?(t, left), right);\n\n public func pop<T>(stacks : Stacks<T>) : Stacks<T> = switch stacks {\n case (?(_, leftTail), right) (leftTail, right);\n case (null, ?(_, rightTail)) (null, rightTail);\n case (null, null) stacks\n };\n\n public func first<T>((left, right) : Stacks<T>) : ?T = switch (left) {\n case (?(h, _)) ?h;\n case (null) do ? { right!.0 }\n };\n\n public func unsafeFirst<T>((left, right) : Stacks<T>) : T = switch (left) {\n case (?(h, _)) h;\n case (null) Option.unwrap(right).0\n };\n\n public func isEmpty<T>((left, right) : Stacks<T>) : Bool = List.isEmpty(left) and List.isEmpty(right);\n\n public func size<T>((left, right) : Stacks<T>) : Nat = List.size(left) + List.size(right);\n\n public func smallqueue<T>((left, right) : Stacks<T>) : Queue<T> = switch (left, right) {\n case (null, null) #empty;\n case (null, ?(x, null)) #one(x);\n case (?(x, null), null) #one(x);\n case (null, ?(x, ?(y, null))) #two(y, x);\n case (?(x, null), ?(y, null)) #two(y, x);\n case (?(x, ?(y, null)), null) #two(y, x);\n case (null, ?(x, ?(y, ?(z, null)))) #three(z, y, x);\n case (?(x, ?(y, ?(z, null))), null) #three(z, y, x);\n case (?(x, ?(y, null)), ?(z, null)) #three(z, y, x);\n case (?(x, null), ?(y, ?(z, null))) #three(z, y, x);\n case _ (trap \"Queue.Stacks.smallqueue() impossible\")\n };\n\n public func smallqueueReversed<T>((left, right) : Stacks<T>) : Queue<T> = switch (left, right) {\n case (null, null) #empty;\n case (null, ?(x, null)) #one(x);\n case (?(x, null), null) #one(x);\n case (null, ?(x, ?(y, null))) #two(x, y);\n case (?(x, null), ?(y, null)) #two(x, y);\n case (?(x, ?(y, null)), null) #two(x, y);\n case (null, ?(x, ?(y, ?(z, null)))) #three(x, y, z);\n case (?(x, ?(y, ?(z, null))), null) #three(x, y, z);\n case (?(x, ?(y, null)), ?(z, null)) #three(x, y, z);\n case (?(x, null), ?(y, ?(z, null))) #three(x, y, z);\n case _ (trap \"Queue.Stacks.smallqueueReversed() impossible\")\n };\n public func map<T, U>((left, right) : Stacks<T>, f : T -> U) : Stacks<U> = (List.map(left, f), List.map(right, f))\n };\n\n /// Represents an end of the queue that is not in a rebalancing process. It is a stack and its size.\n type Idle<T> = (stacks : Stacks<T>, size : Nat);\n module Idle {\n public func push<T>((stacks, size) : Idle<T>, t : T) : Idle<T> = (Stacks.push(stacks, t), 1 + size);\n public func pop<T>((stacks, size) : Idle<T>) : (T, Idle<T>) = (Stacks.unsafeFirst(stacks), (Stacks.pop(stacks), size - 1 : Nat));\n public func peek<T>((stacks, _) : Idle<T>) : T = Stacks.unsafeFirst(stacks);\n\n public func map<T, U>((stacks, size) : Idle<T>, f : T -> U) : Idle<U> = (Stacks.map(stacks, f), size)\n };\n\n /// Stores information about operations that happen during rebalancing but which have not become part of the old state that is being rebalanced.\n ///\n /// - `extra`: newly added elements\n /// - `extraSize`: size of `extra`\n /// - `old`: elements contained before the rebalancing process\n /// - `targetSize`: the number of elements which will be contained after the rebalancing is finished\n type Current<T> = (extra : List<T>, extraSize : Nat, old : Stacks<T>, targetSize : Nat);\n\n module Current {\n public func new<T>(old : Stacks<T>, targetSize : Nat) : Current<T> = (null, 0, old, targetSize);\n\n public func push<T>((extra, extraSize, old, targetSize) : Current<T>, t : T) : Current<T> = (?(t, extra), 1 + extraSize, old, targetSize);\n\n public func pop<T>((extra, extraSize, old, targetSize) : Current<T>) : (T, Current<T>) = switch (extra) {\n case (?(h, t)) (h, (t, extraSize - 1 : Nat, old, targetSize));\n case (null) (Stacks.unsafeFirst(old), (null, extraSize, Stacks.pop(old), targetSize - 1 : Nat))\n };\n\n public func peek<T>((extra, _, old, _) : Current<T>) : T = switch (extra) {\n case (?(h, _)) h;\n case (null) Stacks.unsafeFirst(old)\n };\n\n public func size<T>((_, extraSize, _, targetSize) : Current<T>) : Nat = extraSize + targetSize\n };\n\n /// The bigger end of the queue during rebalancing. It is used to split the bigger end of the queue into the new big end and a portion to be added to the small end. Can be in one of the following states:\n ///\n /// - `#big1(cur, big, aux, n)`: Initial state. Using the step function it takes `n`-elements from the `big` stack and puts them to `aux` in reversed order. `#big1(cur, x1 .. xn : bigTail, [], n) ->* #big1(cur, bigTail, xn .. x1, 0)`. The `bigTail` is later given to the `small` end.\n /// - `#big2(common)`: Is used to reverse the elements from the previous phase to restore the original order. `common = #copy(cur, xn .. x1, [], 0) ->* #copy(cur, [], x1 .. xn, n)`.\n type BigState<T> = {\n #big1 : (Current<T>, Stacks<T>, List<T>, Nat);\n #big2 : CommonState<T>\n };\n\n module BigState {\n public func push<T>(big : BigState<T>, t : T) : BigState<T> = switch big {\n case (#big1(cur, big, aux, n)) #big1(Current.push(cur, t), big, aux, n);\n case (#big2(state)) #big2(CommonState.push(state, t))\n };\n\n public func pop<T>(big : BigState<T>) : (T, BigState<T>) = switch big {\n case (#big1(cur, big, aux, n)) {\n let (x, cur2) = Current.pop(cur);\n (x, #big1(cur2, big, aux, n))\n };\n case (#big2(state)) {\n let (x, state2) = CommonState.pop(state);\n (x, #big2(state2))\n }\n };\n\n public func peek<T>(big : BigState<T>) : T = switch big {\n case (#big1(cur, _, _, _)) Current.peek(cur);\n case (#big2(state)) CommonState.peek(state)\n };\n\n public func step<T>(big : BigState<T>) : BigState<T> = switch big {\n case (#big1(cur, big, aux, n)) {\n if (n == 0)\n #big2(CommonState.norm(#copy(cur, aux, null, 0))) else\n #big1(cur, Stacks.pop(big), ?(Stacks.unsafeFirst(big), aux), n - 1 : Nat)\n };\n case (#big2(state)) #big2(CommonState.step(state))\n };\n\n public func size<T>(big : BigState<T>) : Nat = switch big {\n case (#big1(cur, _, _, _)) Current.size(cur);\n case (#big2(state)) CommonState.size(state)\n };\n\n public func current<T>(big : BigState<T>) : Current<T> = switch big {\n case (#big1(cur, _, _, _)) cur;\n case (#big2(state)) CommonState.current(state)\n }\n };\n\n /// The smaller end of the queue during rebalancing. Can be in one of the following states:\n ///\n /// - `#small1(cur, small, aux)`: Initial state. Using the step function the original elements are reversed. `#small1(cur, s1 .. sn, []) ->* #small1(cur, [], sn .. s1)`, note that `aux` is initially empty, at the end contains the reversed elements from the small stack.\n /// - `#small2(cur, aux, big, new, size)`: Using the step function the newly transfered tail from the bigger end is reversed on top of the `new` list. `#small2(cur, sn .. s1, b1 .. bm, [], 0) ->* #small2(cur, sn .. s1, [], bm .. b1, m)`, note that `aux` is the reversed small stack from the previous phase, `new` is initially empty, `size` corresponds to the size of `new`.\n /// - `#small3(common)`: Is used to reverse the elements from the two previous phases again to get them again in the original order. `#copy(cur, sn .. s1, bm .. b1, m) ->* #copy(cur, [], s1 .. sn : bm .. b1, n + m)`, note that the correct order of the elements from the big stack is reversed.\n type SmallState<T> = {\n #small1 : (Current<T>, Stacks<T>, List<T>);\n #small2 : (Current<T>, List<T>, Stacks<T>, List<T>, Nat);\n #small3 : CommonState<T>\n };\n\n module SmallState {\n public func push<T>(state : SmallState<T>, t : T) : SmallState<T> = switch state {\n case (#small1(cur, small, aux)) #small1(Current.push(cur, t), small, aux);\n case (#small2(cur, aux, big, new, newN)) #small2(Current.push(cur, t), aux, big, new, newN);\n case (#small3(common)) #small3(CommonState.push(common, t))\n };\n\n public func pop<T>(state : SmallState<T>) : (T, SmallState<T>) = switch state {\n case (#small1(cur0, small, aux)) {\n let (t, cur) = Current.pop(cur0);\n (t, #small1(cur, small, aux))\n };\n case (#small2(cur0, aux, big, new, newN)) {\n let (t, cur) = Current.pop(cur0);\n (t, #small2(cur, aux, big, new, newN))\n };\n case (#small3(common0)) {\n let (t, common) = CommonState.pop(common0);\n (t, #small3(common))\n }\n };\n\n public func peek<T>(state : SmallState<T>) : T = switch state {\n case (#small1(cur, _, _)) Current.peek(cur);\n case (#small2(cur, _, _, _, _)) Current.peek(cur);\n case (#small3(common)) CommonState.peek(common)\n };\n\n public func step<T>(state : SmallState<T>) : SmallState<T> = switch state {\n case (#small1(cur, small, aux)) {\n if (Stacks.isEmpty(small)) state else #small1(cur, Stacks.pop(small), ?(Stacks.unsafeFirst(small), aux))\n };\n case (#small2(cur, aux, big, new, newN)) {\n if (Stacks.isEmpty(big)) #small3(CommonState.norm(#copy(cur, aux, new, newN))) else #small2(cur, aux, Stacks.pop(big), ?(Stacks.unsafeFirst(big), new), 1 + newN)\n };\n case (#small3(common)) #small3(CommonState.step(common))\n };\n\n public func size<T>(state : SmallState<T>) : Nat = switch state {\n case (#small1(cur, _, _)) Current.size(cur);\n case (#small2(cur, _, _, _, _)) Current.size(cur);\n case (#small3(common)) CommonState.size(common)\n };\n\n public func current<T>(state : SmallState<T>) : Current<T> = switch state {\n case (#small1(cur, _, _)) cur;\n case (#small2(cur, _, _, _, _)) cur;\n case (#small3(common)) CommonState.current(common)\n }\n };\n\n type CopyState<T> = { #copy : (Current<T>, List<T>, List<T>, Nat) };\n\n /// Represents the last rebalancing phase of both small and big ends of the queue. It is used to reverse the elements from the previous phases to restore the original order. It can be in one of the following states:\n ///\n /// - `#copy(cur, aux, new, sizeOfNew)`: Puts the elements from `aux` in reversed order on top of `new`. `#copy(cur, xn .. x1, new, sizeOfNew) ->* #copy(cur, [], x1 .. xn : new, n + sizeOfNew)`.\n /// - `#idle(cur, idle)`: The rebalancing process is done and the queue is in the idle state.\n type CommonState<T> = CopyState<T> or { #idle : (Current<T>, Idle<T>) };\n\n module CommonState {\n public func step<T>(common : CommonState<T>) : CommonState<T> = switch common {\n case (#copy copy) {\n let (cur, aux, new, sizeOfNew) = copy;\n let (_, _, _, targetSize) = cur;\n norm(if (sizeOfNew < targetSize) #copy(cur, unsafeTail(aux), ?(unsafeHead(aux), new), 1 + sizeOfNew) else #copy copy)\n };\n case (#idle _) common\n };\n\n public func norm<T>(copy : CopyState<T>) : CommonState<T> {\n let #copy(cur, _, new, sizeOfNew) = copy;\n let (extra, extraSize, _, targetSize) = cur;\n debug assert sizeOfNew <= targetSize;\n if (sizeOfNew >= targetSize) {\n #idle(cur, ((extra, new), extraSize + sizeOfNew)) // note: aux can be non-empty, thus ignored here, when the target size decreases after pop operations\n } else copy\n };\n\n public func push<T>(common : CommonState<T>, t : T) : CommonState<T> = switch common {\n case (#copy(cur, aux, new, sizeOfNew)) #copy(Current.push(cur, t), aux, new, sizeOfNew);\n case (#idle(cur, idle)) #idle(Current.push(cur, t), Idle.push(idle, t)) // yes, push to both\n };\n\n public func pop<T>(common : CommonState<T>) : (T, CommonState<T>) = switch common {\n case (#copy(cur, aux, new, sizeOfNew)) {\n let (t, cur2) = Current.pop(cur);\n (t, norm(#copy(cur2, aux, new, sizeOfNew)))\n };\n case (#idle(cur, idle)) {\n let (t, idle2) = Idle.pop(idle);\n (t, #idle(Current.pop(cur).1, idle2))\n }\n };\n\n public func peek<T>(common : CommonState<T>) : T = switch common {\n case (#copy(cur, _, _, _)) Current.peek(cur);\n case (#idle(_, idle)) Idle.peek(idle)\n };\n\n public func size<T>(common : CommonState<T>) : Nat = switch common {\n case (#copy(cur, _, _, _)) Current.size(cur);\n case (#idle(_, (_, size))) size\n };\n\n public func current<T>(common : CommonState<T>) : Current<T> = switch common {\n case (#copy(cur, _, _, _)) cur;\n case (#idle(cur, _)) cur\n }\n };\n\n type States<T> = (\n direction : Direction,\n bigState : BigState<T>,\n smallState : SmallState<T>\n );\n\n module States {\n public func step<T>(states : States<T>) : States<T> = switch states {\n case (dir, #big1(_, bigTail, _, 0), #small1(currentS, _, auxS)) {\n (dir, BigState.step(states.1), #small2(currentS, auxS, bigTail, null, 0))\n };\n case (dir, big, small) (dir, BigState.step(big), SmallState.step(small))\n }\n };\n\n type Direction = { #left; #right };\n\n func idlesInvariant<T>(((l, nL), (r, nR)) : (Idle<T>, Idle<T>)) : Bool = Stacks.size(l) == nL and Stacks.size(r) == nR and 3 * nL >= nR and 3 * nR >= nL;\n\n type List<T> = Types.Pure.List<T>;\n type Iter<T> = Types.Iter<T>;\n func unsafeHead<T>(l : List<T>) : T = Option.unwrap(l).0;\n func unsafeTail<T>(l : List<T>) : List<T> = Option.unwrap(l).1\n}\n"},"Map.mo":{"content":"/// An imperative key-value map based on order/comparison of the keys.\n/// The map data structure type is stable and can be used for orthogonal persistence.\n///\n/// Example:\n/// ```motoko\n/// import Map \"mo:core/Map\";\n/// import Nat \"mo:core/Nat\";\n///\n/// persistent actor {\n/// // creation\n/// let map = Map.empty<Nat, Text>();\n/// // insertion\n/// Map.add(map, Nat.compare, 0, \"Zero\");\n/// // retrieval\n/// assert Map.get(map, Nat.compare, 0) == ?\"Zero\";\n/// assert Map.get(map, Nat.compare, 1) == null;\n/// // removal\n/// Map.remove(map, Nat.compare, 0);\n/// assert Map.isEmpty(map);\n/// }\n/// ```\n///\n/// The internal implementation is a B-tree with order 32.\n///\n/// Performance:\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Space: `O(n)` for storing the entire map.\n/// `n` denotes the number of key-value entries stored in the map.\n\n// Data structure implementation is courtesy of Byron Becker.\n// Source: https://github.com/canscale/StableHeapBTreeMap\n// Copyright (c) 2022 Byron Becker.\n// Distributed under Apache 2.0 license.\n// With adjustments by the Motoko team.\n\nimport PureMap \"pure/Map\";\nimport Types \"Types\";\nimport Order \"Order\";\nimport VarArray \"VarArray\";\nimport Runtime \"Runtime\";\nimport Stack \"Stack\";\nimport Option \"Option\";\nimport BTreeHelper \"internal/BTreeHelper\";\n\nmodule {\n let btreeOrder = 32; // Should be >= 4 and <= 512.\n\n public type Map<K, V> = Types.Map<K, V>;\n\n type Node<K, V> = Types.Map.Node<K, V>;\n type Data<K, V> = Types.Map.Data<K, V>;\n type Internal<K, V> = Types.Map.Internal<K, V>;\n type Leaf<K, V> = Types.Map.Leaf<K, V>;\n\n /// Convert the mutable key-value map to an immutable key-value map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import PureMap \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(), Nat.compare);\n /// let pureMap = Map.toPure(map, Nat.compare);\n /// assert Iter.toArray(PureMap.entries(pureMap)) == Iter.toArray(Map.entries(map))\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func toPure<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order) : PureMap.Map<K, V> {\n PureMap.fromIter(entries(map), compare)\n };\n\n /// Convert an immutable key-value map to a mutable key-value map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import PureMap \"mo:core/pure/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let pureMap = PureMap.fromIter(\n /// [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(), Nat.compare);\n /// let map = Map.fromPure<Nat, Text>(pureMap, Nat.compare);\n /// assert Iter.toArray(Map.entries(map)) == Iter.toArray(PureMap.entries(pureMap))\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func fromPure<K, V>(map : PureMap.Map<K, V>, compare : (K, K) -> Order.Order) : Map<K, V> {\n fromIter(PureMap.entries(map), compare)\n };\n\n /// Create a copy of the mutable key-value map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let originalMap = Map.fromIter<Nat, Text>(\n /// [(1, \"One\"), (2, \"Two\"), (3, \"Three\")].values(), Nat.compare);\n /// let clonedMap = Map.clone(originalMap);\n /// Map.add(originalMap, Nat.compare, 4, \"Four\");\n /// assert Map.size(clonedMap) == 3;\n /// assert Map.size(originalMap) == 4;\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func clone<K, V>(map : Map<K, V>) : Map<K, V> {\n {\n var root = cloneNode(map.root);\n var size = map.size\n }\n };\n\n /// Create a new empty mutable key-value map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n ///\n /// persistent actor {\n /// let map = Map.empty<Nat, Text>();\n /// assert Map.size(map) == 0;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func empty<K, V>() : Map<K, V> {\n {\n var root = #leaf({\n data = {\n kvs = VarArray.repeat<?(K, V)>(null, btreeOrder - 1);\n var count = 0\n }\n });\n var size = 0\n }\n };\n\n /// Create a new mutable key-value map with a single entry.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.singleton<Nat, Text>(0, \"Zero\");\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func singleton<K, V>(key : K, value : V) : Map<K, V> {\n let kvs = VarArray.repeat<?(K, V)>(null, btreeOrder - 1);\n kvs[0] := ?(key, value);\n {\n var root = #leaf { data = { kvs; var count = 1 } };\n var size = 1\n }\n };\n\n /// Delete all the entries in the key-value map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(),\n /// Nat.compare);\n ///\n /// assert Map.size(map) == 3;\n ///\n /// Map.clear(map);\n /// assert Map.size(map) == 0;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func clear<K, V>(map : Map<K, V>) {\n let emptyMap = empty<K, V>();\n map.root := emptyMap.root;\n map.size := 0\n };\n\n /// Determines whether a key-value map is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(),\n /// Nat.compare);\n ///\n /// assert not Map.isEmpty(map);\n /// Map.clear(map);\n /// assert Map.isEmpty(map);\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func isEmpty<K, V>(map : Map<K, V>) : Bool {\n map.size == 0\n };\n\n /// Return the number of entries in a key-value map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(),\n /// Nat.compare);\n ///\n /// assert Map.size(map) == 3;\n /// Map.clear(map);\n /// assert Map.size(map) == 0;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func size<K, V>(map : Map<K, V>) : Nat {\n map.size\n };\n\n /// Test whether two imperative maps have equal entries.\n /// Both maps have to be constructed by the same comparison function.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// persistent actor {\n /// let map1 = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(),\n /// Nat.compare);\n /// let map2 = Map.clone(map1);\n ///\n /// assert Map.equal(map1, map2, Nat.compare, Text.equal);\n /// Map.clear(map2);\n /// assert not Map.equal(map1, map2, Nat.compare, Text.equal);\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n public func equal<K, V>(map1 : Map<K, V>, map2 : Map<K, V>, compareKeys : (K, K) -> Types.Order, equalValues : (V, V) -> Bool) : Bool {\n if (size(map1) != size(map2)) {\n return false\n };\n let iterator1 = entries(map1);\n let iterator2 = entries(map2);\n loop {\n let next1 = iterator1.next();\n let next2 = iterator2.next();\n switch (next1, next2) {\n case (null, null) {\n return true\n };\n case (?(key1, value1), ?(key2, value2)) {\n if (\n not (compareKeys(key1, key2) == #equal) or\n not equalValues(value1, value2)\n ) {\n return false\n }\n };\n case _ { return false }\n }\n }\n };\n\n /// Tests whether the map contains the provided key.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(),\n /// Nat.compare);\n ///\n /// assert Map.containsKey(map, Nat.compare, 1);\n /// assert not Map.containsKey(map, Nat.compare, 3);\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func containsKey<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : Bool {\n Option.isSome(get(map, compare, key))\n };\n\n /// Get the value associated with key in the given map if present and `null` otherwise.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")].values(),\n /// Nat.compare);\n ///\n /// assert Map.get(map, Nat.compare, 1) == ?\"One\";\n /// assert Map.get(map, Nat.compare, 3) == null;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func get<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : ?V {\n switch (map.root) {\n case (#internal(internalNode)) {\n getFromInternal(internalNode, compare, key)\n };\n case (#leaf(leafNode)) { getFromLeaf(leafNode, compare, key) }\n }\n };\n\n /// Given `map` ordered by `compare`, insert a new mapping from `key` to `value`.\n /// Replaces any existing entry under `key`.\n /// Returns true if the key is new to the map, otherwise false.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.empty<Nat, Text>();\n /// assert Map.insert(map, Nat.compare, 0, \"Zero\");\n /// assert Map.insert(map, Nat.compare, 1, \"One\");\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (1, \"One\")];\n /// assert not Map.insert(map, Nat.compare, 0, \"Nil\");\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Nil\"), (1, \"One\")]\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func insert<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K, value : V) : Bool {\n switch (swap(map, compare, key, value)) {\n case null true;\n case _ false\n }\n };\n\n /// Given `map` ordered by `compare`, add a mapping from `key` to `value` to `map`.\n /// Replaces any existing entry for `key`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.empty<Nat, Text>();\n ///\n /// Map.add(map, Nat.compare, 0, \"Zero\");\n /// Map.add(map, Nat.compare, 1, \"One\");\n /// Map.add(map, Nat.compare, 0, \"Nil\");\n ///\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Nil\"), (1, \"One\")]\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func add<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K, value : V) {\n ignore swap(map, compare, key, value)\n };\n\n /// Associates the value with the key in the map.\n /// If the key is not yet present in the map, a new key-value pair is added and `null` is returned.\n /// Otherwise, if the key is already present, the value is overwritten and the previous value is returned.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.singleton<Nat, Text>(1, \"One\");\n ///\n /// assert Map.swap(map, Nat.compare, 0, \"Zero\") == null;\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (1, \"One\")];\n ///\n /// assert Map.swap(map, Nat.compare, 0, \"Nil\") == ?\"Zero\";\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Nil\"), (1, \"One\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func swap<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K, value : V) : ?V {\n let insertResult = switch (map.root) {\n case (#leaf(leafNode)) {\n leafInsertHelper<K, V>(leafNode, btreeOrder, compare, key, value)\n };\n case (#internal(internalNode)) {\n internalInsertHelper<K, V>(internalNode, btreeOrder, compare, key, value)\n }\n };\n\n switch (insertResult) {\n case (#insert(ov)) {\n switch (ov) {\n // if inserted a value that was not previously there, increment the tree size counter\n case null { map.size += 1 };\n case _ {}\n };\n ov\n };\n case (#promote({ kv; leftChild; rightChild })) {\n let kvs = VarArray.repeat<?(K, V)>(null, btreeOrder - 1);\n kvs[0] := ?kv;\n let children = VarArray.repeat<?Node<K, V>>(null, btreeOrder);\n children[0] := ?leftChild;\n children[1] := ?rightChild;\n map.root := #internal {\n data = {\n kvs;\n var count = 1\n };\n children\n };\n // promotion always comes from inserting a new element, so increment the tree size counter\n map.size += 1;\n\n null\n }\n }\n };\n\n /// Overwrites the value of an existing key and returns the previous value.\n /// If the key does not exist, it has no effect and returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.singleton<Nat, Text>(0, \"Zero\");\n ///\n /// let prev1 = Map.replace(map, Nat.compare, 0, \"Nil\"); // overwrites the value for existing key.\n /// assert prev1 == ?\"Zero\";\n /// assert Map.get(map, Nat.compare, 0) == ?\"Nil\";\n ///\n /// let prev2 = Map.replace(map, Nat.compare, 1, \"One\"); // no effect, key is absent\n /// assert prev2 == null;\n /// assert Map.get(map, Nat.compare, 1) == null;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func replace<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K, value : V) : ?V {\n // TODO: Could be optimized in future\n if (containsKey(map, compare, key)) {\n swap(map, compare, key, value)\n } else {\n null\n }\n };\n\n /// Delete an entry by its key in the map.\n /// No effect if the key is not present.\n ///\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(),\n /// Nat.compare);\n ///\n /// Map.remove(map, Nat.compare, 1);\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (2, \"Two\")];\n /// Map.remove(map, Nat.compare, 42);\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (2, \"Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` including garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` objects that will be collected as garbage.\n public func remove<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) {\n ignore delete(map, compare, key)\n };\n\n /// Delete an existing entry by its key in the map.\n /// Returns `true` if the key was present in the map, otherwise `false`.\n ///\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(),\n /// Nat.compare);\n ///\n /// assert Map.delete(map, Nat.compare, 1); // present, returns true\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (2, \"Two\")];\n ///\n /// assert not Map.delete(map, Nat.compare, 42); // absent, returns false\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (2, \"Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` including garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` objects that will be collected as garbage.\n public func delete<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : Bool {\n switch (take(map, compare, key)) {\n case null false;\n case _ true\n }\n };\n\n /// Removes any existing entry by its key in the map.\n /// Returns the previous value of the key or `null` if the key was absent.\n ///\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>(\n /// [(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(),\n /// Nat.compare);\n ///\n /// assert Map.take(map, Nat.compare, 0) == ?\"Zero\";\n /// assert Iter.toArray(Map.entries(map)) == [(1, \"One\"), (2, \"Two\")];\n ///\n /// assert Map.take(map, Nat.compare, 3) == null;\n /// assert Iter.toArray(Map.entries(map)) == [(1, \"One\"), (2, \"Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` including garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` objects that will be collected as garbage.\n public func take<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, key : K) : ?V {\n let deletedValue = switch (map.root) {\n case (#leaf(leafNode)) {\n // TODO: think about how this can be optimized so don't have to do two steps (search and then insert)?\n switch (NodeUtil.getKeyIndex<K, V>(leafNode.data, compare, key)) {\n case (#keyFound(deleteIndex)) {\n leafNode.data.count -= 1;\n let (_, deletedValue) = BTreeHelper.deleteAndShift<(K, V)>(leafNode.data.kvs, deleteIndex);\n map.size -= 1;\n ?deletedValue\n };\n case _ { null }\n }\n };\n case (#internal(internalNode)) {\n let deletedValueResult = switch (internalDeleteHelper(internalNode, btreeOrder, compare, key, false)) {\n case (#delete(value)) { value };\n case (#mergeChild({ internalChild; deletedValue })) {\n if (internalChild.data.count > 0) {\n map.root := #internal(internalChild)\n }\n // This case will be hit if the BTree has order == 4\n // In this case, the internalChild has no keys (last key was merged with new child), so need to promote that merged child (its only child)\n else {\n map.root := switch (internalChild.children[0]) {\n case (?node) { node };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.delete(), element deletion failed, due to a null replacement node error\")\n }\n }\n };\n deletedValue\n }\n };\n switch (deletedValueResult) {\n // if deleted a value from the BTree, decrement the size\n case (?deletedValue) { map.size -= 1 };\n case null {}\n };\n deletedValueResult\n }\n };\n deletedValue\n };\n\n /// Retrieves the key-value pair from the map with the maximum key.\n /// If the map is empty, returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.empty<Nat, Text>();\n ///\n /// assert Map.maxEntry(map) == null;\n ///\n /// Map.add(map, Nat.compare, 0, \"Zero\");\n /// Map.add(map, Nat.compare, 2, \"Two\");\n /// Map.add(map, Nat.compare, 1, \"One\");\n ///\n /// assert Map.maxEntry(map) == ?(2, \"Two\")\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func maxEntry<K, V>(map : Map<K, V>) : ?(K, V) {\n reverseEntries(map).next()\n };\n\n /// Retrieves the key-value pair from the map with the minimum key.\n /// If the map is empty, returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.empty<Nat, Text>();\n ///\n /// assert Map.minEntry(map) == null;\n ///\n /// Map.add(map, Nat.compare, 2, \"Two\");\n /// Map.add(map, Nat.compare, 0, \"Zero\");\n /// Map.add(map, Nat.compare, 1, \"One\");\n ///\n /// assert Map.minEntry(map) == ?(0, \"Zero\")\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func minEntry<K, V>(map : Map<K, V>) : ?(K, V) {\n entries(map).next()\n };\n\n /// Returns an iterator over the key-value pairs in the map,\n /// traversing the entries in the ascending order of the keys.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")];\n /// var sum = 0;\n /// var text = \"\";\n /// for ((k, v) in Map.entries(map)) { sum += k; text #= v };\n /// assert sum == 3;\n /// assert text == \"ZeroOneTwo\"\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func entries<K, V>(map : Map<K, V>) : Types.Iter<(K, V)> {\n switch (map.root) {\n case (#leaf(leafNode)) { return leafEntries(leafNode) };\n case (#internal(internalNode)) { internalEntries(internalNode) }\n }\n };\n\n /// Returns an iterator over the key-value pairs in the map,\n /// starting from a given key in ascending order.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (3, \"Three\"), (1, \"One\")].values(), Nat.compare);\n /// assert Iter.toArray(Map.entriesFrom(map, Nat.compare, 1)) == [(1, \"One\"), (3, \"Three\")];\n /// assert Iter.toArray(Map.entriesFrom(map, Nat.compare, 2)) == [(3, \"Three\")];\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func entriesFrom<K, V>(\n map : Map<K, V>,\n compare : (K, K) -> Order.Order,\n key : K\n ) : Types.Iter<(K, V)> {\n switch (map.root) {\n case (#leaf(leafNode)) leafEntriesFrom(leafNode, compare, key);\n case (#internal(internalNode)) internalEntriesFrom(internalNode, compare, key)\n }\n };\n\n /// Returns an iterator over the key-value pairs in the map,\n /// traversing the entries in the descending order of the keys.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Iter.toArray(Map.reverseEntries(map)) == [(2, \"Two\"), (1, \"One\"), (0, \"Zero\")];\n /// var sum = 0;\n /// var text = \"\";\n /// for ((k, v) in Map.reverseEntries(map)) { sum += k; text #= v };\n /// assert sum == 3;\n /// assert text == \"TwoOneZero\"\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func reverseEntries<K, V>(map : Map<K, V>) : Types.Iter<(K, V)> {\n switch (map.root) {\n case (#leaf(leafNode)) reverseLeafEntries(leafNode);\n case (#internal(internalNode)) reverseInternalEntries(internalNode)\n }\n };\n\n /// Returns an iterator over the key-value pairs in the map,\n /// starting from a given key in descending order.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (1, \"One\"), (3, \"Three\")].values(), Nat.compare);\n /// assert Iter.toArray(Map.reverseEntriesFrom(map, Nat.compare, 0)) == [(0, \"Zero\")];\n /// assert Iter.toArray(Map.reverseEntriesFrom(map, Nat.compare, 2)) == [(1, \"One\"), (0, \"Zero\")];\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func reverseEntriesFrom<K, V>(\n map : Map<K, V>,\n compare : (K, K) -> Order.Order,\n key : K\n ) : Types.Iter<(K, V)> {\n switch (map.root) {\n case (#leaf(leafNode)) reverseLeafEntriesFrom(leafNode, compare, key);\n case (#internal(internalNode)) reverseInternalEntriesFrom(internalNode, compare, key)\n }\n };\n\n /// Returns an iterator over the keys in the map,\n /// traversing all keys in ascending order.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Iter.toArray(Map.keys(map)) == [0, 1, 2];\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n public func keys<K, V>(map : Map<K, V>) : Types.Iter<K> {\n object {\n let iterator = entries(map);\n\n public func next() : ?K {\n switch (iterator.next()) {\n case null null;\n case (?(key, _)) ?key\n }\n }\n }\n };\n\n /// Returns an iterator over the values in the map,\n /// traversing the values in the ascending order of the keys to which they are associated.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// assert Iter.toArray(Map.values(map)) == [\"Zero\", \"One\", \"Two\"];\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n public func values<K, V>(map : Map<K, V>) : Types.Iter<V> {\n object {\n let iterator = entries(map);\n\n public func next() : ?V {\n switch (iterator.next()) {\n case null null;\n case (?(_, value)) ?value\n }\n }\n }\n };\n\n /// Create a mutable key-value map with the entries obtained from an iterator.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// transient let iter =\n /// Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]);\n ///\n /// let map = Map.fromIter<Nat, Text>(iter, Nat.compare);\n ///\n /// assert Iter.toArray(Map.entries(map)) == [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of key-value entries returned by the iterator and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func fromIter<K, V>(iter : Types.Iter<(K, V)>, compare : (K, K) -> Order.Order) : Map<K, V> {\n let map = empty<K, V>();\n for ((key, value) in iter) {\n add(map, compare, key, value)\n };\n map\n };\n\n /// Apply an operation on each key-value pair contained in the map.\n /// The operation is applied in ascending order of the keys.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n /// var sum = 0;\n /// var text = \"\";\n /// Map.forEach<Nat, Text>(map, func (key, value) {\n /// sum += key;\n /// text #= value;\n /// });\n /// assert sum == 3;\n /// assert text == \"ZeroOneTwo\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func forEach<K, V>(map : Map<K, V>, operation : (K, V) -> ()) {\n for (entry in entries(map)) {\n operation(entry)\n }\n };\n\n /// Filter entries in a new map.\n /// Create a copy of the mutable map that only contains the key-value pairs\n /// that fulfil the criterion function.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let numberNames = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// let evenNames = Map.filter<Nat, Text>(numberNames, Nat.compare, func (key, value) {\n /// key % 2 == 0\n /// });\n ///\n /// assert Iter.toArray(Map.entries(evenNames)) == [(0, \"Zero\"), (2, \"Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func filter<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order, criterion : (K, V) -> Bool) : Map<K, V> {\n let result = empty<K, V>();\n for ((key, value) in entries(map)) {\n if (criterion(key, value)) {\n add(result, compare, key, value)\n }\n };\n result\n };\n\n /// Project all values of the map in a new map.\n /// Apply a mapping function to the values of each entry in the map and\n /// collect the mapped entries in a new mutable key-value map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// func f(key : Nat, _val : Text) : Nat = key * 2;\n ///\n /// let resMap = Map.map<Nat, Text, Nat>(map, f);\n ///\n /// assert Iter.toArray(Map.entries(resMap)) == [(0, 0), (1, 2), (2, 4)];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func map<K, V1, V2>(map : Map<K, V1>, project : (K, V1) -> V2) : Map<K, V2> {\n {\n var root = mapNode(map.root, project);\n var size = map.size\n }\n };\n\n /// Iterate all entries in ascending order of the keys,\n /// and accumulate the entries by applying the combine function, starting from a base value.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// func folder(accum : (Nat, Text), key : Nat, val : Text) : ((Nat, Text))\n /// = (key + accum.0, accum.1 # val);\n ///\n /// assert Map.foldLeft(map, (0, \"\"), folder) == (3, \"ZeroOneTwo\");\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func foldLeft<K, V, A>(\n map : Map<K, V>,\n base : A,\n combine : (A, K, V) -> A\n ) : A {\n var accumulator = base;\n for ((key, value) in entries(map)) {\n accumulator := combine(accumulator, key, value)\n };\n accumulator\n };\n\n /// Iterate all entries in descending order of the keys,\n /// and accumulate the entries by applying the combine function, starting from a base value.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// func folder(key : Nat, val : Text, accum : (Nat, Text)) : ((Nat, Text))\n /// = (key + accum.0, accum.1 # val);\n ///\n /// assert Map.foldRight(map, (0, \"\"), folder) == (3, \"TwoOneZero\");\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func foldRight<K, V, A>(\n map : Map<K, V>,\n base : A,\n combine : (K, V, A) -> A\n ) : A {\n var accumulator = base;\n for ((key, value) in reverseEntries(map)) {\n accumulator := combine(key, value, accumulator)\n };\n accumulator\n };\n\n /// Check whether all entries in the map fulfil a predicate function, i.e.\n /// the predicate function returns `true` for all entries in the map.\n /// Returns `true` for an empty map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"0\"), (2, \"2\"), (1, \"1\")].values(), Nat.compare);\n ///\n /// assert Map.all<Nat, Text>(map, func (k, v) = v == Nat.toText(k));\n /// assert not Map.all<Nat, Text>(map, func (k, v) = k < 2);\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func all<K, V>(map : Map<K, V>, predicate : (K, V) -> Bool) : Bool {\n //TODO: optimize\n for (entry in entries(map)) {\n if (not predicate(entry)) {\n return false\n }\n };\n true\n };\n\n /// Test if any key-value pair in `map` satisfies the given predicate `pred`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"0\"), (2, \"2\"), (1, \"1\")].values(), Nat.compare);\n ///\n /// assert Map.any<Nat, Text>(map, func (k, v) = (k >= 0));\n /// assert not Map.any<Nat, Text>(map, func (k, v) = (k >= 3));\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func any<K, V>(map : Map<K, V>, predicate : (K, V) -> Bool) : Bool {\n //TODO: optimize\n for (entry in entries(map)) {\n if (predicate(entry)) {\n return true\n }\n };\n false\n };\n\n /// Filter all entries in the map by also applying a projection to the value.\n /// Apply a mapping function `project` to all entries in the map and collect all\n /// entries, for which the function returns a non-null new value. Collect all\n /// non-discarded entries with the key and new value in a new mutable map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n ///\n /// func f(key : Nat, val : Text) : ?Text {\n /// if(key == 0) {null}\n /// else { ?(\"Twenty \" # val)}\n /// };\n ///\n /// let newMap = Map.filterMap<Nat, Text, Text>(map, Nat.compare, f);\n ///\n /// assert Iter.toArray(Map.entries(newMap)) == [(1, \"Twenty One\"), (2, \"Twenty Two\")];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func filterMap<K, V1, V2>(map : Map<K, V1>, compare : (K, K) -> Order.Order, project : (K, V1) -> ?V2) : Map<K, V2> {\n let result = empty<K, V2>();\n for ((key, value1) in entries(map)) {\n switch (project(key, value1)) {\n case null {};\n case (?value2) add(result, compare, key, value2)\n }\n };\n result\n };\n\n /// Internal sanity check function.\n /// Can be used to check that key/value pairs have been inserted with a consistent key comparison function.\n /// Traps if the internal map structure is invalid.\n public func assertValid<K, V>(map : Map<K, V>, compare : (K, K) -> Order.Order) {\n func checkIteration(iterator : Types.Iter<(K, V)>, order : Order.Order) {\n switch (iterator.next()) {\n case null {};\n case (?first) {\n var previous = first;\n loop {\n switch (iterator.next()) {\n case null return;\n case (?next) {\n if (compare(previous.0, next.0) != order) {\n Runtime.trap(\"Invalid order\")\n };\n previous := next\n }\n }\n }\n }\n }\n };\n checkIteration(entries(map), #less);\n checkIteration(reverseEntries(map), #greater)\n };\n\n /// Generate a textual representation of all the entries in the map.\n /// Primarily to be used for testing and debugging.\n /// The keys and values are formatted according to `keyFormat` and `valueFormat`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let map = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")].values(), Nat.compare);\n /// assert Map.toText<Nat, Text>(map, Nat.toText, func t { t }) == \"Map{(0, Zero), (1, One), (2, Two)}\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that `keyFormat` and `valueFormat` have runtime and space costs of `O(1)`.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func toText<K, V>(map : Map<K, V>, keyFormat : K -> Text, valueFormat : V -> Text) : Text {\n var text = \"Map{\";\n var sep = \"\";\n for ((key, value) in entries(map)) {\n text #= sep # \"(\" # keyFormat(key) # \", \" # valueFormat(value) # \")\";\n sep := \", \"\n };\n text # \"}\"\n };\n\n /// Compare two maps by primarily comparing keys and secondarily values.\n /// Both maps must have been created by the same key comparison function.\n /// The two maps are iterated by the ascending order of their creation and\n /// order is determined by the following rules:\n /// Less:\n /// `map1` is less than `map2` if:\n /// * the pairwise iteration hits a entry pair `entry1` and `entry2` where\n /// `entry1` is less than `entry2` and all preceding entry pairs are equal, or,\n /// * `map1` is a strict prefix of `map2`, i.e. `map2` has more entries than `map1`\n /// and all entries of `map1` occur at the beginning of iteration `map2`.\n /// `entry1` is less than `entry2` if:\n /// * the key of `entry1` is less than the key of `entry2`, or\n /// * `entry1` and `entry2` have equal keys and the value of `entry1` is less than\n /// the value of `entry2`.\n /// Equal:\n /// `map1` and `map2` have same series of equal entries by pairwise iteration.\n /// Greater:\n /// `map1` is neither less nor equal `map2`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:core/Map\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n ///\n /// persistent actor {\n /// let map1 = Map.fromIter<Nat, Text>([(0, \"Zero\"), (1, \"One\")].values(), Nat.compare);\n /// let map2 = Map.fromIter<Nat, Text>([(0, \"Zero\"), (2, \"Two\")].values(), Nat.compare);\n ///\n /// assert Map.compare(map1, map2, Nat.compare, Text.compare) == #less;\n /// assert Map.compare(map1, map1, Nat.compare, Text.compare) == #equal;\n /// assert Map.compare(map2, map1, Nat.compare, Text.compare) == #greater\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that `compareKey` and `compareValue` have runtime and space costs of `O(1)`.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func compare<K, V>(map1 : Map<K, V>, map2 : Map<K, V>, compareKey : (K, K) -> Order.Order, compareValue : (V, V) -> Order.Order) : Order.Order {\n let iterator1 = entries(map1);\n let iterator2 = entries(map2);\n loop {\n switch (iterator1.next(), iterator2.next()) {\n case (null, null) return #equal;\n case (null, _) return #less;\n case (_, null) return #greater;\n case (?(key1, value1), ?(key2, value2)) {\n let keyComparison = compareKey(key1, key2);\n if (keyComparison != #equal) {\n return keyComparison\n };\n let valueComparison = compareValue(value1, value2);\n if (valueComparison != #equal) {\n return valueComparison\n }\n }\n }\n }\n };\n\n func leafEntries<K, V>({ data } : Leaf<K, V>) : Types.Iter<(K, V)> {\n var i : Nat = 0;\n object {\n public func next() : ?(K, V) {\n if (i >= data.count) {\n null\n } else {\n let res = data.kvs[i];\n i += 1;\n res\n }\n }\n }\n };\n\n func leafEntriesFrom<K, V>({ data } : Leaf<K, V>, compare : (K, K) -> Order.Order, key : K) : Types.Iter<(K, V)> {\n var i = switch (BinarySearch.binarySearchNode<K, V>(data.kvs, compare, key, data.count)) {\n case (#keyFound(i)) i;\n case (#notFound(i)) i\n };\n object {\n public func next() : ?(K, V) {\n if (i >= data.count) {\n null\n } else {\n let res = data.kvs[i];\n i += 1;\n res\n }\n }\n }\n };\n\n func reverseLeafEntries<K, V>({ data } : Leaf<K, V>) : Types.Iter<(K, V)> {\n var i : Nat = data.count;\n object {\n public func next() : ?(K, V) {\n if (i == 0) {\n null\n } else {\n let res = data.kvs[i - 1];\n i -= 1;\n res\n }\n }\n }\n };\n\n func reverseLeafEntriesFrom<K, V>({ data } : Leaf<K, V>, compare : (K, K) -> Order.Order, key : K) : Types.Iter<(K, V)> {\n var i = switch (BinarySearch.binarySearchNode<K, V>(data.kvs, compare, key, data.count)) {\n case (#keyFound(i)) i + 1; // +1 to include this key\n case (#notFound(i)) i // i is the index of the first key greater than the search key, or count if all keys are less than the search key\n };\n object {\n public func next() : ?(K, V) {\n if (i == 0) {\n null\n } else {\n let res = data.kvs[i - 1];\n i -= 1;\n res\n }\n }\n }\n };\n\n // Cursor type that keeps track of the current node and the current key-value index in the node\n type NodeCursor<K, V> = { node : Node<K, V>; kvIndex : Nat };\n\n func internalEntries<K, V>(internal : Internal<K, V>) : Types.Iter<(K, V)> {\n // The nodeCursorStack keeps track of the current node and the current key-value index in the node\n // We use a stack here to push to/pop off the next node cursor to visit\n let nodeCursorStack = initializeForwardNodeCursorStack(internal);\n internalEntriesFromStack(nodeCursorStack)\n };\n\n func internalEntriesFrom<K, V>(internal : Internal<K, V>, compare : (K, K) -> Order.Order, key : K) : Types.Iter<(K, V)> {\n let nodeCursorStack = initializeForwardNodeCursorStackFrom(internal, compare, key);\n internalEntriesFromStack(nodeCursorStack)\n };\n\n func internalEntriesFromStack<K, V>(nodeCursorStack : Stack.Stack<NodeCursor<K, V>>) : Types.Iter<(K, V)> {\n object {\n public func next() : ?(K, V) {\n // pop the next node cursor off the stack\n var nodeCursor = Stack.pop(nodeCursorStack);\n switch (nodeCursor) {\n case null { return null };\n case (?{ node; kvIndex }) {\n switch (node) {\n // if a leaf node, iterate through the leaf node's next key-value pair\n case (#leaf(leafNode)) {\n let lastKV = leafNode.data.count - 1 : Nat;\n if (kvIndex > lastKV) {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.internalEntries(), leaf kvIndex out of bounds\")\n };\n\n let currentKV = switch (leafNode.data.kvs[kvIndex]) {\n case (?kv) { kv };\n case null {\n Runtime.trap(\n \"UNREACHABLE_ERROR: file a bug report! In Map.internalEntries(), null key-value pair found in leaf node.\"\n # \"leafNode.data.count=\" # debug_show (leafNode.data.count) # \", kvIndex=\" # debug_show (kvIndex)\n )\n }\n };\n // if not at the last key-value pair, push the next key-value index of the leaf onto the stack and return the current key-value pair\n if (kvIndex < lastKV) {\n Stack.push(\n nodeCursorStack,\n {\n node = #leaf(leafNode);\n kvIndex = kvIndex + 1 : Nat\n }\n )\n };\n\n // return the current key-value pair\n ?currentKV\n };\n // if an internal node\n case (#internal(internalNode)) {\n let lastKV = internalNode.data.count - 1 : Nat;\n // Developer facing message in case of a bug\n if (kvIndex > lastKV) {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.internalEntries(), internal kvIndex out of bounds\")\n };\n\n let currentKV = switch (internalNode.data.kvs[kvIndex]) {\n case (?kv) { kv };\n case null {\n Runtime.trap(\n \"UNREACHABLE_ERROR: file a bug report! In Map.internalEntries(), null key-value pair found in internal node. \" #\n \"internal.data.count=\" # debug_show (internalNode.data.count) # \", kvIndex=\" # debug_show (kvIndex)\n )\n }\n };\n\n let nextCursor = {\n node = #internal(internalNode);\n kvIndex = kvIndex + 1 : Nat\n };\n // if not the last key-value pair, push the next key-value index of the internal node onto the stack\n if (kvIndex < lastKV) {\n Stack.push(nodeCursorStack, nextCursor)\n };\n // traverse the next child's min subtree and push the resulting node cursors onto the stack\n // then return the current key-value pair of the internal node\n traverseMinSubtreeIter(nodeCursorStack, nextCursor);\n ?currentKV\n }\n }\n }\n }\n }\n }\n };\n\n func reverseInternalEntries<K, V>(internal : Internal<K, V>) : Types.Iter<(K, V)> {\n // The nodeCursorStack keeps track of the current node and the current key-value index in the node\n // We use a stack here to push to/pop off the next node cursor to visit\n let nodeCursorStack = initializeReverseNodeCursorStack(internal);\n reverseInternalEntriesFromStack(nodeCursorStack)\n };\n\n func reverseInternalEntriesFrom<K, V>(internal : Internal<K, V>, compare : (K, K) -> Order.Order, key : K) : Types.Iter<(K, V)> {\n let nodeCursorStack = initializeReverseNodeCursorStackFrom(internal, compare, key);\n reverseInternalEntriesFromStack(nodeCursorStack)\n };\n\n func reverseInternalEntriesFromStack<K, V>(nodeCursorStack : Stack.Stack<NodeCursor<K, V>>) : Types.Iter<(K, V)> {\n object {\n public func next() : ?(K, V) {\n // pop the next node cursor off the stack\n var nodeCursor = Stack.pop(nodeCursorStack);\n switch (nodeCursor) {\n case null { return null };\n case (?{ node; kvIndex }) {\n let firstKV = 0 : Nat;\n assert (kvIndex > firstKV);\n switch (node) {\n // if a leaf node, reverse iterate through the leaf node's next key-value pair\n case (#leaf(leafNode)) {\n let currentKV = switch (leafNode.data.kvs[kvIndex - 1]) {\n case (?kv) { kv };\n case null {\n Runtime.trap(\n \"UNREACHABLE_ERROR: file a bug report! In Map.reverseInternalEntries(), null key-value pair found in leaf node.\"\n # \"leafNode.data.count=\" # debug_show (leafNode.data.count) # \", kvIndex=\" # debug_show (kvIndex)\n )\n }\n };\n // if not at the last key-value pair, push the previous key-value index of the leaf onto the stack and return the current key-value pair\n if (kvIndex - 1 : Nat > firstKV) {\n Stack.push(\n nodeCursorStack,\n {\n node = #leaf(leafNode);\n kvIndex = kvIndex - 1 : Nat\n }\n )\n };\n\n // return the current key-value pair\n ?currentKV\n };\n // if an internal node\n case (#internal(internalNode)) {\n let currentKV = switch (internalNode.data.kvs[kvIndex - 1]) {\n case (?kv) { kv };\n case null {\n Runtime.trap(\n \"UNREACHABLE_ERROR: file a bug report! In Map.reverseInternalEntries(), null key-value pair found in internal node. \" #\n \"internal.data.count=\" # debug_show (internalNode.data.count) # \", kvIndex=\" # debug_show (kvIndex)\n )\n }\n };\n\n let previousCursor = {\n node = #internal(internalNode);\n kvIndex = kvIndex - 1 : Nat\n };\n // if not the first key-value pair, push the previous key-value index of the internal node onto the stack\n if (kvIndex - 1 : Nat > firstKV) {\n Stack.push(nodeCursorStack, previousCursor)\n };\n // traverse the previous child's max subtree and push the resulting node cursors onto the stack\n // then return the current key-value pair of the internal node\n traverseMaxSubtreeIter(nodeCursorStack, previousCursor);\n ?currentKV\n }\n }\n }\n }\n }\n }\n };\n\n func initializeForwardNodeCursorStack<K, V>(internal : Internal<K, V>) : Stack.Stack<NodeCursor<K, V>> {\n let nodeCursorStack = Stack.empty<NodeCursor<K, V>>();\n let nodeCursor : NodeCursor<K, V> = {\n node = #internal(internal);\n kvIndex = 0\n };\n\n // push the initial cursor to the stack\n Stack.push(nodeCursorStack, nodeCursor);\n // then traverse left\n traverseMinSubtreeIter(nodeCursorStack, nodeCursor);\n nodeCursorStack\n };\n\n func initializeForwardNodeCursorStackFrom<K, V>(internal : Internal<K, V>, compare : (K, K) -> Order.Order, key : K) : Stack.Stack<NodeCursor<K, V>> {\n let nodeCursorStack = Stack.empty<NodeCursor<K, V>>();\n let nodeCursor : NodeCursor<K, V> = {\n node = #internal(internal);\n kvIndex = 0\n };\n\n traverseMinSubtreeIterFrom(nodeCursorStack, nodeCursor, compare, key);\n nodeCursorStack\n };\n\n func initializeReverseNodeCursorStack<K, V>(internal : Internal<K, V>) : Stack.Stack<NodeCursor<K, V>> {\n let nodeCursorStack = Stack.empty<NodeCursor<K, V>>();\n let nodeCursor : NodeCursor<K, V> = {\n node = #internal(internal);\n kvIndex = internal.data.count\n };\n\n // push the initial cursor to the stack\n Stack.push(nodeCursorStack, nodeCursor);\n // then traverse left\n traverseMaxSubtreeIter(nodeCursorStack, nodeCursor);\n nodeCursorStack\n };\n\n func initializeReverseNodeCursorStackFrom<K, V>(internal : Internal<K, V>, compare : (K, K) -> Order.Order, key : K) : Stack.Stack<NodeCursor<K, V>> {\n let nodeCursorStack = Stack.empty<NodeCursor<K, V>>();\n let nodeCursor : NodeCursor<K, V> = {\n node = #internal(internal);\n kvIndex = internal.data.count\n };\n\n traverseMaxSubtreeIterFrom(nodeCursorStack, nodeCursor, compare, key);\n nodeCursorStack\n };\n\n // traverse the min subtree of the current node cursor, passing each new element to the node cursor stack\n func traverseMinSubtreeIter<K, V>(nodeCursorStack : Stack.Stack<NodeCursor<K, V>>, nodeCursor : NodeCursor<K, V>) {\n var currentNode = nodeCursor.node;\n var childIndex = nodeCursor.kvIndex;\n\n label l loop {\n switch (currentNode) {\n // If currentNode is leaf, have hit the minimum element of the subtree and already pushed it's cursor to the stack\n // so can return\n case (#leaf(_)) {\n return\n };\n // If currentNode is internal, add it's left most child to the stack and continue traversing\n case (#internal(internalNode)) {\n switch (internalNode.children[childIndex]) {\n // Push the next min (left most) child node to the stack\n case (?childNode) {\n childIndex := 0;\n currentNode := childNode;\n Stack.push(\n nodeCursorStack,\n {\n node = currentNode;\n kvIndex = childIndex\n }\n )\n };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.traverseMinSubtreeIter(), null child node error\")\n }\n }\n }\n }\n }\n };\n\n func traverseMinSubtreeIterFrom<K, V>(nodeCursorStack : Stack.Stack<NodeCursor<K, V>>, nodeCursor : NodeCursor<K, V>, compare : (K, K) -> Order.Order, key : K) {\n var currentNode = nodeCursor.node;\n\n label l loop {\n let (node, childrenOption) = switch (currentNode) {\n case (#leaf(leafNode)) (leafNode, null);\n case (#internal(internalNode)) (internalNode, ?internalNode.children)\n };\n let (i, isFound) = switch (NodeUtil.getKeyIndex<K, V>(node.data, compare, key)) {\n case (#keyFound(i)) (i, true);\n case (#notFound(i)) (i, false)\n };\n if (i < node.data.count) {\n Stack.push(\n nodeCursorStack,\n {\n node = currentNode;\n kvIndex = i // greater entries to traverse\n }\n )\n };\n if isFound return;\n let ?children = childrenOption else return;\n let ?childNode = children[i] else Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.traverseMinSubtreeIterFrom(), null child node error\");\n currentNode := childNode\n }\n };\n\n // traverse the max subtree of the current node cursor, passing each new element to the node cursor stack\n func traverseMaxSubtreeIter<K, V>(nodeCursorStack : Stack.Stack<NodeCursor<K, V>>, nodeCursor : NodeCursor<K, V>) {\n var currentNode = nodeCursor.node;\n var childIndex = nodeCursor.kvIndex;\n\n label l loop {\n switch (currentNode) {\n // If currentNode is leaf, have hit the maximum element of the subtree and already pushed it's cursor to the stack\n // so can return\n case (#leaf(_)) {\n return\n };\n // If currentNode is internal, add it's right most child to the stack and continue traversing\n case (#internal(internalNode)) {\n assert (childIndex <= internalNode.data.count); // children are one more than data entries\n switch (internalNode.children[childIndex]) {\n // Push the next max (right most) child node to the stack\n case (?childNode) {\n childIndex := switch (childNode) {\n case (#internal(internalNode)) internalNode.data.count;\n case (#leaf(leafNode)) leafNode.data.count\n };\n currentNode := childNode;\n Stack.push(\n nodeCursorStack,\n {\n node = currentNode;\n kvIndex = childIndex\n }\n )\n };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.traverseMaxSubtreeIter(), null child node error\")\n }\n }\n }\n }\n }\n };\n\n func traverseMaxSubtreeIterFrom<K, V>(nodeCursorStack : Stack.Stack<NodeCursor<K, V>>, nodeCursor : NodeCursor<K, V>, compare : (K, K) -> Order.Order, key : K) {\n var currentNode = nodeCursor.node;\n\n label l loop {\n let (node, childrenOption) = switch (currentNode) {\n case (#leaf(leafNode)) (leafNode, null);\n case (#internal(internalNode)) (internalNode, ?internalNode.children)\n };\n let (i, isFound) = switch (NodeUtil.getKeyIndex<K, V>(node.data, compare, key)) {\n case (#keyFound(i)) (i + 1, true); // +1 to include this key\n case (#notFound(i)) (i, false) // i is the index of the first key less than the search key, or 0 if all keys are greater than the search key\n };\n if (i > 0) {\n Stack.push(\n nodeCursorStack,\n {\n node = currentNode;\n kvIndex = i\n }\n )\n };\n if isFound return;\n let ?children = childrenOption else return;\n let ?childNode = children[i] else Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.traverseMaxSubtreeIterFrom(), null child node error\");\n currentNode := childNode\n }\n };\n\n // This type is used to signal to the parent calling context what happened in the level below\n type IntermediateInternalDeleteResult<K, V> = {\n // element was deleted or not found, returning the old value (?value or null)\n #delete : ?V;\n // deleted an element, but was unable to successfully borrow and rebalance at the previous level without merging children\n // the internalChild is the merged child that needs to be rebalanced at the next level up in the BTree\n #mergeChild : {\n internalChild : Internal<K, V>;\n deletedValue : ?V\n }\n };\n\n func internalDeleteHelper<K, V>(internalNode : Internal<K, V>, order : Nat, compare : (K, K) -> Order.Order, deleteKey : K, skipNode : Bool) : IntermediateInternalDeleteResult<K, V> {\n let minKeys = NodeUtil.minKeysFromOrder(order);\n let keyIndex = NodeUtil.getKeyIndex<K, V>(internalNode.data, compare, deleteKey);\n\n // match on both the result of the node binary search, and if this node level should be skipped even if the key is found (internal kv replacement case)\n switch (keyIndex, skipNode) {\n // if key is found in the internal node\n case (#keyFound(deleteIndex), false) {\n let deletedValue = switch (internalNode.data.kvs[deleteIndex]) {\n case (?kv) { ?kv.1 };\n case null { assert false; null }\n };\n // TODO: (optimization) replace with deletion in one step without having to retrieve the maxKey first\n let replaceKV = NodeUtil.getMaxKeyValue(internalNode.children[deleteIndex]);\n internalNode.data.kvs[deleteIndex] := ?replaceKV;\n switch (internalDeleteHelper(internalNode, order, compare, replaceKV.0, true)) {\n case (#delete(_)) { #delete(deletedValue) };\n case (#mergeChild({ internalChild })) {\n #mergeChild({ internalChild; deletedValue })\n }\n }\n };\n // if key is not found in the internal node OR the key is found, but skipping this node (because deleting the in order precessor i.e. replacement kv)\n // in both cases need to descend and traverse to find the kv to delete\n case ((#keyFound(_), true) or (#notFound(_), _)) {\n let childIndex = switch (keyIndex) {\n case (#keyFound(replacedSkipKeyIndex)) { replacedSkipKeyIndex };\n case (#notFound(childIndex)) { childIndex }\n };\n let child = switch (internalNode.children[childIndex]) {\n case (?c) { c };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.internalDeleteHelper, child index of #keyFound or #notfound is null\")\n }\n };\n switch (child) {\n // if child is internal\n case (#internal(internalChild)) {\n switch (internalDeleteHelper(internalChild, order, compare, deleteKey, false), childIndex == 0) {\n // if value was successfully deleted and no additional tree re-balancing is needed, return the deleted value\n case (#delete(v), _) { #delete(v) };\n // if internalChild needs rebalancing and pulling child is left most\n case (#mergeChild({ internalChild; deletedValue }), true) {\n // try to pull left-most key and child from right sibling\n switch (NodeUtil.borrowFromInternalSibling(internalNode.children, childIndex + 1, #successor)) {\n // if can pull up sibling kv and child\n case (#borrowed({ deletedSiblingKVPair; child })) {\n NodeUtil.rotateBorrowedKVsAndChildFromSibling(\n internalNode,\n childIndex,\n deletedSiblingKVPair,\n child,\n internalChild,\n #right\n );\n #delete(deletedValue)\n };\n // unable to pull from sibling, need to merge with right sibling and push down parent\n case (#notEnoughKeys(sibling)) {\n // get the parent kv that will be pushed down the the child\n let kvPairToBePushedToChild = ?BTreeHelper.deleteAndShift(internalNode.data.kvs, 0);\n internalNode.data.count -= 1;\n // merge the children and push down the parent\n let newChild = NodeUtil.mergeChildrenAndPushDownParent<K, V>(internalChild, kvPairToBePushedToChild, sibling);\n // update children of the parent\n internalNode.children[0] := ?#internal(newChild);\n ignore ?BTreeHelper.deleteAndShift(internalNode.children, 1);\n\n if (internalNode.data.count < minKeys) {\n #mergeChild({ internalChild = internalNode; deletedValue })\n } else {\n #delete(deletedValue)\n }\n }\n }\n };\n // if internalChild needs rebalancing and pulling child is > 0, so a left sibling exists\n case (#mergeChild({ internalChild; deletedValue }), false) {\n // try to pull right-most key and its child directly from left sibling\n switch (NodeUtil.borrowFromInternalSibling(internalNode.children, childIndex - 1 : Nat, #predecessor)) {\n case (#borrowed({ deletedSiblingKVPair; child })) {\n NodeUtil.rotateBorrowedKVsAndChildFromSibling(\n internalNode,\n childIndex - 1 : Nat,\n deletedSiblingKVPair,\n child,\n internalChild,\n #left\n );\n #delete(deletedValue)\n };\n // unable to pull from left sibling\n case (#notEnoughKeys(leftSibling)) {\n // if child is not last index, try to pull from the right child\n if (childIndex < internalNode.data.count) {\n switch (NodeUtil.borrowFromInternalSibling(internalNode.children, childIndex, #successor)) {\n // if can pull up sibling kv and child\n case (#borrowed({ deletedSiblingKVPair; child })) {\n NodeUtil.rotateBorrowedKVsAndChildFromSibling(\n internalNode,\n childIndex,\n deletedSiblingKVPair,\n child,\n internalChild,\n #right\n );\n return #delete(deletedValue)\n };\n // if cannot borrow, from left or right, merge (see below)\n case _ {}\n }\n };\n\n // get the parent kv that will be pushed down the the child\n let kvPairToBePushedToChild = ?BTreeHelper.deleteAndShift(internalNode.data.kvs, childIndex - 1 : Nat);\n internalNode.data.count -= 1;\n // merge it the children and push down the parent\n let newChild = NodeUtil.mergeChildrenAndPushDownParent(leftSibling, kvPairToBePushedToChild, internalChild);\n\n // update children of the parent\n internalNode.children[childIndex - 1] := ?#internal(newChild);\n ignore ?BTreeHelper.deleteAndShift(internalNode.children, childIndex);\n\n if (internalNode.data.count < minKeys) {\n #mergeChild({ internalChild = internalNode; deletedValue })\n } else {\n #delete(deletedValue)\n }\n }\n }\n }\n }\n };\n // if child is leaf\n case (#leaf(leafChild)) {\n switch (leafDeleteHelper(leafChild, order, compare, deleteKey), childIndex == 0) {\n case (#delete(value), _) { #delete(value) };\n // if delete child is left most, try to borrow from right child\n case (#mergeLeafData({ leafDeleteIndex }), true) {\n switch (NodeUtil.borrowFromRightLeafChild(internalNode.children, childIndex)) {\n case (?borrowedKVPair) {\n let kvPairToBePushedToChild = internalNode.data.kvs[childIndex];\n internalNode.data.kvs[childIndex] := ?borrowedKVPair;\n\n let deletedKV = BTreeHelper.insertAtPostionAndDeleteAtPosition<(K, V)>(leafChild.data.kvs, kvPairToBePushedToChild, leafChild.data.count - 1, leafDeleteIndex);\n #delete(?deletedKV.1)\n };\n\n case null {\n // can't borrow from right child, delete from leaf and merge with right child and parent kv, then push down into new leaf\n let rightChild = switch (internalNode.children[childIndex + 1]) {\n case (?#leaf(rc)) { rc };\n case _ {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.internalDeleteHelper, if trying to borrow from right leaf child is null, rightChild index cannot be null or internal\")\n }\n };\n let (mergedLeaf, deletedKV) = mergeParentWithLeftRightChildLeafNodesAndDelete(\n internalNode.data.kvs[childIndex],\n leafChild,\n rightChild,\n leafDeleteIndex,\n #left\n );\n // delete the left most internal node kv, since was merging from a deletion in left most child (0) and the parent kv was pushed into the mergedLeaf\n ignore BTreeHelper.deleteAndShift<(K, V)>(internalNode.data.kvs, 0);\n // update internal node children\n BTreeHelper.replaceTwoWithElementAndShift<Node<K, V>>(internalNode.children, #leaf(mergedLeaf), 0);\n internalNode.data.count -= 1;\n\n if (internalNode.data.count < minKeys) {\n #mergeChild({\n internalChild = internalNode;\n deletedValue = ?deletedKV.1\n })\n } else {\n #delete(?deletedKV.1)\n }\n\n }\n }\n };\n // if delete child is middle or right most, try to borrow from left child\n case (#mergeLeafData({ leafDeleteIndex }), false) {\n // if delete child is right most, try to borrow from left child\n switch (NodeUtil.borrowFromLeftLeafChild(internalNode.children, childIndex)) {\n case (?borrowedKVPair) {\n let kvPairToBePushedToChild = internalNode.data.kvs[childIndex - 1];\n internalNode.data.kvs[childIndex - 1] := ?borrowedKVPair;\n let kvDelete = BTreeHelper.insertAtPostionAndDeleteAtPosition<(K, V)>(leafChild.data.kvs, kvPairToBePushedToChild, 0, leafDeleteIndex);\n #delete(?kvDelete.1)\n };\n case null {\n // if delete child is in the middle, try to borrow from right child\n if (childIndex < internalNode.data.count) {\n // try to borrow from right\n switch (NodeUtil.borrowFromRightLeafChild(internalNode.children, childIndex)) {\n case (?borrowedKVPair) {\n let kvPairToBePushedToChild = internalNode.data.kvs[childIndex];\n internalNode.data.kvs[childIndex] := ?borrowedKVPair;\n // insert the successor at the very last element\n let kvDelete = BTreeHelper.insertAtPostionAndDeleteAtPosition<(K, V)>(leafChild.data.kvs, kvPairToBePushedToChild, leafChild.data.count - 1, leafDeleteIndex);\n return #delete(?kvDelete.1)\n };\n // if cannot borrow, from left or right, merge (see below)\n case _ {}\n }\n };\n\n // can't borrow from left child, delete from leaf and merge with left child and parent kv, then push down into new leaf\n let leftChild = switch (internalNode.children[childIndex - 1]) {\n case (?#leaf(lc)) { lc };\n case _ {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.internalDeleteHelper, if trying to borrow from left leaf child is null, then left child index must not be null or internal\")\n }\n };\n let (mergedLeaf, deletedKV) = mergeParentWithLeftRightChildLeafNodesAndDelete(\n internalNode.data.kvs[childIndex - 1],\n leftChild,\n leafChild,\n leafDeleteIndex,\n #right\n );\n // delete the right most internal node kv, since was merging from a deletion in the right most child and the parent kv was pushed into the mergedLeaf\n ignore BTreeHelper.deleteAndShift<(K, V)>(internalNode.data.kvs, childIndex - 1);\n // update internal node children\n BTreeHelper.replaceTwoWithElementAndShift<Node<K, V>>(internalNode.children, #leaf(mergedLeaf), childIndex - 1);\n internalNode.data.count -= 1;\n\n if (internalNode.data.count < minKeys) {\n #mergeChild({\n internalChild = internalNode;\n deletedValue = ?deletedKV.1\n })\n } else {\n #delete(?deletedKV.1)\n }\n }\n }\n }\n }\n }\n }\n }\n }\n };\n\n // This type is used to signal to the parent calling context what happened in the level below\n type IntermediateLeafDeleteResult<K, V> = {\n // element was deleted or not found, returning the old value (?value or null)\n #delete : ?V;\n // leaf had the minimum number of keys when deleting, so returns the leaf node's data and the index of the key that will be deleted\n #mergeLeafData : {\n data : Data<K, V>;\n leafDeleteIndex : Nat\n }\n };\n\n func leafDeleteHelper<K, V>(leafNode : Leaf<K, V>, order : Nat, compare : (K, K) -> Order.Order, deleteKey : K) : IntermediateLeafDeleteResult<K, V> {\n let minKeys = NodeUtil.minKeysFromOrder(order);\n\n switch (NodeUtil.getKeyIndex<K, V>(leafNode.data, compare, deleteKey)) {\n case (#keyFound(deleteIndex)) {\n if (leafNode.data.count > minKeys) {\n leafNode.data.count -= 1;\n #delete(?BTreeHelper.deleteAndShift<(K, V)>(leafNode.data.kvs, deleteIndex).1)\n } else {\n #mergeLeafData({\n data = leafNode.data;\n leafDeleteIndex = deleteIndex\n })\n }\n };\n case (#notFound(_)) {\n #delete(null)\n }\n }\n };\n\n // get helper if internal node\n func getFromInternal<K, V>(internalNode : Internal<K, V>, compare : (K, K) -> Order.Order, key : K) : ?V {\n switch (NodeUtil.getKeyIndex<K, V>(internalNode.data, compare, key)) {\n case (#keyFound(index)) {\n getExistingValueFromIndex(internalNode.data, index)\n };\n case (#notFound(index)) {\n switch (internalNode.children[index]) {\n // expects the child to be there, otherwise there's a bug in binary search or the tree is invalid\n case null { Runtime.trap(\"Internal bug: Map.getFromInternal\") };\n case (?#leaf(leafNode)) { getFromLeaf(leafNode, compare, key) };\n case (?#internal(internalNode)) {\n getFromInternal(internalNode, compare, key)\n }\n }\n }\n }\n };\n\n // get function helper if leaf node\n func getFromLeaf<K, V>(leafNode : Leaf<K, V>, compare : (K, K) -> Order.Order, key : K) : ?V {\n switch (NodeUtil.getKeyIndex<K, V>(leafNode.data, compare, key)) {\n case (#keyFound(index)) {\n getExistingValueFromIndex(leafNode.data, index)\n };\n case _ null\n }\n };\n\n // get function helper that retrieves an existing value in the case that the key is found\n func getExistingValueFromIndex<K, V>(data : Data<K, V>, index : Nat) : ?V {\n switch (data.kvs[index]) {\n case null { null };\n case (?ov) { ?ov.1 }\n }\n };\n\n // which child the deletionIndex is referring to\n type DeletionSide = { #left; #right };\n\n func mergeParentWithLeftRightChildLeafNodesAndDelete<K, V>(\n parentKV : ?(K, V),\n leftChild : Leaf<K, V>,\n rightChild : Leaf<K, V>,\n deleteIndex : Nat,\n deletionSide : DeletionSide\n ) : (Leaf<K, V>, (K, V)) {\n let count = leftChild.data.count * 2;\n let (kvs, deletedKV) = BTreeHelper.mergeParentWithChildrenAndDelete<(K, V)>(\n parentKV,\n leftChild.data.count,\n leftChild.data.kvs,\n rightChild.data.kvs,\n deleteIndex,\n deletionSide\n );\n (\n {\n data = {\n kvs;\n var count = count\n }\n },\n deletedKV\n )\n };\n\n // This type is used to signal to the parent calling context what happened in the level below\n type IntermediateInsertResult<K, V> = {\n // element was inserted or replaced, returning the old value (?value or null)\n #insert : ?V;\n // child was full when inserting, so returns the promoted kv pair and the split left and right child\n #promote : {\n kv : (K, V);\n leftChild : Node<K, V>;\n rightChild : Node<K, V>\n }\n };\n\n // Helper for inserting into a leaf node\n func leafInsertHelper<K, V>(leafNode : Leaf<K, V>, order : Nat, compare : (K, K) -> Order.Order, key : K, value : V) : (IntermediateInsertResult<K, V>) {\n // Perform binary search to see if the element exists in the node\n switch (NodeUtil.getKeyIndex<K, V>(leafNode.data, compare, key)) {\n case (#keyFound(insertIndex)) {\n let previous = leafNode.data.kvs[insertIndex];\n leafNode.data.kvs[insertIndex] := ?(key, value);\n switch (previous) {\n case (?ov) { #insert(?ov.1) };\n case null { assert false; #insert(null) }; // the binary search already found an element, so this case should never happen\n }\n };\n case (#notFound(insertIndex)) {\n // Note: BTree will always have an order >= 4, so this will never have negative Nat overflow\n let maxKeys : Nat = order - 1;\n // If the leaf is full, insert, split the node, and promote the middle element\n if (leafNode.data.count >= maxKeys) {\n let (leftKVs, promotedParentElement, rightKVs) = BTreeHelper.insertOneAtIndexAndSplitArray(\n leafNode.data.kvs,\n (key, value),\n insertIndex\n );\n\n let leftCount = order / 2;\n let rightCount : Nat = if (order % 2 == 0) { leftCount - 1 } else {\n leftCount\n };\n\n (\n #promote({\n kv = promotedParentElement;\n leftChild = createLeaf<K, V>(leftKVs, leftCount);\n rightChild = createLeaf<K, V>(rightKVs, rightCount)\n })\n )\n }\n // Otherwise, insert at the specified index (shifting elements over if necessary)\n else {\n NodeUtil.insertAtIndexOfNonFullNodeData<K, V>(leafNode.data, ?(key, value), insertIndex);\n #insert(null)\n }\n }\n }\n };\n\n // Helper for inserting into an internal node\n func internalInsertHelper<K, V>(internalNode : Internal<K, V>, order : Nat, compare : (K, K) -> Order.Order, key : K, value : V) : IntermediateInsertResult<K, V> {\n switch (NodeUtil.getKeyIndex<K, V>(internalNode.data, compare, key)) {\n case (#keyFound(insertIndex)) {\n let previous = internalNode.data.kvs[insertIndex];\n internalNode.data.kvs[insertIndex] := ?(key, value);\n switch (previous) {\n case (?ov) { #insert(?ov.1) };\n case null { assert false; #insert(null) }; // the binary search already found an element, so this case should never happen\n }\n };\n case (#notFound(insertIndex)) {\n let insertResult = switch (internalNode.children[insertIndex]) {\n case null { assert false; #insert(null) };\n case (?#leaf(leafNode)) {\n leafInsertHelper(leafNode, order, compare, key, value)\n };\n case (?#internal(internalChildNode)) {\n internalInsertHelper(internalChildNode, order, compare, key, value)\n }\n };\n\n switch (insertResult) {\n case (#insert(ov)) { #insert(ov) };\n case (#promote({ kv; leftChild; rightChild })) {\n // Note: BTree will always have an order >= 4, so this will never have negative Nat overflow\n let maxKeys : Nat = order - 1;\n // if current internal node is full, need to split the internal node\n if (internalNode.data.count >= maxKeys) {\n // insert and split internal kvs, determine new promotion target kv\n let (leftKVs, promotedParentElement, rightKVs) = BTreeHelper.insertOneAtIndexAndSplitArray(\n internalNode.data.kvs,\n (kv),\n insertIndex\n );\n\n // calculate the element count in the left KVs and the element count in the right KVs\n let leftCount = order / 2;\n let rightCount : Nat = if (order % 2 == 0) { leftCount - 1 } else {\n leftCount\n };\n\n // split internal children\n let (leftChildren, rightChildren) = NodeUtil.splitChildrenInTwoWithRebalances<K, V>(\n internalNode.children,\n insertIndex,\n leftChild,\n rightChild\n );\n\n // send the kv to be promoted, as well as the internal children left and right split\n #promote({\n kv = promotedParentElement;\n leftChild = #internal({\n data = { kvs = leftKVs; var count = leftCount };\n children = leftChildren\n });\n rightChild = #internal({\n data = { kvs = rightKVs; var count = rightCount };\n children = rightChildren\n })\n })\n } else {\n // insert the new kvs into the internal node\n NodeUtil.insertAtIndexOfNonFullNodeData(internalNode.data, ?kv, insertIndex);\n // split and re-insert the single child that needs rebalancing\n NodeUtil.insertRebalancedChild(internalNode.children, insertIndex, leftChild, rightChild);\n #insert(null)\n }\n }\n }\n }\n }\n };\n\n func createLeaf<K, V>(kvs : [var ?(K, V)], count : Nat) : Node<K, V> {\n #leaf({\n data = {\n kvs;\n var count\n }\n })\n };\n\n // Additional functionality compared to original source.\n\n func mapData<K, V1, V2>(data : Data<K, V1>, project : (K, V1) -> V2) : Data<K, V2> {\n {\n kvs = VarArray.map<?(K, V1), ?(K, V2)>(\n data.kvs,\n func entry {\n switch entry {\n case (?kv) ?(kv.0, project kv);\n case null null\n }\n }\n );\n var count = data.count\n }\n };\n\n func mapNode<K, V1, V2>(node : Node<K, V1>, project : (K, V1) -> V2) : Node<K, V2> {\n switch node {\n case (#leaf { data }) {\n #leaf { data = mapData(data, project) }\n };\n case (#internal { data; children }) {\n let mappedData = mapData<K, V1, V2>(data, project);\n let mappedChildren = VarArray.map<?Node<K, V1>, ?Node<K, V2>>(\n children,\n func child {\n switch child {\n case null null;\n case (?childNode) ?mapNode(childNode, project)\n }\n }\n );\n # internal({\n data = mappedData;\n children = mappedChildren\n })\n }\n }\n };\n\n func cloneNode<K, V>(node : Node<K, V>) : Node<K, V> = mapNode<K, V, V>(node, func(k, v) = v);\n\n module BinarySearch {\n public type SearchResult = {\n #keyFound : Nat;\n #notFound : Nat\n };\n\n /// Searches an array for a specific key, returning the index it occurs at if #keyFound, or the child/insert index it may occur at\n /// if #notFound. This is used when determining if a key exists in an internal or leaf node, where a key should be inserted in a\n /// leaf node, or which child of an internal node a key could be in.\n ///\n /// Note: This function expects a mutable, nullable, array of keys in sorted order, where all nulls appear at the end of the array.\n /// This function may trap if a null value appears before any values. It also expects a maxIndex, which is the right-most index (bound)\n /// from which to begin the binary search (the left most bound is expected to be 0)\n ///\n /// Parameters:\n ///\n /// * array - the sorted array that the binary search is performed upon\n /// * compare - the comparator used to perform the search\n /// * searchKey - the key being compared against in the search\n /// * maxIndex - the right-most index (bound) from which to begin the search\n public func binarySearchNode<K, V>(array : [var ?(K, V)], compare : (K, K) -> Order.Order, searchKey : K, maxIndex : Nat) : SearchResult {\n // TODO: get rid of this check?\n // Trap if array is size 0 (should not happen)\n if (array.size() == 0) {\n assert false\n };\n\n // if all elements in the array are null (i.e. first element is null), return #notFound(0)\n if (maxIndex == 0) {\n return #notFound(0)\n };\n\n // Initialize search from first to last index\n var left : Nat = 0;\n var right = maxIndex; // maxIndex does not necessarily mean array.size() - 1\n // Search the array\n while (left < right) {\n let middle = (left + right) / 2;\n switch (array[middle]) {\n case null { assert false };\n case (?(key, _)) {\n switch (compare(searchKey, key)) {\n // If the element is present at the middle itself\n case (#equal) { return #keyFound(middle) };\n // If element is greater than mid, it can only be present in left subarray\n case (#greater) { left := middle + 1 };\n // If element is smaller than mid, it can only be present in right subarray\n case (#less) {\n right := if (middle == 0) { 0 } else { middle - 1 }\n }\n }\n }\n }\n };\n\n if (left == array.size()) {\n return #notFound(left)\n };\n\n // left == right\n switch (array[left]) {\n // inserting at end of array\n case null { #notFound(left) };\n case (?(key, _)) {\n switch (compare(searchKey, key)) {\n // if left is the key\n case (#equal) { #keyFound(left) };\n // if the key is not found, return notFound and the insert location\n case (#greater) { #notFound(left + 1) };\n case (#less) { #notFound(left) }\n }\n }\n }\n }\n };\n\n module NodeUtil {\n /// Inserts element at the given index into a non-full leaf node\n public func insertAtIndexOfNonFullNodeData<K, V>(data : Data<K, V>, kvPair : ?(K, V), insertIndex : Nat) {\n let currentLastElementIndex : Nat = if (data.count == 0) { 0 } else {\n data.count - 1\n };\n BTreeHelper.insertAtPosition<(K, V)>(data.kvs, kvPair, insertIndex, currentLastElementIndex);\n\n // increment the count of data in this node since just inserted an element\n data.count += 1\n };\n\n /// Inserts two rebalanced (split) child halves into a non-full array of children.\n public func insertRebalancedChild<K, V>(children : [var ?Node<K, V>], rebalancedChildIndex : Nat, leftChildInsert : Node<K, V>, rightChildInsert : Node<K, V>) {\n // Note: BTree will always have an order >= 4, so this will never have negative Nat overflow\n var j : Nat = children.size() - 2;\n\n // This is just a sanity check to ensure the children aren't already full (should split promote otherwise)\n // TODO: Remove this check once confident\n if (Option.isSome(children[j + 1])) { assert false };\n\n // Iterate backwards over the array and shift each element over to the right by one until the rebalancedChildIndex is hit\n while (j > rebalancedChildIndex) {\n children[j + 1] := children[j];\n j -= 1\n };\n\n // Insert both the left and right rebalanced children (replacing the pre-split child)\n children[j] := ?leftChildInsert;\n children[j + 1] := ?rightChildInsert\n };\n\n /// Used when splitting the children of an internal node\n ///\n /// Takes in the rebalanced child index, as well as both halves of the rebalanced child and splits the children, inserting the left and right child halves appropriately\n ///\n /// For more context, see the documentation for the splitArrayAndInsertTwo method in BTreeHelper.mo\n public func splitChildrenInTwoWithRebalances<K, V>(\n children : [var ?Node<K, V>],\n rebalancedChildIndex : Nat,\n leftChildInsert : Node<K, V>,\n rightChildInsert : Node<K, V>\n ) : ([var ?Node<K, V>], [var ?Node<K, V>]) {\n BTreeHelper.splitArrayAndInsertTwo<Node<K, V>>(children, rebalancedChildIndex, leftChildInsert, rightChildInsert)\n };\n\n /// Helper used to get the key index of of a key within a node\n ///\n /// for more, see the BinarySearch.binarySearchNode() documentation\n public func getKeyIndex<K, V>(data : Data<K, V>, compare : (K, K) -> Order.Order, key : K) : BinarySearch.SearchResult {\n BinarySearch.binarySearchNode<K, V>(data.kvs, compare, key, data.count)\n };\n\n // calculates a BTree Node's minimum allowed keys given the order of the BTree\n public func minKeysFromOrder(order : Nat) : Nat {\n if (order % 2 == 0) { order / 2 - 1 } else { order / 2 }\n };\n\n // Given a node, get the maximum key value (right most leaf kv)\n public func getMaxKeyValue<K, V>(node : ?Node<K, V>) : (K, V) {\n switch (node) {\n case (?#leaf({ data })) {\n switch (data.kvs[data.count - 1]) {\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.NodeUtil.getMaxKeyValue, data cannot have more elements than it's count\")\n };\n case (?kv) { kv }\n }\n };\n case (?#internal({ data; children })) {\n getMaxKeyValue(children[data.count])\n };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.NodeUtil.getMaxKeyValue, the node provided cannot be null\")\n }\n }\n };\n\n type InorderBorrowType = {\n #predecessor;\n #successor\n };\n\n // attempts to retrieve the in max key of the child leaf node directly to the left if the node will allow it\n // returns the deleted max key if able to retrieve, null if not able\n //\n // mutates the predecessing node's keys\n public func borrowFromLeftLeafChild<K, V>(children : [var ?Node<K, V>], ofChildIndex : Nat) : ?(K, V) {\n let predecessorIndex : Nat = ofChildIndex - 1;\n borrowFromLeafChild(children, predecessorIndex, #predecessor)\n };\n\n // attempts to retrieve the in max key of the child leaf node directly to the right if the node will allow it\n // returns the deleted max key if able to retrieve, null if not able\n //\n // mutates the predecessing node's keys\n public func borrowFromRightLeafChild<K, V>(children : [var ?Node<K, V>], ofChildIndex : Nat) : ?(K, V) {\n borrowFromLeafChild(children, ofChildIndex + 1, #successor)\n };\n\n func borrowFromLeafChild<K, V>(children : [var ?Node<K, V>], borrowChildIndex : Nat, childSide : InorderBorrowType) : ?(K, V) {\n let minKeys = minKeysFromOrder(children.size());\n\n switch (children[borrowChildIndex]) {\n case (?#leaf({ data })) {\n if (data.count > minKeys) {\n // able to borrow a key-value from this child, so decrement the count of kvs\n data.count -= 1; // Since enforce order >= 4, there will always be at least 1 element per node\n switch (childSide) {\n case (#predecessor) {\n let deletedKV = data.kvs[data.count];\n data.kvs[data.count] := null;\n deletedKV\n };\n case (#successor) {\n ?BTreeHelper.deleteAndShift(data.kvs, 0)\n }\n }\n } else { null }\n };\n case _ {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.NodeUtil.borrowFromLeafChild, the node at the borrow child index cannot be null or internal\")\n }\n }\n };\n\n type InternalBorrowResult<K, V> = {\n #borrowed : InternalBorrow<K, V>;\n #notEnoughKeys : Internal<K, V>\n };\n\n type InternalBorrow<K, V> = {\n deletedSiblingKVPair : ?(K, V);\n child : ?Node<K, V>\n };\n\n // Attempts to borrow a KV and child from an internal sibling node\n public func borrowFromInternalSibling<K, V>(children : [var ?Node<K, V>], borrowChildIndex : Nat, borrowType : InorderBorrowType) : InternalBorrowResult<K, V> {\n let minKeys = minKeysFromOrder(children.size());\n\n switch (children[borrowChildIndex]) {\n case (?#internal({ data; children })) {\n if (data.count > minKeys) {\n data.count -= 1;\n switch (borrowType) {\n case (#predecessor) {\n let deletedSiblingKVPair = data.kvs[data.count];\n data.kvs[data.count] := null;\n let child = children[data.count + 1];\n children[data.count + 1] := null;\n #borrowed({\n deletedSiblingKVPair;\n child\n })\n };\n case (#successor) {\n #borrowed({\n deletedSiblingKVPair = ?BTreeHelper.deleteAndShift(data.kvs, 0);\n child = ?BTreeHelper.deleteAndShift(children, 0)\n })\n }\n }\n } else { #notEnoughKeys({ data; children }) }\n };\n case _ {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Map.NodeUtil.borrowFromInternalSibling from internal sibling, the child at the borrow index cannot be null or a leaf\")\n }\n }\n };\n\n type SiblingSide = { #left; #right };\n\n // Rotates the borrowed KV and child from sibling side of the internal node to the internal child recipient\n public func rotateBorrowedKVsAndChildFromSibling<K, V>(\n internalNode : Internal<K, V>,\n parentRotateIndex : Nat,\n borrowedSiblingKVPair : ?(K, V),\n borrowedSiblingChild : ?Node<K, V>,\n internalChildRecipient : Internal<K, V>,\n siblingSide : SiblingSide\n ) {\n // if borrowing from the left, the rotated key and child will always be inserted first\n // if borrowing from the right, the rotated key and child will always be inserted last\n let (kvIndex, childIndex) = switch (siblingSide) {\n case (#left) { (0, 0) };\n case (#right) {\n (internalChildRecipient.data.count, internalChildRecipient.data.count + 1)\n }\n };\n\n // get the parent kv that will be pushed down the the child\n let kvPairToBePushedToChild = internalNode.data.kvs[parentRotateIndex];\n // replace the parent with the sibling kv\n internalNode.data.kvs[parentRotateIndex] := borrowedSiblingKVPair;\n // push the kv and child down into the internalChild\n insertAtIndexOfNonFullNodeData<K, V>(internalChildRecipient.data, kvPairToBePushedToChild, kvIndex);\n\n BTreeHelper.insertAtPosition<Node<K, V>>(internalChildRecipient.children, borrowedSiblingChild, childIndex, internalChildRecipient.data.count)\n };\n\n // Merges the kvs and children of two internal nodes, pushing the parent kv in between the right and left halves\n public func mergeChildrenAndPushDownParent<K, V>(leftChild : Internal<K, V>, parentKV : ?(K, V), rightChild : Internal<K, V>) : Internal<K, V> {\n {\n data = mergeData<K, V>(leftChild.data, parentKV, rightChild.data);\n children = mergeChildren(leftChild.children, rightChild.children)\n }\n };\n\n func mergeData<K, V>(leftData : Data<K, V>, parentKV : ?(K, V), rightData : Data<K, V>) : Data<K, V> {\n assert leftData.count <= minKeysFromOrder(leftData.kvs.size() + 1);\n assert rightData.count <= minKeysFromOrder(rightData.kvs.size() + 1);\n\n let mergedKVs = VarArray.repeat<?(K, V)>(null, leftData.kvs.size());\n var i = 0;\n while (i < leftData.count) {\n mergedKVs[i] := leftData.kvs[i];\n i += 1\n };\n\n mergedKVs[i] := parentKV;\n i += 1;\n\n var j = 0;\n while (j < rightData.count) {\n mergedKVs[i] := rightData.kvs[j];\n i += 1;\n j += 1\n };\n\n {\n kvs = mergedKVs;\n var count = leftData.count + 1 + rightData.count\n }\n };\n\n func mergeChildren<K, V>(leftChildren : [var ?Node<K, V>], rightChildren : [var ?Node<K, V>]) : [var ?Node<K, V>] {\n let mergedChildren = VarArray.repeat<?Node<K, V>>(null, leftChildren.size());\n var i = 0;\n\n while (Option.isSome(leftChildren[i])) {\n mergedChildren[i] := leftChildren[i];\n i += 1\n };\n\n var j = 0;\n while (Option.isSome(rightChildren[j])) {\n mergedChildren[i] := rightChildren[j];\n i += 1;\n j += 1\n };\n\n mergedChildren\n }\n }\n}\n"},"Set.mo":{"content":"/// Imperative (mutable) sets based on order/comparison of elements.\n/// A set is a collection of elements without duplicates.\n/// The set data structure type is stable and can be used for orthogonal persistence.\n///\n/// Example:\n/// ```motoko\n/// import Set \"mo:core/Set\";\n/// import Nat \"mo:core/Nat\";\n///\n/// persistent actor {\n/// let set = Set.fromIter([3, 1, 2, 3].vals(), Nat.compare);\n/// assert Set.size(set) == 3;\n/// assert not Set.contains(set, Nat.compare, 4);\n/// let diff = Set.difference(set, set, Nat.compare);\n/// assert Set.isEmpty(diff);\n/// }\n/// ```\n///\n/// These sets are implemented as B-trees with order 32, a balanced search tree of ordered elements.\n///\n/// Performance:\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Space: `O(n)` for storing the entire tree,\n/// where `n` denotes the number of elements stored in the set.\n\n// Data structure implementation is courtesy of Byron Becker.\n// Source: https://github.com/canscale/StableHeapBTreeMap\n// Copyright (c) 2022 Byron Becker.\n// Distributed under Apache 2.0 license.\n// With adjustments by the Motoko team.\n\nimport PureSet \"pure/Set\";\nimport Types \"Types\";\nimport Order \"Order\";\nimport Array \"Array\";\nimport VarArray \"VarArray\";\nimport Runtime \"Runtime\";\nimport Stack \"Stack\";\nimport Option \"Option\";\nimport Iter \"Iter\";\nimport BTreeHelper \"internal/BTreeHelper\";\n\nmodule {\n let btreeOrder = 32; // Should be >= 4 and <= 512.\n\n public type Set<T> = Types.Set.Set<T>;\n type Node<T> = Types.Set.Node<T>;\n type Data<T> = Types.Set.Data<T>;\n type Internal<T> = Types.Set.Internal<T>;\n type Leaf<T> = Types.Set.Leaf<T>;\n\n /// Convert the mutable set to an immutable, purely functional set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import PureSet \"mo:core/pure/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter<Nat>([0, 2, 1].values(), Nat.compare);\n /// let pureSet = Set.toPure(set, Nat.compare);\n /// assert Iter.toArray(PureSet.values(pureSet)) == Iter.toArray(Set.values(set));\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func toPure<T>(set : Set<T>, compare : (T, T) -> Order.Order) : PureSet.Set<T> {\n PureSet.fromIter(values(set), compare)\n };\n\n /// Convert an immutable, purely functional set to a mutable set.\n ///\n /// Example:\n /// ```motoko\n /// import PureSet \"mo:core/pure/Set\";\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let pureSet = PureSet.fromIter([3, 1, 2].values(), Nat.compare);\n /// let set = Set.fromPure(pureSet, Nat.compare);\n /// assert Iter.toArray(Set.values(set)) == Iter.toArray(PureSet.values(pureSet));\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func fromPure<T>(set : PureSet.Set<T>, compare : (T, T) -> Order.Order) : Set<T> {\n fromIter(PureSet.values(set), compare)\n };\n\n /// Create a copy of the mutable set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let originalSet = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let clonedSet = Set.clone(originalSet);\n /// Set.add(originalSet, Nat.compare, 4);\n /// assert Set.size(clonedSet) == 3;\n /// assert Set.size(originalSet) == 4;\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of elements stored in the set.\n public func clone<T>(set : Set<T>) : Set<T> {\n {\n var root = cloneNode(set.root);\n var size = set.size\n }\n };\n\n /// Create a new empty mutable set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// assert Set.size(set) == 0;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func empty<T>() : Set<T> {\n {\n var root = #leaf({\n data = {\n elements = VarArray.repeat<?T>(null, btreeOrder - 1);\n var count = 0\n }\n });\n var size = 0\n }\n };\n\n /// Create a new mutable set with a single element.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n ///\n /// persistent actor {\n /// let cities = Set.singleton<Text>(\"Zurich\");\n /// assert Set.size(cities) == 1;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func singleton<T>(element : T) : Set<T> {\n let elements = VarArray.repeat<?T>(null, btreeOrder - 1);\n elements[0] := ?element;\n {\n var root =\n #leaf({ data = { elements; var count = 1 } });\n var size = 1\n }\n };\n\n /// Remove all the elements from the set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Text \"mo:core/Text\";\n ///\n /// persistent actor {\n /// let cities = Set.empty<Text>();\n /// Set.add(cities, Text.compare, \"Zurich\");\n /// Set.add(cities, Text.compare, \"San Francisco\");\n /// Set.add(cities, Text.compare, \"London\");\n /// assert Set.size(cities) == 3;\n ///\n /// Set.clear(cities);\n /// assert Set.size(cities) == 0;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func clear<T>(set : Set<T>) {\n let emptySet = empty<T>();\n set.root := emptySet.root;\n set.size := 0\n };\n\n /// Determines whether a set is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// Set.add(set, Nat.compare, 1);\n /// Set.add(set, Nat.compare, 2);\n /// Set.add(set, Nat.compare, 3);\n ///\n /// assert not Set.isEmpty(set);\n /// Set.clear(set);\n /// assert Set.isEmpty(set);\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func isEmpty<T>(set : Set<T>) : Bool {\n set.size == 0\n };\n\n /// Return the number of elements in a set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// Set.add(set, Nat.compare, 1);\n /// Set.add(set, Nat.compare, 2);\n /// Set.add(set, Nat.compare, 3);\n ///\n /// assert Set.size(set) == 3;\n /// }\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func size<T>(set : Set<T>) : Nat {\n set.size\n };\n\n /// Test whether two imperative sets are equal.\n /// Both sets have to be constructed by the same comparison function.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2].values(), Nat.compare);\n /// let set2 = Set.fromIter([2, 1].values(), Nat.compare);\n /// let set3 = Set.fromIter([2, 1, 0].values(), Nat.compare);\n /// assert Set.equal(set1, set2, Nat.compare);\n /// assert not Set.equal(set1, set3, Nat.compare);\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n public func equal<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Types.Order) : Bool {\n if (set1.size != set2.size) return false;\n // TODO: optimize\n let iterator1 = values(set1);\n let iterator2 = values(set2);\n loop {\n let next1 = iterator1.next();\n let next2 = iterator2.next();\n switch (next1, next2) {\n case (null, null) {\n return true\n };\n case (?element1, ?element2) {\n if (not (compare(element1, element2) == #equal)) {\n return false\n }\n };\n case _ { return false }\n }\n }\n };\n\n /// Tests whether the set contains the provided element.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// Set.add(set, Nat.compare, 1);\n /// Set.add(set, Nat.compare, 2);\n /// Set.add(set, Nat.compare, 3);\n ///\n /// assert Set.contains(set, Nat.compare, 1);\n /// assert not Set.contains(set, Nat.compare, 4);\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func contains<T>(set : Set<T>, compare : (T, T) -> Order.Order, element : T) : Bool {\n switch (set.root) {\n case (#internal(internalNode)) {\n containsInInternal(internalNode, compare, element)\n };\n case (#leaf(leafNode)) { containsInLeaf(leafNode, compare, element) }\n }\n };\n\n /// Add a new element to a set.\n /// No effect if the element already exists in the set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// Set.add(set, Nat.compare, 2);\n /// Set.add(set, Nat.compare, 1);\n /// Set.add(set, Nat.compare, 2);\n /// assert Iter.toArray(Set.values(set)) == [1, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func add<T>(set : Set<T>, compare : (T, T) -> Order.Order, element : T) {\n ignore insert(set, compare, element)\n };\n\n /// Insert a new element in the set.\n /// Returns true if the element is new, false if the element was already contained in the set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// assert Set.insert(set, Nat.compare, 2);\n /// assert Set.insert(set, Nat.compare, 1);\n /// assert not Set.insert(set, Nat.compare, 2);\n /// assert Iter.toArray(Set.values(set)) == [1, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func insert<T>(set : Set<T>, compare : (T, T) -> Order.Order, element : T) : Bool {\n let insertResult = switch (set.root) {\n case (#leaf(leafNode)) {\n leafInsertHelper<T>(leafNode, btreeOrder, compare, element)\n };\n case (#internal(internalNode)) {\n internalInsertHelper<T>(internalNode, btreeOrder, compare, element)\n }\n };\n\n switch (insertResult) {\n case (#inserted) {\n // if inserted an element that was not previously there, increment the tree size counter\n set.size += 1;\n true\n };\n case (#existent) {\n // keep size\n false\n };\n case (#promote({ element = promotedElement; leftChild; rightChild })) {\n let elements = VarArray.repeat<?T>(null, btreeOrder - 1);\n elements[0] := ?promotedElement;\n let children = VarArray.repeat<?Node<T>>(null, btreeOrder);\n children[0] := ?leftChild;\n children[1] := ?rightChild;\n set.root := #internal({\n data = { elements; var count = 1 };\n children\n });\n // promotion always comes from inserting a new element, so increment the tree size counter\n set.size += 1;\n true\n }\n }\n };\n\n /// Deletes an element from a set.\n /// No effect if the element is not contained in the set.\n ///\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([1, 2, 3].values(), Nat.compare);\n ///\n /// Set.remove(set, Nat.compare, 2);\n /// assert not Set.contains(set, Nat.compare, 2);\n ///\n /// Set.remove(set, Nat.compare, 4);\n /// assert not Set.contains(set, Nat.compare, 4);\n ///\n /// assert Iter.toArray(Set.values(set)) == [1, 3];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` including garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` objects that will be collected as garbage.\n public func remove<T>(set : Set<T>, compare : (T, T) -> Order.Order, element : T) : () {\n ignore delete(set, compare, element)\n };\n\n /// Deletes an element from a set.\n /// Returns true if the element was contained in the set, false if not.\n ///\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([1, 2, 3].values(), Nat.compare);\n ///\n /// assert Set.delete(set, Nat.compare, 2);\n /// assert not Set.contains(set, Nat.compare, 2);\n ///\n /// assert not Set.delete(set, Nat.compare, 4);\n /// assert not Set.contains(set, Nat.compare, 4);\n /// assert Iter.toArray(Set.values(set)) == [1, 3];\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` including garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` objects that will be collected as garbage.\n public func delete<T>(set : Set<T>, compare : (T, T) -> Order.Order, element : T) : Bool {\n let deleted = switch (set.root) {\n case (#leaf(leafNode)) {\n // TODO: think about how this can be optimized so don't have to do two steps (search and then insert)?\n switch (NodeUtil.getElementIndex<T>(leafNode.data, compare, element)) {\n case (#elementFound(deleteIndex)) {\n leafNode.data.count -= 1;\n ignore BTreeHelper.deleteAndShift<T>(leafNode.data.elements, deleteIndex);\n set.size -= 1;\n true\n };\n case _ { false }\n }\n };\n case (#internal(internalNode)) {\n let deletedElement = switch (internalDeleteHelper(internalNode, btreeOrder, compare, element, false)) {\n case (#deleted) { true };\n case (#inexistent) { false };\n case (#mergeChild({ internalChild })) {\n if (internalChild.data.count > 0) {\n set.root := #internal(internalChild)\n }\n // This case will be hit if the BTree has order == 4\n // In this case, the internalChild has no element (last element was merged with new child), so need to promote that merged child (its only child)\n else {\n set.root := switch (internalChild.children[0]) {\n case (?node) { node };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.delete(), element deletion failed, due to a null replacement node error\")\n }\n }\n };\n true\n }\n };\n if (deletedElement) {\n // if deleted an element from the BTree, decrement the size\n set.size -= 1\n };\n deletedElement\n }\n };\n deleted\n };\n\n /// Retrieves the maximum element from the set.\n /// If the set is empty, returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// assert Set.max(set) == null;\n /// Set.add(set, Nat.compare, 3);\n /// Set.add(set, Nat.compare, 1);\n /// Set.add(set, Nat.compare, 2);\n /// assert Set.max(set) == ?3;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements stored in the set.\n public func max<T>(set : Set<T>) : ?T {\n reverseValues(set).next()\n };\n\n /// Retrieves the minimum element from the set.\n /// If the set is empty, returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.empty<Nat>();\n /// assert Set.min(set) == null;\n /// Set.add(set, Nat.compare, 1);\n /// Set.add(set, Nat.compare, 2);\n /// Set.add(set, Nat.compare, 3);\n /// assert Set.min(set) == ?1;\n /// }\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements stored in the set.\n public func min<T>(set : Set<T>) : ?T {\n values(set).next()\n };\n\n /// Returns an iterator over the elements in the set,\n /// traversing the elements in the ascending order.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 2, 3, 1].values(), Nat.compare);\n ///\n /// var tmp = \"\";\n /// for (number in Set.values(set)) {\n /// tmp #= \" \" # Nat.toText(number);\n /// };\n /// assert tmp == \" 0 1 2 3\";\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func values<T>(set : Set<T>) : Types.Iter<T> {\n switch (set.root) {\n case (#leaf(leafNode)) { return leafElements(leafNode) };\n case (#internal(internalNode)) { internalElements(internalNode) }\n }\n };\n\n /// Returns an iterator over the elements in the set,\n /// starting from a given element in ascending order.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 3, 1].values(), Nat.compare);\n /// assert Iter.toArray(Set.valuesFrom(set, Nat.compare, 1)) == [1, 3];\n /// assert Iter.toArray(Set.valuesFrom(set, Nat.compare, 2)) == [3];\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func valuesFrom<T>(\n set : Set<T>,\n compare : (T, T) -> Order.Order,\n element : T\n ) : Types.Iter<T> {\n switch (set.root) {\n case (#leaf(leafNode)) leafElementsFrom(leafNode, compare, element);\n case (#internal(internalNode)) internalElementsFrom(internalNode, compare, element)\n }\n };\n\n /// Returns an iterator over the elements in the set,\n /// traversing the elements in the descending order.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 2, 3, 1].values(), Nat.compare);\n ///\n /// var tmp = \"\";\n /// for (number in Set.reverseValues(set)) {\n /// tmp #= \" \" # Nat.toText(number);\n /// };\n /// assert tmp == \" 3 2 1 0\";\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func reverseValues<T>(set : Set<T>) : Types.Iter<T> {\n switch (set.root) {\n case (#leaf(leafNode)) { return reverseLeafElements(leafNode) };\n case (#internal(internalNode)) { reverseInternalElements(internalNode) }\n }\n };\n\n /// Returns an iterator over the elements in the set,\n /// starting from a given element in descending order.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 1, 3].values(), Nat.compare);\n /// assert Iter.toArray(Set.reverseValuesFrom(set, Nat.compare, 0)) == [0];\n /// assert Iter.toArray(Set.reverseValuesFrom(set, Nat.compare, 2)) == [1, 0];\n /// }\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func reverseValuesFrom<T>(\n set : Set<T>,\n compare : (T, T) -> Order.Order,\n element : T\n ) : Types.Iter<T> {\n switch (set.root) {\n case (#leaf(leafNode)) reverseLeafElementsFrom(leafNode, compare, element);\n case (#internal(internalNode)) reverseInternalElementsFrom(internalNode, compare, element)\n }\n };\n\n /// Create a mutable set with the elements obtained from an iterator.\n /// Potential duplicate elements in the iterator are ignored, i.e.\n /// multiple occurrence of an equal element only occur once in the set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter<Nat>([3, 1, 2, 1].values(), Nat.compare);\n /// assert Iter.toArray(Set.values(set)) == [1, 2, 3];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of elements returned by the iterator and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func fromIter<T>(iter : Types.Iter<T>, compare : (T, T) -> Order.Order) : Set<T> {\n let set = empty<T>();\n for (element in iter) {\n add(set, compare, element)\n };\n set\n };\n\n /// Test whether `set1` is a sub-set of `set2`, i.e. each element in `set1` is\n /// also contained in `set2`. Returns `true` if both sets are equal.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2].values(), Nat.compare);\n /// let set2 = Set.fromIter([2, 1, 0].values(), Nat.compare);\n /// let set3 = Set.fromIter([3, 4].values(), Nat.compare);\n /// assert Set.isSubset(set1, set2, Nat.compare);\n /// assert not Set.isSubset(set1, set3, Nat.compare);\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func isSubset<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Bool {\n if (set1.size > set2.size) { return false };\n // TODO: optimize\n for (element in values(set1)) {\n if (not contains(set2, compare, element)) {\n return false\n }\n };\n true\n };\n\n /// Returns a new set that is the union of `set1` and `set2`,\n /// i.e. a new set that all the elements that exist in at least on of the two sets.\n /// Potential duplicates are ignored, i.e. if the same element occurs in both `set1`\n /// and `set2`, it only occurs once in the returned set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let set2 = Set.fromIter([3, 4, 5].values(), Nat.compare);\n /// let union = Set.union(set1, set2, Nat.compare);\n /// assert Iter.toArray(Set.values(union)) == [1, 2, 3, 4, 5];\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func union<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Set<T> {\n let result = clone<T>(set1);\n for (element in values(set2)) {\n if (not contains(result, compare, element)) {\n add(result, compare, element)\n }\n };\n result\n };\n\n /// Returns a new set that is the intersection of `set1` and `set2`,\n /// i.e. a new set that contains all the elements that exist in both sets.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([0, 1, 2].values(), Nat.compare);\n /// let set2 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let intersection = Set.intersection(set1, set2, Nat.compare);\n /// assert Iter.toArray(Set.values(intersection)) == [1, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func intersection<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Set<T> {\n let result = empty<T>();\n for (element in values(set1)) {\n if (contains(set2, compare, element)) {\n add(result, compare, element)\n }\n };\n result\n };\n\n /// Returns a new set that is the difference between `set1` and `set2` (`set1` minus `set2`),\n /// i.e. a new set that contains all the elements of `set1` that do not exist in `set2`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let set2 = Set.fromIter([3, 4, 5].values(), Nat.compare);\n /// let difference = Set.difference(set1, set2, Nat.compare);\n /// assert Iter.toArray(Set.values(difference)) == [1, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets `set1` and `set2`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func difference<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Set<T> {\n let result = empty<T>();\n for (element in values(set1)) {\n if (not contains(set2, compare, element)) {\n add(result, compare, element)\n }\n };\n result\n };\n\n /// Adds all elements from `iter` to the specified `set`.\n /// This is equivalent to `Set.union()` but modifies the set in place.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// Set.addAll(set, Nat.compare, [3, 4, 5].values());\n /// assert Iter.toArray(Set.values(set)) == [1, 2, 3, 4, 5];\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements in `set` and `iter`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func addAll<T>(set : Set<T>, compare : (T, T) -> Order.Order, iter : Types.Iter<T>) {\n for (element in iter) {\n add(set, compare, element)\n }\n };\n\n /// Deletes all values in `iter` from the specified `set`.\n /// Returns `true` if any value was present in the set, otherwise false.\n /// The return value indicates whether the size of the set has changed.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 1, 2].values(), Nat.compare);\n /// assert Set.deleteAll(set, Nat.compare, [0, 2].values());\n /// assert Iter.toArray(Set.values(set)) == [1];\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements in `set` and `iter`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func deleteAll<T>(set : Set<T>, compare : (T, T) -> Order.Order, iter : Types.Iter<T>) : Bool {\n var deleted = false;\n for (element in iter) {\n deleted := delete(set, compare, element) or deleted // order matters!\n };\n deleted\n };\n\n /// Inserts all values in `iter` into `set`.\n /// Returns true if any value was not contained in the original set, otherwise false.\n /// The return value indicates whether the size of the set has changed.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 1, 2].values(), Nat.compare);\n /// assert Set.insertAll(set, Nat.compare, [0, 2, 3].values());\n /// assert Iter.toArray(Set.values(set)) == [0, 1, 2, 3];\n /// assert not Set.insertAll(set, Nat.compare, [0, 1, 2].values()); // no change\n /// }\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements in `set` and `iter`, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func insertAll<T>(set : Set<T>, compare : (T, T) -> Order.Order, iter : Types.Iter<T>) : Bool {\n var inserted = false;\n for (element in iter) {\n inserted := insert(set, compare, element) or inserted // order matters!\n };\n inserted\n };\n\n /// Removes all values in `set` that do not satisfy the given predicate.\n /// Returns `true` if and only if the size of the set has changed.\n /// Modifies the set in place.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([3, 1, 2].values(), Nat.compare);\n ///\n /// let sizeChanged = Set.retainAll<Nat>(set, Nat.compare, func n { n % 2 == 0 });\n /// assert Iter.toArray(Set.values(set)) == [2];\n /// assert sizeChanged;\n /// }\n /// ```\n public func retainAll<T>(set : Set<T>, compare : (T, T) -> Order.Order, predicate : T -> Bool) : Bool {\n let array = Array.fromIter<T>(values(set));\n deleteAll(\n set,\n compare,\n Iter.filter<T>(array.vals(), func(element : T) : Bool = not predicate(element))\n )\n };\n\n /// Apply an operation on each element contained in the set.\n /// The operation is applied in ascending order of the elements.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let numbers = Set.fromIter([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// var tmp = \"\";\n /// Set.forEach<Nat>(numbers, func (element) {\n /// tmp #= \" \" # Nat.toText(element)\n /// });\n /// assert tmp == \" 0 1 2 3\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func forEach<T>(set : Set<T>, operation : T -> ()) {\n for (element in values(set)) {\n operation(element)\n }\n };\n\n /// Filter elements in a new set.\n /// Create a copy of the mutable set that only contains the elements\n /// that fulfil the criterion function.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let numbers = Set.fromIter([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// let evenNumbers = Set.filter<Nat>(numbers, Nat.compare, func (number) {\n /// number % 2 == 0\n /// });\n /// assert Iter.toArray(Set.values(evenNumbers)) == [0, 2];\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func filter<T>(set : Set<T>, compare : (T, T) -> Order.Order, criterion : T -> Bool) : Set<T> {\n let result = empty<T>();\n for (element in values(set)) {\n if (criterion(element)) {\n add(result, compare, element)\n }\n };\n result\n };\n\n /// Project all elements of the set in a new set.\n /// Apply a mapping function to each element in the set and\n /// collect the mapped elements in a new mutable set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let numbers = Set.fromIter([3, 1, 2].values(), Nat.compare);\n ///\n /// let textNumbers =\n /// Set.map<Nat, Text>(numbers, Text.compare, Nat.toText);\n /// assert Iter.toArray(Set.values(textNumbers)) == [\"1\", \"2\", \"3\"];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func map<T1, T2>(set : Set<T1>, compare : (T2, T2) -> Order.Order, project : T1 -> T2) : Set<T2> {\n let result = empty<T2>();\n for (element1 in values(set)) {\n let element2 = project(element1);\n add(result, compare, element2)\n };\n result\n };\n\n /// Filter all elements in the set by also applying a projection to the elements.\n /// Apply a mapping function `project` to all elements in the set and collect all\n /// elements, for which the function returns a non-null new element. Collect all\n /// non-discarded new elements in a new mutable set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Text \"mo:core/Text\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let numbers = Set.fromIter([3, 0, 2, 1].values(), Nat.compare);\n ///\n /// let evenTextNumbers = Set.filterMap<Nat, Text>(numbers, Text.compare, func (number) {\n /// if (number % 2 == 0) {\n /// ?Nat.toText(number)\n /// } else {\n /// null // discard odd numbers\n /// }\n /// });\n /// assert Iter.toArray(Set.values(evenTextNumbers)) == [\"0\", \"2\"];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func filterMap<T1, T2>(set : Set<T1>, compare : (T2, T2) -> Order.Order, project : T1 -> ?T2) : Set<T2> {\n let result = empty<T2>();\n for (element1 in values(set)) {\n switch (project(element1)) {\n case null {};\n case (?element2) add(result, compare, element2)\n }\n };\n result\n };\n\n /// Iterate all elements in ascending order,\n /// and accumulate the elements by applying the combine function, starting from a base value.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 3, 2, 1].values(), Nat.compare);\n ///\n /// let text = Set.foldLeft<Nat, Text>(\n /// set,\n /// \"\",\n /// func (accumulator, element) {\n /// accumulator # \" \" # Nat.toText(element)\n /// }\n /// );\n /// assert text == \" 0 1 2 3\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func foldLeft<T, A>(\n set : Set<T>,\n base : A,\n combine : (A, T) -> A\n ) : A {\n var accumulator = base;\n for (element in values(set)) {\n accumulator := combine(accumulator, element)\n };\n accumulator\n };\n\n /// Iterate all elements in descending order,\n /// and accumulate the elements by applying the combine function, starting from a base value.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter([0, 3, 2, 1].values(), Nat.compare);\n ///\n /// let text = Set.foldRight<Nat, Text>(\n /// set,\n /// \"\",\n /// func (element, accumulator) {\n /// accumulator # \" \" # Nat.toText(element)\n /// }\n /// );\n /// assert text == \" 3 2 1 0\";\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func foldRight<T, A>(\n set : Set<T>,\n base : A,\n combine : (T, A) -> A\n ) : A {\n var accumulator = base;\n for (element in reverseValues(set)) {\n accumulator := combine(element, accumulator)\n };\n accumulator\n };\n\n /// Construct the union of a series of sets, i.e. all elements of\n /// each set are included in the result set.\n /// Any duplicates are ignored, i.e. if an element occurs\n /// in several of the iterated sets, it only occurs once in the result set.\n ///\n /// Assumes all sets are ordered by `compare`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let set2 = Set.fromIter([3, 4, 5].values(), Nat.compare);\n /// let set3 = Set.fromIter([5, 6, 7].values(), Nat.compare);\n /// let combined = Set.join([set1, set2, set3].values(), Nat.compare);\n /// assert Iter.toArray(Set.values(combined)) == [1, 2, 3, 4, 5, 6, 7];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the iterated sets,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func join<T>(setIterator : Types.Iter<Set<T>>, compare : (T, T) -> Order.Order) : Set<T> {\n let result = empty<T>();\n for (set in setIterator) {\n for (element in values(set)) {\n add(result, compare, element)\n }\n };\n result\n };\n\n /// Construct the union of a set of element sets, i.e. all elements of\n /// each element set are included in the result set.\n /// Any duplicates are ignored, i.e. if the same element occurs in multiple element sets,\n /// it only occurs once in the result set.\n ///\n /// Assumes all sets are ordered by `compare`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n /// import Order \"mo:core/Order\";\n /// import Iter \"mo:core/Iter\";\n ///\n /// persistent actor {\n /// func setCompare(first: Set.Set<Nat>, second: Set.Set<Nat>) : Order.Order {\n /// Set.compare(first, second, Nat.compare)\n /// };\n ///\n /// let set1 = Set.fromIter([1, 2, 3].values(), Nat.compare);\n /// let set2 = Set.fromIter([3, 4, 5].values(), Nat.compare);\n /// let set3 = Set.fromIter([5, 6, 7].values(), Nat.compare);\n /// let setOfSets = Set.fromIter([set1, set2, set3].values(), setCompare);\n /// let flatSet = Set.flatten(setOfSets, Nat.compare);\n /// assert Iter.toArray(Set.values(flatSet)) == [1, 2, 3, 4, 5, 6, 7];\n /// }\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in all the sub-sets,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func flatten<T>(setOfSets : Set<Set<T>>, compare : (T, T) -> Order.Order) : Set<T> {\n let result = empty<T>();\n for (subSet in values(setOfSets)) {\n for (element in values(subSet)) {\n add(result, compare, element)\n }\n };\n result\n };\n\n /// Check whether all elements in the set satisfy a predicate, i.e.\n /// the `predicate` function returns `true` for all elements in the set.\n /// Returns `true` for an empty set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter<Nat>([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// let belowTen = Set.all<Nat>(set, func (number) {\n /// number < 10\n /// });\n /// assert belowTen;\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func all<T>(set : Set<T>, predicate : T -> Bool) : Bool {\n // TODO optimize, avoiding iterator\n for (element in values(set)) {\n if (not predicate(element)) {\n return false\n }\n };\n true\n };\n\n /// Check whether at least one element in the set satisfies a predicate, i.e.\n /// the `predicate` function returns `true` for at least one element in the set.\n /// Returns `false` for an empty set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter<Nat>([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// let aboveTen = Set.any<Nat>(set, func (number) {\n /// number > 10\n /// });\n /// assert not aboveTen;\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func any<T>(set : Set<T>, predicate : T -> Bool) : Bool {\n // TODO optimize, avoiding iterator\n for (element in values(set)) {\n if (predicate(element)) {\n return true\n }\n };\n false\n };\n\n /// Internal sanity check function.\n /// Can be used to check that elements have been inserted with a consistent comparison function.\n /// Traps if the internal set structure is invalid.\n public func assertValid<T>(set : Set<T>, compare : (T, T) -> Order.Order) {\n func checkIteration(iterator : Types.Iter<T>, order : Order.Order) {\n switch (iterator.next()) {\n case null {};\n case (?first) {\n var previous = first;\n loop {\n switch (iterator.next()) {\n case null return;\n case (?next) {\n if (compare(previous, next) != order) {\n Runtime.trap(\"Invalid order\")\n };\n previous := next\n }\n }\n }\n }\n }\n };\n checkIteration(values(set), #less);\n checkIteration(reverseValues(set), #greater)\n };\n\n /// Generate a textual representation of all the elements in the set.\n /// Primarily to be used for testing and debugging.\n /// The elements are formatted according to `elementFormat`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set = Set.fromIter<Nat>([0, 3, 1, 2].values(), Nat.compare);\n ///\n /// assert Set.toText(set, Nat.toText) == \"Set{0, 1, 2, 3}\"\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(n)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that `elementFormat` has runtime and space costs of `O(1)`.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func toText<T>(set : Set<T>, elementFormat : T -> Text) : Text {\n var text = \"Set{\";\n var sep = \"\";\n for (element in values(set)) {\n text #= sep # elementFormat(element);\n sep := \", \"\n };\n text # \"}\"\n };\n\n /// Compare two sets by comparing the elements.\n /// Both sets must have been created by the same comparison function.\n /// The two sets are iterated by the ascending order of their creation and\n /// order is determined by the following rules:\n /// Less:\n /// `set1` is less than `set2` if:\n /// * the pairwise iteration hits an element pair `element1` and `element2` where\n /// `element1` is less than `element2` and all preceding elements are equal, or,\n /// * `set1` is a strict prefix of `set2`, i.e. `set2` has more elements than `set1`\n /// and all elements of `set1` occur at the beginning of iteration `set2`.\n /// Equal:\n /// `set1` and `set2` have same series of equal elements by pairwise iteration.\n /// Greater:\n /// `set1` is neither less nor equal `set2`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:core/Set\";\n /// import Nat \"mo:core/Nat\";\n ///\n /// persistent actor {\n /// let set1 = Set.fromIter([0, 1].values(), Nat.compare);\n /// let set2 = Set.fromIter([0, 2].values(), Nat.compare);\n ///\n /// assert Set.compare(set1, set2, Nat.compare) == #less;\n /// assert Set.compare(set1, set1, Nat.compare) == #equal;\n /// assert Set.compare(set2, set1, Nat.compare) == #greater;\n /// }\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)` retained memory plus garbage, see below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that `compare` has runtime and space costs of `O(1)`.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func compare<T>(set1 : Set<T>, set2 : Set<T>, compare : (T, T) -> Order.Order) : Order.Order {\n let iterator1 = values(set1);\n let iterator2 = values(set2);\n loop {\n switch (iterator1.next(), iterator2.next()) {\n case (null, null) return #equal;\n case (null, _) return #less;\n case (_, null) return #greater;\n case (?element1, ?element2) {\n let comparison = compare(element1, element2);\n if (comparison != #equal) {\n return comparison\n }\n }\n }\n }\n };\n\n func leafElements<T>({ data } : Leaf<T>) : Types.Iter<T> {\n var i : Nat = 0;\n object {\n public func next() : ?T {\n if (i >= data.count) {\n null\n } else {\n let res = data.elements[i];\n i += 1;\n res\n }\n }\n }\n };\n\n func leafElementsFrom<T>({ data } : Leaf<T>, compare : (T, T) -> Order.Order, element : T) : Types.Iter<T> {\n var i = switch (BinarySearch.binarySearchNode<T>(data.elements, compare, element, data.count)) {\n case (#elementFound(i)) i;\n case (#notFound(i)) i\n };\n object {\n public func next() : ?T {\n if (i >= data.count) {\n null\n } else {\n let res = data.elements[i];\n i += 1;\n res\n }\n }\n }\n };\n\n func reverseLeafElements<T>({ data } : Leaf<T>) : Types.Iter<T> {\n var i : Nat = data.count;\n object {\n public func next() : ?T {\n if (i == 0) {\n null\n } else {\n let res = data.elements[i - 1];\n i -= 1;\n res\n }\n }\n }\n };\n\n func reverseLeafElementsFrom<T>({ data } : Leaf<T>, compare : (T, T) -> Order.Order, element : T) : Types.Iter<T> {\n var i = switch (BinarySearch.binarySearchNode<T>(data.elements, compare, element, data.count)) {\n case (#elementFound(i)) i + 1; // +1 to include this element\n case (#notFound(i)) i // i is the index of the first element greater than the search element, or count if all elements are less than the search element\n };\n object {\n public func next() : ?T {\n if (i == 0) {\n null\n } else {\n let res = data.elements[i - 1];\n i -= 1;\n res\n }\n }\n }\n };\n\n // Cursor type that keeps track of the current node and the current element index in the node\n type NodeCursor<T> = { node : Node<T>; elementIndex : Nat };\n\n func internalElements<T>(internal : Internal<T>) : Types.Iter<T> {\n // The nodeCursorStack keeps track of the current node and the current element index in the node\n // We use a stack here to push to/pop off the next node cursor to visit\n let nodeCursorStack = initializeForwardNodeCursorStack(internal);\n internalElementsFromStack(nodeCursorStack)\n };\n\n func internalElementsFrom<T>(internal : Internal<T>, compare : (T, T) -> Order.Order, element : T) : Types.Iter<T> {\n let nodeCursorStack = initializeForwardNodeCursorStackFrom(internal, compare, element);\n internalElementsFromStack(nodeCursorStack)\n };\n\n func internalElementsFromStack<T>(nodeCursorStack : Stack.Stack<NodeCursor<T>>) : Types.Iter<T> {\n object {\n public func next() : ?T {\n // pop the next node cursor off the stack\n var nodeCursor = Stack.pop(nodeCursorStack);\n switch (nodeCursor) {\n case null { return null };\n case (?{ node; elementIndex }) {\n switch (node) {\n // if a leaf node, iterate through the leaf node's next element\n case (#leaf(leafNode)) {\n let lastIndex = leafNode.data.count - 1 : Nat;\n if (elementIndex > lastIndex) {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.internalElements(), leaf elementIndex out of bounds\")\n };\n\n let currentElement = switch (leafNode.data.elements[elementIndex]) {\n case (?element) { element };\n case null {\n Runtime.trap(\n \"UNREACHABLE_ERROR: file a bug report! In Set.internalElements(), null element found in leaf node.\"\n # \"leafNode.data.count=\" # debug_show (leafNode.data.count) # \", elementIndex=\" # debug_show (elementIndex)\n )\n }\n };\n // if not at the last element, push the next element index of the leaf onto the stack and return the current element\n if (elementIndex < lastIndex) {\n Stack.push(\n nodeCursorStack,\n {\n node = #leaf(leafNode);\n elementIndex = elementIndex + 1 : Nat\n }\n )\n };\n\n ?currentElement\n };\n // if an internal node\n case (#internal(internalNode)) {\n let lastIndex = internalNode.data.count - 1 : Nat;\n // Developer facing message in case of a bug\n if (elementIndex > lastIndex) {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.internalElements(), internal elementIndex out of bounds\")\n };\n\n let currentElement = switch (internalNode.data.elements[elementIndex]) {\n case (?element) { element };\n case null {\n Runtime.trap(\n \"UNREACHABLE_ERROR: file a bug report! In Set.internalElements(), null element found in internal node. \" #\n \"internal.data.count=\" # debug_show (internalNode.data.count) # \", elementIndex=\" # debug_show (elementIndex)\n )\n }\n };\n\n let nextCursor = {\n node = #internal(internalNode);\n elementIndex = elementIndex + 1 : Nat\n };\n // if not the last element, push the next element of the internal node onto the stack\n if (elementIndex < lastIndex) {\n Stack.push(nodeCursorStack, nextCursor)\n };\n // traverse the next child's min subtree and push the resulting node cursors onto the stack\n // then return the current element of the internal node\n traverseMinSubtreeIter(nodeCursorStack, nextCursor);\n ?currentElement\n }\n }\n }\n }\n }\n }\n };\n\n func reverseInternalElements<T>(internal : Internal<T>) : Types.Iter<T> {\n // The nodeCursorStack keeps track of the current node and the current element index in the node\n // We use a stack here to push to/pop off the next node cursor to visit\n let nodeCursorStack = initializeReverseNodeCursorStack(internal);\n reverseInternalElementsFromStack(nodeCursorStack)\n };\n\n func reverseInternalElementsFrom<T>(internal : Internal<T>, compare : (T, T) -> Order.Order, element : T) : Types.Iter<T> {\n let nodeCursorStack = initializeReverseNodeCursorStackFrom(internal, compare, element);\n reverseInternalElementsFromStack(nodeCursorStack)\n };\n\n func reverseInternalElementsFromStack<T>(nodeCursorStack : Stack.Stack<NodeCursor<T>>) : Types.Iter<T> {\n object {\n public func next() : ?T {\n // pop the next node cursor off the stack\n var nodeCursor = Stack.pop(nodeCursorStack);\n switch (nodeCursor) {\n case null { return null };\n case (?{ node; elementIndex }) {\n let firstIndex = 0 : Nat;\n assert (elementIndex > firstIndex);\n switch (node) {\n // if a leaf node, reverse iterate through the leaf node's next element\n case (#leaf(leafNode)) {\n let currentElement = switch (leafNode.data.elements[elementIndex - 1]) {\n case (?element) { element };\n case null {\n Runtime.trap(\n \"UNREACHABLE_ERROR: file a bug report! In Set.reverseInternalElements(), null element found in leaf node.\"\n # \"leafNode.data.count=\" # debug_show (leafNode.data.count) # \", elementIndex=\" # debug_show (elementIndex)\n )\n }\n };\n // if not at the last element, push the previous element index of the leaf onto the stack and return the current element\n if (elementIndex - 1 : Nat > firstIndex) {\n Stack.push(\n nodeCursorStack,\n {\n node = #leaf(leafNode);\n elementIndex = elementIndex - 1 : Nat\n }\n )\n };\n\n // return the current element\n ?currentElement\n };\n // if an internal node\n case (#internal(internalNode)) {\n let currentElement = switch (internalNode.data.elements[elementIndex - 1]) {\n case (?element) { element };\n case null {\n Runtime.trap(\n \"UNREACHABLE_ERROR: file a bug report! In Set.reverseInternalElements(), null element found in internal node. \" #\n \"internal.data.count=\" # debug_show (internalNode.data.count) # \", elementIndex=\" # debug_show (elementIndex)\n )\n }\n };\n\n let previousCursor = {\n node = #internal(internalNode);\n elementIndex = elementIndex - 1 : Nat\n };\n // if not the first element, push the previous element index of the internal node onto the stack\n if (elementIndex - 1 : Nat > firstIndex) {\n Stack.push(nodeCursorStack, previousCursor)\n };\n // traverse the previous child's max subtree and push the resulting node cursors onto the stack\n // then return the current element of the internal node\n traverseMaxSubtreeIter(nodeCursorStack, previousCursor);\n ?currentElement\n }\n }\n }\n }\n }\n }\n };\n\n func initializeForwardNodeCursorStack<T>(internal : Internal<T>) : Stack.Stack<NodeCursor<T>> {\n let nodeCursorStack = Stack.empty<NodeCursor<T>>();\n let nodeCursor : NodeCursor<T> = {\n node = #internal(internal);\n elementIndex = 0\n };\n\n // push the initial cursor to the stack\n Stack.push(nodeCursorStack, nodeCursor);\n // then traverse left\n traverseMinSubtreeIter(nodeCursorStack, nodeCursor);\n nodeCursorStack\n };\n\n func initializeForwardNodeCursorStackFrom<T>(internal : Internal<T>, compare : (T, T) -> Order.Order, element : T) : Stack.Stack<NodeCursor<T>> {\n let nodeCursorStack = Stack.empty<NodeCursor<T>>();\n let nodeCursor : NodeCursor<T> = {\n node = #internal(internal);\n elementIndex = 0\n };\n\n traverseMinSubtreeIterFrom(nodeCursorStack, nodeCursor, compare, element);\n nodeCursorStack\n };\n\n func initializeReverseNodeCursorStack<T>(internal : Internal<T>) : Stack.Stack<NodeCursor<T>> {\n let nodeCursorStack = Stack.empty<NodeCursor<T>>();\n let nodeCursor : NodeCursor<T> = {\n node = #internal(internal);\n elementIndex = internal.data.count\n };\n\n // push the initial cursor to the stack\n Stack.push(nodeCursorStack, nodeCursor);\n // then traverse left\n traverseMaxSubtreeIter(nodeCursorStack, nodeCursor);\n nodeCursorStack\n };\n\n func initializeReverseNodeCursorStackFrom<T>(internal : Internal<T>, compare : (T, T) -> Order.Order, element : T) : Stack.Stack<NodeCursor<T>> {\n let nodeCursorStack = Stack.empty<NodeCursor<T>>();\n let nodeCursor : NodeCursor<T> = {\n node = #internal(internal);\n elementIndex = internal.data.count\n };\n\n traverseMaxSubtreeIterFrom(nodeCursorStack, nodeCursor, compare, element);\n nodeCursorStack\n };\n\n // traverse the min subtree of the current node cursor, passing each new element to the node cursor stack\n func traverseMinSubtreeIter<T>(nodeCursorStack : Stack.Stack<NodeCursor<T>>, nodeCursor : NodeCursor<T>) {\n var currentNode = nodeCursor.node;\n var childIndex = nodeCursor.elementIndex;\n\n label l loop {\n switch (currentNode) {\n // If currentNode is leaf, have hit the minimum element of the subtree and already pushed it's cursor to the stack\n // so can return\n case (#leaf(_)) {\n return\n };\n // If currentNode is internal, add it's left most child to the stack and continue traversing\n case (#internal(internalNode)) {\n switch (internalNode.children[childIndex]) {\n // Push the next min (left most) child node to the stack\n case (?childNode) {\n childIndex := 0;\n currentNode := childNode;\n Stack.push(\n nodeCursorStack,\n {\n node = currentNode;\n elementIndex = childIndex\n }\n )\n };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.traverseMinSubtreeIter(), null child node error\")\n }\n }\n }\n }\n }\n };\n\n func traverseMinSubtreeIterFrom<T>(nodeCursorStack : Stack.Stack<NodeCursor<T>>, nodeCursor : NodeCursor<T>, compare : (T, T) -> Order.Order, element : T) {\n var currentNode = nodeCursor.node;\n\n label l loop {\n let (node, childrenOption) = switch (currentNode) {\n case (#leaf(leafNode)) (leafNode, null);\n case (#internal(internalNode)) (internalNode, ?internalNode.children)\n };\n let (i, isFound) = switch (NodeUtil.getElementIndex<T>(node.data, compare, element)) {\n case (#elementFound(i)) (i, true);\n case (#notFound(i)) (i, false)\n };\n if (i < node.data.count) {\n Stack.push(\n nodeCursorStack,\n {\n node = currentNode;\n elementIndex = i // greater elements to traverse\n }\n )\n };\n if isFound return;\n let ?children = childrenOption else return;\n let ?childNode = children[i] else Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.traverseMinSubtreeIterFrom(), null child node error\");\n currentNode := childNode\n }\n };\n\n // traverse the max subtree of the current node cursor, passing each new element to the node cursor stack\n func traverseMaxSubtreeIter<T>(nodeCursorStack : Stack.Stack<NodeCursor<T>>, nodeCursor : NodeCursor<T>) {\n var currentNode = nodeCursor.node;\n var childIndex = nodeCursor.elementIndex;\n\n label l loop {\n switch (currentNode) {\n // If currentNode is leaf, have hit the maximum element of the subtree and already pushed it's cursor to the stack\n // so can return\n case (#leaf(_)) {\n return\n };\n // If currentNode is internal, add it's right most child to the stack and continue traversing\n case (#internal(internalNode)) {\n assert (childIndex <= internalNode.data.count); // children are one more than data elements\n switch (internalNode.children[childIndex]) {\n // Push the next max (right most) child node to the stack\n case (?childNode) {\n childIndex := switch (childNode) {\n case (#internal(internalNode)) internalNode.data.count;\n case (#leaf(leafNode)) leafNode.data.count\n };\n currentNode := childNode;\n Stack.push(\n nodeCursorStack,\n {\n node = currentNode;\n elementIndex = childIndex\n }\n )\n };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.traverseMaxSubtreeIter(), null child node error\")\n }\n }\n }\n }\n }\n };\n\n func traverseMaxSubtreeIterFrom<T>(nodeCursorStack : Stack.Stack<NodeCursor<T>>, nodeCursor : NodeCursor<T>, compare : (T, T) -> Order.Order, element : T) {\n var currentNode = nodeCursor.node;\n\n label l loop {\n let (node, childrenOption) = switch (currentNode) {\n case (#leaf(leafNode)) (leafNode, null);\n case (#internal(internalNode)) (internalNode, ?internalNode.children)\n };\n let (i, isFound) = switch (NodeUtil.getElementIndex<T>(node.data, compare, element)) {\n case (#elementFound(i)) (i + 1, true); // +1 to include this element\n case (#notFound(i)) (i, false) // i is the index of the first element less than the search element, or 0 if all elements are greater than the search element\n };\n if (i > 0) {\n Stack.push(\n nodeCursorStack,\n {\n node = currentNode;\n elementIndex = i\n }\n )\n };\n if isFound return;\n let ?children = childrenOption else return;\n let ?childNode = children[i] else Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.traverseMaxSubtreeIterFrom(), null child node error\");\n currentNode := childNode\n }\n };\n\n // This type is used to signal to the parent calling context what happened in the level below\n type IntermediateInternalDeleteResult<T> = {\n // element was deleted\n #deleted;\n // element was absent\n #inexistent;\n // deleted an element, but was unable to successfully borrow and rebalance at the previous level without merging children\n // the internalChild is the merged child that needs to be rebalanced at the next level up in the BTree\n #mergeChild : {\n internalChild : Internal<T>\n }\n };\n\n func internalDeleteHelper<T>(internalNode : Internal<T>, order : Nat, compare : (T, T) -> Order.Order, deleteElement : T, skipNode : Bool) : IntermediateInternalDeleteResult<T> {\n let minElements = NodeUtil.minElementsFromOrder(order);\n let elementIndex = NodeUtil.getElementIndex<T>(internalNode.data, compare, deleteElement);\n\n // match on both the result of the node binary search, and if this node level should be skipped even if the element is found (internal element replacement case)\n switch (elementIndex, skipNode) {\n // if element is found in the internal node\n case (#elementFound(deleteIndex), false) {\n if (Option.isNull(internalNode.data.elements[deleteIndex])) {\n Runtime.trap(\"Bug in Set.internalDeleteHelper\")\n };\n // TODO: (optimization) replace with deletion in one step without having to retrieve the max element first\n let replaceElement = NodeUtil.getMaxElement(internalNode.children[deleteIndex]);\n internalNode.data.elements[deleteIndex] := ?replaceElement;\n switch (internalDeleteHelper(internalNode, order, compare, replaceElement, true)) {\n case (#deleted) { #deleted };\n case (#inexistent) { #inexistent };\n case (#mergeChild({ internalChild })) {\n #mergeChild({ internalChild })\n }\n }\n };\n // if element is not found in the internal node OR the element is found, but skipping this node (because deleting the in order precessor i.e. replacement element)\n // in both cases need to descend and traverse to find the element to delete\n case ((#elementFound(_), true) or (#notFound(_), _)) {\n let childIndex = switch (elementIndex) {\n case (#elementFound(replacedSkipElementIndex)) {\n replacedSkipElementIndex\n };\n case (#notFound(childIndex)) { childIndex }\n };\n let child = switch (internalNode.children[childIndex]) {\n case (?c) { c };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.internalDeleteHelper, child index of #elementFound or #notfound is null\")\n }\n };\n switch (child) {\n // if child is internal\n case (#internal(internalChild)) {\n switch (internalDeleteHelper(internalChild, order, compare, deleteElement, false), childIndex == 0) {\n // if element was successfully deleted and no additional tree re-balancing is needed, return #deleted\n case (#deleted, _) { #deleted };\n case (#inexistent, _) { #inexistent };\n // if internalChild needs rebalancing and pulling child is left most\n case (#mergeChild({ internalChild }), true) {\n // try to pull left-most element and child from right sibling\n switch (NodeUtil.borrowFromInternalSibling(internalNode.children, childIndex + 1, #successor)) {\n // if can pull up sibling element and child\n case (#borrowed({ deletedSiblingElement; child })) {\n NodeUtil.rotateBorrowedElementsAndChildFromSibling(\n internalNode,\n childIndex,\n deletedSiblingElement,\n child,\n internalChild,\n #right\n );\n #deleted\n };\n // unable to pull from sibling, need to merge with right sibling and push down parent\n case (#notEnoughElements(sibling)) {\n // get the parent element that will be pushed down the the child\n let elementsToBePushedToChild = ?BTreeHelper.deleteAndShift(internalNode.data.elements, 0);\n internalNode.data.count -= 1;\n // merge the children and push down the parent\n let newChild = NodeUtil.mergeChildrenAndPushDownParent<T>(internalChild, elementsToBePushedToChild, sibling);\n // update children of the parent\n internalNode.children[0] := ?#internal(newChild);\n ignore ?BTreeHelper.deleteAndShift(internalNode.children, 1);\n\n if (internalNode.data.count < minElements) {\n #mergeChild({ internalChild = internalNode })\n } else {\n #deleted\n }\n }\n }\n };\n // if internalChild needs rebalancing and pulling child is > 0, so a left sibling exists\n case (#mergeChild({ internalChild }), false) {\n // try to pull right-most element and its child directly from left sibling\n switch (NodeUtil.borrowFromInternalSibling(internalNode.children, childIndex - 1 : Nat, #predecessor)) {\n case (#borrowed({ deletedSiblingElement; child })) {\n NodeUtil.rotateBorrowedElementsAndChildFromSibling(\n internalNode,\n childIndex - 1 : Nat,\n deletedSiblingElement,\n child,\n internalChild,\n #left\n );\n #deleted\n };\n // unable to pull from left sibling\n case (#notEnoughElements(leftSibling)) {\n // if child is not last index, try to pull from the right child\n if (childIndex < internalNode.data.count) {\n switch (NodeUtil.borrowFromInternalSibling(internalNode.children, childIndex, #successor)) {\n // if can pull up sibling element and child\n case (#borrowed({ deletedSiblingElement; child })) {\n NodeUtil.rotateBorrowedElementsAndChildFromSibling(\n internalNode,\n childIndex,\n deletedSiblingElement,\n child,\n internalChild,\n #right\n );\n return #deleted\n };\n // if cannot borrow, from left or right, merge (see below)\n case _ {}\n }\n };\n\n // get the parent element that will be pushed down the the child\n let elementToBePushedToChild = ?BTreeHelper.deleteAndShift(internalNode.data.elements, childIndex - 1 : Nat);\n internalNode.data.count -= 1;\n // merge it the children and push down the parent\n let newChild = NodeUtil.mergeChildrenAndPushDownParent(leftSibling, elementToBePushedToChild, internalChild);\n\n // update children of the parent\n internalNode.children[childIndex - 1] := ?#internal(newChild);\n ignore ?BTreeHelper.deleteAndShift(internalNode.children, childIndex);\n\n if (internalNode.data.count < minElements) {\n #mergeChild({ internalChild = internalNode })\n } else {\n #deleted\n }\n }\n }\n }\n }\n };\n // if child is leaf\n case (#leaf(leafChild)) {\n switch (leafDeleteHelper(leafChild, order, compare, deleteElement), childIndex == 0) {\n case (#deleted, _) { #deleted };\n case (#inexistent, _) { #inexistent };\n // if delete child is left most, try to borrow from right child\n case (#mergeLeafData({ leafDeleteIndex }), true) {\n switch (NodeUtil.borrowFromRightLeafChild(internalNode.children, childIndex)) {\n case (?borrowedElement) {\n let elementToBePushedToChild = internalNode.data.elements[childIndex];\n internalNode.data.elements[childIndex] := ?borrowedElement;\n\n ignore BTreeHelper.insertAtPostionAndDeleteAtPosition<T>(leafChild.data.elements, elementToBePushedToChild, leafChild.data.count - 1, leafDeleteIndex);\n #deleted\n };\n\n case null {\n // can't borrow from right child, delete from leaf and merge with right child and parent element, then push down into new leaf\n let rightChild = switch (internalNode.children[childIndex + 1]) {\n case (?#leaf(rc)) { rc };\n case _ {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.internalDeleteHelper, if trying to borrow from right leaf child is null, rightChild index cannot be null or internal\")\n }\n };\n let mergedLeaf = mergeParentWithLeftRightChildLeafNodesAndDelete(\n internalNode.data.elements[childIndex],\n leafChild,\n rightChild,\n leafDeleteIndex,\n #left\n );\n // delete the left most internal node element, since was merging from a deletion in left most child (0) and the parent element was pushed into the mergedLeaf\n ignore BTreeHelper.deleteAndShift<T>(internalNode.data.elements, 0);\n // update internal node children\n BTreeHelper.replaceTwoWithElementAndShift<Node<T>>(internalNode.children, #leaf(mergedLeaf), 0);\n internalNode.data.count -= 1;\n\n if (internalNode.data.count < minElements) {\n #mergeChild({\n internalChild = internalNode\n })\n } else {\n #deleted\n }\n\n }\n }\n };\n // if delete child is middle or right most, try to borrow from left child\n case (#mergeLeafData({ leafDeleteIndex }), false) {\n // if delete child is right most, try to borrow from left child\n switch (NodeUtil.borrowFromLeftLeafChild(internalNode.children, childIndex)) {\n case (?borrowedElement) {\n let elementToBePushedToChild = internalNode.data.elements[childIndex - 1];\n internalNode.data.elements[childIndex - 1] := ?borrowedElement;\n ignore BTreeHelper.insertAtPostionAndDeleteAtPosition<T>(leafChild.data.elements, elementToBePushedToChild, 0, leafDeleteIndex);\n #deleted\n };\n case null {\n // if delete child is in the middle, try to borrow from right child\n if (childIndex < internalNode.data.count) {\n // try to borrow from right\n switch (NodeUtil.borrowFromRightLeafChild(internalNode.children, childIndex)) {\n case (?borrowedElement) {\n let elementToBePushedToChild = internalNode.data.elements[childIndex];\n internalNode.data.elements[childIndex] := ?borrowedElement;\n // insert the successor at the very last element\n ignore BTreeHelper.insertAtPostionAndDeleteAtPosition<T>(leafChild.data.elements, elementToBePushedToChild, leafChild.data.count - 1, leafDeleteIndex);\n return #deleted\n };\n // if cannot borrow, from left or right, merge (see below)\n case _ {}\n }\n };\n\n // can't borrow from left child, delete from leaf and merge with left child and parent element, then push down into new leaf\n let leftChild = switch (internalNode.children[childIndex - 1]) {\n case (?#leaf(lc)) { lc };\n case _ {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.internalDeleteHelper, if trying to borrow from left leaf child is null, then left child index must not be null or internal\")\n }\n };\n let mergedLeaf = mergeParentWithLeftRightChildLeafNodesAndDelete(\n internalNode.data.elements[childIndex - 1],\n leftChild,\n leafChild,\n leafDeleteIndex,\n #right\n );\n // delete the right most internal node element, since was merging from a deletion in the right most child and the parent element was pushed into the mergedLeaf\n ignore BTreeHelper.deleteAndShift<T>(internalNode.data.elements, childIndex - 1);\n // update internal node children\n BTreeHelper.replaceTwoWithElementAndShift<Node<T>>(internalNode.children, #leaf(mergedLeaf), childIndex - 1);\n internalNode.data.count -= 1;\n\n if (internalNode.data.count < minElements) {\n #mergeChild({\n internalChild = internalNode\n })\n } else {\n #deleted\n }\n }\n }\n }\n }\n }\n }\n }\n }\n };\n\n // This type is used to signal to the parent calling context what happened in the level below\n type IntermediateLeafDeleteResult<T> = {\n // element was deleted\n #deleted;\n // element was absent\n #inexistent;\n // leaf had the minimum number of elements when deleting, so returns the leaf node's data and the index of the element that will be deleted\n #mergeLeafData : {\n data : Data<T>;\n leafDeleteIndex : Nat\n }\n };\n\n func leafDeleteHelper<T>(leafNode : Leaf<T>, order : Nat, compare : (T, T) -> Order.Order, deleteElement : T) : IntermediateLeafDeleteResult<T> {\n let minElements = NodeUtil.minElementsFromOrder(order);\n\n switch (NodeUtil.getElementIndex<T>(leafNode.data, compare, deleteElement)) {\n case (#elementFound(deleteIndex)) {\n if (leafNode.data.count > minElements) {\n leafNode.data.count -= 1;\n ignore BTreeHelper.deleteAndShift<T>(leafNode.data.elements, deleteIndex);\n #deleted\n } else {\n #mergeLeafData({\n data = leafNode.data;\n leafDeleteIndex = deleteIndex\n })\n }\n };\n case (#notFound(_)) {\n #inexistent\n }\n }\n };\n\n func containsInInternal<T>(internalNode : Internal<T>, compare : (T, T) -> Order.Order, element : T) : Bool {\n switch (NodeUtil.getElementIndex<T>(internalNode.data, compare, element)) {\n case (#elementFound _index) {\n true\n };\n case (#notFound(index)) {\n switch (internalNode.children[index]) {\n // expects the child to be there, otherwise there's a bug in binary search or the tree is invalid\n case null { Runtime.trap(\"Internal bug: Set.containsInInternal\") };\n case (?#leaf(leafNode)) { containsInLeaf(leafNode, compare, element) };\n case (?#internal(internalNode)) {\n containsInInternal(internalNode, compare, element)\n }\n }\n }\n }\n };\n\n func containsInLeaf<T>(leafNode : Leaf<T>, compare : (T, T) -> Order.Order, element : T) : Bool {\n switch (NodeUtil.getElementIndex<T>(leafNode.data, compare, element)) {\n case (#elementFound(_index)) {\n true\n };\n case _ false\n }\n };\n\n type DeletionSide = { #left; #right };\n\n func mergeParentWithLeftRightChildLeafNodesAndDelete<T>(\n parentElement : ?T,\n leftChild : Leaf<T>,\n rightChild : Leaf<T>,\n deleteIndex : Nat,\n deletionSide : DeletionSide\n ) : Leaf<T> {\n let count = leftChild.data.count * 2;\n let (elements, _) = BTreeHelper.mergeParentWithChildrenAndDelete<T>(\n parentElement,\n leftChild.data.count,\n leftChild.data.elements,\n rightChild.data.elements,\n deleteIndex,\n deletionSide\n );\n ({\n data = {\n elements;\n var count = count\n }\n })\n };\n\n // This type is used to signal to the parent calling context what happened in the level below\n type IntermediateInsertResult<T> = {\n // element was inserted\n #inserted;\n // element was alreay present\n #existent;\n // child was full when inserting, so returns the promoted element and the split left and right child\n #promote : {\n element : T;\n leftChild : Node<T>;\n rightChild : Node<T>\n }\n };\n\n // Helper for inserting into a leaf node\n func leafInsertHelper<T>(leafNode : Leaf<T>, order : Nat, compare : (T, T) -> Order.Order, insertedElement : T) : (IntermediateInsertResult<T>) {\n // Perform binary search to see if the element exists in the node\n switch (NodeUtil.getElementIndex<T>(leafNode.data, compare, insertedElement)) {\n case (#elementFound(insertIndex)) {\n let previous = leafNode.data.elements[insertIndex];\n leafNode.data.elements[insertIndex] := ?insertedElement;\n switch (previous) {\n case (?_) { #existent };\n case null { Runtime.trap(\"Bug in Set.leafInsertHelper\") }; // the binary search already found an element, so this case should never happen\n }\n };\n case (#notFound(insertIndex)) {\n // Note: BTree will always have an order >= 4, so this will never have negative Nat overflow\n let maxElements : Nat = order - 1;\n // If the leaf is full, insert, split the node, and promote the middle element\n if (leafNode.data.count >= maxElements) {\n let (leftElements, promotedParentElement, rightElements) = BTreeHelper.insertOneAtIndexAndSplitArray(\n leafNode.data.elements,\n insertedElement,\n insertIndex\n );\n\n let leftCount = order / 2;\n let rightCount : Nat = if (order % 2 == 0) { leftCount - 1 } else {\n leftCount\n };\n\n (\n #promote({\n element = promotedParentElement;\n leftChild = createLeaf<T>(leftElements, leftCount);\n rightChild = createLeaf<T>(rightElements, rightCount)\n })\n )\n }\n // Otherwise, insert at the specified index (shifting elements over if necessary)\n else {\n NodeUtil.insertAtIndexOfNonFullNodeData<T>(leafNode.data, ?insertedElement, insertIndex);\n #inserted\n }\n }\n }\n };\n\n // Helper for inserting into an internal node\n func internalInsertHelper<T>(internalNode : Internal<T>, order : Nat, compare : (T, T) -> Order.Order, insertElement : T) : IntermediateInsertResult<T> {\n switch (NodeUtil.getElementIndex<T>(internalNode.data, compare, insertElement)) {\n case (#elementFound(insertIndex)) {\n let previous = internalNode.data.elements[insertIndex];\n internalNode.data.elements[insertIndex] := ?insertElement;\n switch (previous) {\n case (?_) { #existent };\n case null {\n Runtime.trap(\"Bug in Set.internalInsertHelper, element found\")\n }; // the binary search already found an element, so this case should never happen\n }\n };\n case (#notFound(insertIndex)) {\n let insertResult = switch (internalNode.children[insertIndex]) {\n case null {\n Runtime.trap(\"Bug in Set.internalInsertHelper, not found\")\n };\n case (?#leaf(leafNode)) {\n leafInsertHelper(leafNode, order, compare, insertElement)\n };\n case (?#internal(internalChildNode)) {\n internalInsertHelper(internalChildNode, order, compare, insertElement)\n }\n };\n\n switch (insertResult) {\n case (#inserted) #inserted;\n case (#existent) #existent;\n case (#promote({ element = promotedElement; leftChild; rightChild })) {\n // Note: BTree will always have an order >= 4, so this will never have negative Nat overflow\n let maxElements : Nat = order - 1;\n // if current internal node is full, need to split the internal node\n if (internalNode.data.count >= maxElements) {\n // insert and split internal elements, determine new promotion target element\n let (leftElements, promotedParentElement, rightElements) = BTreeHelper.insertOneAtIndexAndSplitArray(\n internalNode.data.elements,\n promotedElement,\n insertIndex\n );\n\n // calculate the element count in the left elements and the element count in the right elements\n let leftCount = order / 2;\n let rightCount : Nat = if (order % 2 == 0) { leftCount - 1 } else {\n leftCount\n };\n\n // split internal children\n let (leftChildren, rightChildren) = NodeUtil.splitChildrenInTwoWithRebalances<T>(\n internalNode.children,\n insertIndex,\n leftChild,\n rightChild\n );\n\n // send the element to be promoted, as well as the internal children left and right split\n #promote({\n element = promotedParentElement;\n leftChild = #internal({\n data = { elements = leftElements; var count = leftCount };\n children = leftChildren\n });\n rightChild = #internal({\n data = { elements = rightElements; var count = rightCount };\n children = rightChildren\n })\n })\n } else {\n // insert the new elements into the internal node\n NodeUtil.insertAtIndexOfNonFullNodeData(internalNode.data, ?promotedElement, insertIndex);\n // split and re-insert the single child that needs rebalancing\n NodeUtil.insertRebalancedChild(internalNode.children, insertIndex, leftChild, rightChild);\n #inserted\n }\n }\n }\n }\n }\n };\n\n func createLeaf<T>(elements : [var ?T], count : Nat) : Node<T> {\n #leaf({\n data = {\n elements;\n var count\n }\n })\n };\n\n // FIXME\n // Additional functionality compared to original source.\n\n func cloneData<T>(data : Data<T>) : Data<T> {\n {\n elements = VarArray.clone(data.elements);\n var count = data.count\n }\n };\n\n func cloneNode<T>(node : Node<T>) : Node<T> {\n switch node {\n case (#leaf { data }) {\n #leaf { data = cloneData(data) }\n };\n case (#internal { data; children }) {\n let clonedData = cloneData(data);\n let clonedChildren = VarArray.map<?Node<T>, ?Node<T>>(\n children,\n func child {\n switch child {\n case null null;\n case (?childNode) ?cloneNode(childNode)\n }\n }\n );\n #internal({\n data = clonedData;\n children = clonedChildren\n })\n }\n }\n };\n\n module BinarySearch {\n public type SearchResult = {\n #elementFound : Nat;\n #notFound : Nat\n };\n\n /// Searches an array for a specific element, returning the index it occurs at if #elementFound, or the child/insert index it may occur at\n /// if #notFound. This is used when determining if a element exists in an internal or leaf node, where an element should be inserted in a\n /// leaf node, or which child of an internal node a element could be in.\n ///\n /// Note: This function expects a mutable, nullable, array of elements in sorted order, where all nulls appear at the end of the array.\n /// This function may trap if a null element appears before any elements. It also expects a maxIndex, which is the right-most index (bound)\n /// from which to begin the binary search (the left most bound is expected to be 0)\n ///\n /// Parameters:\n ///\n /// * array - the sorted array that the binary search is performed upon\n /// * compare - the comparator used to perform the search\n /// * searchElement - the element being compared against in the search\n /// * maxIndex - the right-most index (bound) from which to begin the search\n public func binarySearchNode<T>(array : [var ?T], compare : (T, T) -> Order.Order, searchElement : T, maxIndex : Nat) : SearchResult {\n // TODO: get rid of this check?\n // Trap if array is size 0 (should not happen)\n if (array.size() == 0) {\n assert false\n };\n\n // if all elements in the array are null (i.e. first element is null), return #notFound(0)\n if (maxIndex == 0) {\n return #notFound(0)\n };\n\n // Initialize search from first to last index\n var left : Nat = 0;\n var right = maxIndex; // maxIndex does not necessarily mean array.size() - 1\n // Search the array\n while (left < right) {\n let middle = (left + right) / 2;\n switch (array[middle]) {\n case null { assert false };\n case (?element) {\n switch (compare(searchElement, element)) {\n // If the element is present at the middle itself\n case (#equal) { return #elementFound(middle) };\n // If element is greater than mid, it can only be present in left subarray\n case (#greater) { left := middle + 1 };\n // If element is smaller than mid, it can only be present in right subarray\n case (#less) {\n right := if (middle == 0) { 0 } else { middle - 1 }\n }\n }\n }\n }\n };\n\n if (left == array.size()) {\n return #notFound(left)\n };\n\n // left == right\n switch (array[left]) {\n // inserting at end of array\n case null { #notFound(left) };\n case (?element) {\n switch (compare(searchElement, element)) {\n // if left is the searched element\n case (#equal) { #elementFound(left) };\n // if the element is not found, return notFound and the insert location\n case (#greater) { #notFound(left + 1) };\n case (#less) { #notFound(left) }\n }\n }\n }\n }\n };\n\n module NodeUtil {\n /// Inserts element at the given index into a non-full leaf node\n public func insertAtIndexOfNonFullNodeData<T>(data : Data<T>, element : ?T, insertIndex : Nat) {\n let currentLastElementIndex : Nat = if (data.count == 0) { 0 } else {\n data.count - 1\n };\n BTreeHelper.insertAtPosition<T>(data.elements, element, insertIndex, currentLastElementIndex);\n\n // increment the count of data in this node since just inserted an element\n data.count += 1\n };\n\n /// Inserts two rebalanced (split) child halves into a non-full array of children.\n public func insertRebalancedChild<T>(children : [var ?Node<T>], rebalancedChildIndex : Nat, leftChildInsert : Node<T>, rightChildInsert : Node<T>) {\n // Note: BTree will always have an order >= 4, so this will never have negative Nat overflow\n var j : Nat = children.size() - 2;\n\n // This is just a sanity check to ensure the children aren't already full (should split promote otherwise)\n // TODO: Remove this check once confident\n if (Option.isSome(children[j + 1])) { assert false };\n\n // Iterate backwards over the array and shift each element over to the right by one until the rebalancedChildIndex is hit\n while (j > rebalancedChildIndex) {\n children[j + 1] := children[j];\n j -= 1\n };\n\n // Insert both the left and right rebalanced children (replacing the pre-split child)\n children[j] := ?leftChildInsert;\n children[j + 1] := ?rightChildInsert\n };\n\n /// Used when splitting the children of an internal node\n ///\n /// Takes in the rebalanced child index, as well as both halves of the rebalanced child and splits the children, inserting the left and right child halves appropriately\n ///\n /// For more context, see the documentation for the splitArrayAndInsertTwo method in ArrayUtils.mo\n public func splitChildrenInTwoWithRebalances<T>(\n children : [var ?Node<T>],\n rebalancedChildIndex : Nat,\n leftChildInsert : Node<T>,\n rightChildInsert : Node<T>\n ) : ([var ?Node<T>], [var ?Node<T>]) {\n BTreeHelper.splitArrayAndInsertTwo<Node<T>>(children, rebalancedChildIndex, leftChildInsert, rightChildInsert)\n };\n\n /// Helper used to get the element index of of a element within a node\n ///\n /// for more, see the BinarySearch.binarySearchNode() documentation\n public func getElementIndex<T>(data : Data<T>, compare : (T, T) -> Order.Order, element : T) : BinarySearch.SearchResult {\n BinarySearch.binarySearchNode<T>(data.elements, compare, element, data.count)\n };\n\n // calculates a BTree Node's minimum allowed elements given the order of the BTree\n public func minElementsFromOrder(order : Nat) : Nat {\n if (order % 2 == 0) { order / 2 - 1 } else { order / 2 }\n };\n\n // Given a node, get the maximum element (right most leaf element)\n public func getMaxElement<T>(node : ?Node<T>) : T {\n switch (node) {\n case (?#leaf({ data })) {\n switch (data.elements[data.count - 1]) {\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.NodeUtil.getMaxElement, data cannot have more elements than it's count\")\n };\n case (?element) { element }\n }\n };\n case (?#internal({ data; children })) {\n getMaxElement(children[data.count])\n };\n case null {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.NodeUtil.getMaxElement, the node provided cannot be null\")\n }\n }\n };\n\n type InorderBorrowType = {\n #predecessor;\n #successor\n };\n\n // attempts to retrieve the in max element of the child leaf node directly to the left if the node will allow it\n // returns the deleted max element if able to retrieve, null if not able\n //\n // mutates the predecessing node's elements\n public func borrowFromLeftLeafChild<T>(children : [var ?Node<T>], ofChildIndex : Nat) : ?T {\n let predecessorIndex : Nat = ofChildIndex - 1;\n borrowFromLeafChild(children, predecessorIndex, #predecessor)\n };\n\n // attempts to retrieve the in max element of the child leaf node directly to the right if the node will allow it\n // returns the deleted max element if able to retrieve, null if not able\n //\n // mutates the predecessing node's elements\n public func borrowFromRightLeafChild<T>(children : [var ?Node<T>], ofChildIndex : Nat) : ?T {\n borrowFromLeafChild(children, ofChildIndex + 1, #successor)\n };\n\n func borrowFromLeafChild<T>(children : [var ?Node<T>], borrowChildIndex : Nat, childSide : InorderBorrowType) : ?T {\n let minElements = minElementsFromOrder(children.size());\n\n switch (children[borrowChildIndex]) {\n case (?#leaf({ data })) {\n if (data.count > minElements) {\n // able to borrow an element from this child, so decrement the count of elements\n data.count -= 1; // Since enforce order >= 4, there will always be at least 1 element per node\n switch (childSide) {\n case (#predecessor) {\n let deletedElement = data.elements[data.count];\n data.elements[data.count] := null;\n deletedElement\n };\n case (#successor) {\n ?BTreeHelper.deleteAndShift(data.elements, 0)\n }\n }\n } else { null }\n };\n case _ {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.NodeUtil.borrowFromLeafChild, the node at the borrow child index cannot be null or internal\")\n }\n }\n };\n\n type InternalBorrowResult<T> = {\n #borrowed : InternalBorrow<T>;\n #notEnoughElements : Internal<T>\n };\n\n type InternalBorrow<T> = {\n deletedSiblingElement : ?T;\n child : ?Node<T>\n };\n\n // Attempts to borrow an element and child from an internal sibling node\n public func borrowFromInternalSibling<T>(children : [var ?Node<T>], borrowChildIndex : Nat, borrowType : InorderBorrowType) : InternalBorrowResult<T> {\n let minElements = minElementsFromOrder(children.size());\n\n switch (children[borrowChildIndex]) {\n case (?#internal({ data; children })) {\n if (data.count > minElements) {\n data.count -= 1;\n switch (borrowType) {\n case (#predecessor) {\n let deletedSiblingElement = data.elements[data.count];\n data.elements[data.count] := null;\n let child = children[data.count + 1];\n children[data.count + 1] := null;\n #borrowed({\n deletedSiblingElement;\n child\n })\n };\n case (#successor) {\n #borrowed({\n deletedSiblingElement = ?BTreeHelper.deleteAndShift(data.elements, 0);\n child = ?BTreeHelper.deleteAndShift(children, 0)\n })\n }\n }\n } else { #notEnoughElements({ data; children }) }\n };\n case _ {\n Runtime.trap(\"UNREACHABLE_ERROR: file a bug report! In Set.NodeUtil.borrowFromInternalSibling from internal sibling, the child at the borrow index cannot be null or a leaf\")\n }\n }\n };\n\n type SiblingSide = { #left; #right };\n\n // Rotates the borrowed elements and child from sibling side of the internal node to the internal child recipient\n public func rotateBorrowedElementsAndChildFromSibling<T>(\n internalNode : Internal<T>,\n parentRotateIndex : Nat,\n borrowedSiblingElement : ?T,\n borrowedSiblingChild : ?Node<T>,\n internalChildRecipient : Internal<T>,\n siblingSide : SiblingSide\n ) {\n // if borrowing from the left, the rotated element and child will always be inserted first\n // if borrowing from the right, the rotated element and child will always be inserted last\n let (elementIndex, childIndex) = switch (siblingSide) {\n case (#left) { (0, 0) };\n case (#right) {\n (internalChildRecipient.data.count, internalChildRecipient.data.count + 1)\n }\n };\n\n // get the parent element that will be pushed down the the child\n let elementToBePushedToChild = internalNode.data.elements[parentRotateIndex];\n // replace the parent with the sibling element\n internalNode.data.elements[parentRotateIndex] := borrowedSiblingElement;\n // push the element and child down into the internalChild\n insertAtIndexOfNonFullNodeData<T>(internalChildRecipient.data, elementToBePushedToChild, elementIndex);\n\n BTreeHelper.insertAtPosition<Node<T>>(internalChildRecipient.children, borrowedSiblingChild, childIndex, internalChildRecipient.data.count)\n };\n\n // Merges the elements and children of two internal nodes, pushing the parent element in between the right and left halves\n public func mergeChildrenAndPushDownParent<T>(leftChild : Internal<T>, parentElement : ?T, rightChild : Internal<T>) : Internal<T> {\n {\n data = mergeData<T>(leftChild.data, parentElement, rightChild.data);\n children = mergeChildren(leftChild.children, rightChild.children)\n }\n };\n\n func mergeData<T>(leftData : Data<T>, parentElement : ?T, rightData : Data<T>) : Data<T> {\n assert leftData.count <= minElementsFromOrder(leftData.elements.size() + 1);\n assert rightData.count <= minElementsFromOrder(rightData.elements.size() + 1);\n\n let mergedElements = VarArray.repeat<?T>(null, leftData.elements.size());\n var i = 0;\n while (i < leftData.count) {\n mergedElements[i] := leftData.elements[i];\n i += 1\n };\n\n mergedElements[i] := parentElement;\n i += 1;\n\n var j = 0;\n while (j < rightData.count) {\n mergedElements[i] := rightData.elements[j];\n i += 1;\n j += 1\n };\n\n {\n elements = mergedElements;\n var count = leftData.count + 1 + rightData.count\n }\n };\n\n func mergeChildren<T>(leftChildren : [var ?Node<T>], rightChildren : [var ?Node<T>]) : [var ?Node<T>] {\n let mergedChildren = VarArray.repeat<?Node<T>>(null, leftChildren.size());\n var i = 0;\n\n while (Option.isSome(leftChildren[i])) {\n mergedChildren[i] := leftChildren[i];\n i += 1\n };\n\n var j = 0;\n while (Option.isSome(rightChildren[j])) {\n mergedChildren[i] := rightChildren[j];\n i += 1;\n j += 1\n };\n\n mergedChildren\n }\n }\n}\n"}}}