-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[move] Implement generic comparison method in move - move part
- Loading branch information
1 parent
686d2de
commit 3e9fb56
Showing
7 changed files
with
395 additions
and
8 deletions.
There are no files selected for viewing
1 change: 1 addition & 0 deletions
1
aptos-move/e2e-move-tests/src/tests/code_publishing.data/pack_stdlib/sources/cmp.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../../../framework/move-stdlib/sources/cmp.move |
1 change: 1 addition & 0 deletions
1
...-move/e2e-move-tests/src/tests/code_publishing.data/pack_stdlib_incompat/sources/cmp.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../../../framework/move-stdlib/sources/cmp.move |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
|
||
<a id="0x1_cmp"></a> | ||
|
||
# Module `0x1::cmp` | ||
|
||
|
||
|
||
- [Enum `Ordering`](#0x1_cmp_Ordering) | ||
- [Function `compare`](#0x1_cmp_compare) | ||
- [Function `is_eq`](#0x1_cmp_is_eq) | ||
- [Function `is_lt`](#0x1_cmp_is_lt) | ||
- [Function `is_le`](#0x1_cmp_is_le) | ||
- [Function `is_gt`](#0x1_cmp_is_gt) | ||
- [Function `is_ge`](#0x1_cmp_is_ge) | ||
|
||
|
||
<pre><code></code></pre> | ||
|
||
|
||
|
||
<a id="0x1_cmp_Ordering"></a> | ||
|
||
## Enum `Ordering` | ||
|
||
|
||
|
||
<pre><code>enum <a href="cmp.md#0x1_cmp_Ordering">Ordering</a> <b>has</b> <b>copy</b>, drop | ||
</code></pre> | ||
|
||
|
||
|
||
<details> | ||
<summary>Variants</summary> | ||
|
||
|
||
<details> | ||
<summary>Less</summary> | ||
|
||
|
||
<details> | ||
<summary>Fields</summary> | ||
|
||
|
||
<dl> | ||
</dl> | ||
|
||
|
||
</details> | ||
|
||
</details> | ||
|
||
<details> | ||
<summary>Equal</summary> | ||
|
||
|
||
<details> | ||
<summary>Fields</summary> | ||
|
||
|
||
<dl> | ||
</dl> | ||
|
||
|
||
</details> | ||
|
||
</details> | ||
|
||
<details> | ||
<summary>Greater</summary> | ||
|
||
|
||
<details> | ||
<summary>Fields</summary> | ||
|
||
|
||
<dl> | ||
</dl> | ||
|
||
|
||
</details> | ||
|
||
</details> | ||
|
||
</details> | ||
|
||
<a id="0x1_cmp_compare"></a> | ||
|
||
## Function `compare` | ||
|
||
Compares two values with the natural ordering: | ||
- native types are compared identically to <code><</code> and other operators | ||
- complex types | ||
- Structs and vectors - are compared lexicographically - first field/element is compared first, | ||
and if equal we proceed to the next. | ||
- enum's are compared first by their variant, and if equal - they are compared as structs are. | ||
|
||
|
||
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="cmp.md#0x1_cmp_compare">compare</a><T>(first: &T, second: &T): <a href="cmp.md#0x1_cmp_Ordering">cmp::Ordering</a> | ||
</code></pre> | ||
|
||
|
||
|
||
<details> | ||
<summary>Implementation</summary> | ||
|
||
|
||
<pre><code><b>native</b> <b>public</b>(<b>friend</b>) <b>fun</b> <a href="cmp.md#0x1_cmp_compare">compare</a><T>(first: &T, second: &T): <a href="cmp.md#0x1_cmp_Ordering">Ordering</a>; | ||
</code></pre> | ||
|
||
|
||
|
||
</details> | ||
|
||
<a id="0x1_cmp_is_eq"></a> | ||
|
||
## Function `is_eq` | ||
|
||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_eq">is_eq</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">cmp::Ordering</a>): bool | ||
</code></pre> | ||
|
||
|
||
|
||
<details> | ||
<summary>Implementation</summary> | ||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_eq">is_eq</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">Ordering</a>): bool { | ||
self is Ordering::Equal | ||
} | ||
</code></pre> | ||
|
||
|
||
|
||
</details> | ||
|
||
<a id="0x1_cmp_is_lt"></a> | ||
|
||
## Function `is_lt` | ||
|
||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_lt">is_lt</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">cmp::Ordering</a>): bool | ||
</code></pre> | ||
|
||
|
||
|
||
<details> | ||
<summary>Implementation</summary> | ||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_lt">is_lt</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">Ordering</a>): bool { | ||
self is Ordering::Less | ||
} | ||
</code></pre> | ||
|
||
|
||
|
||
</details> | ||
|
||
<a id="0x1_cmp_is_le"></a> | ||
|
||
## Function `is_le` | ||
|
||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_le">is_le</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">cmp::Ordering</a>): bool | ||
</code></pre> | ||
|
||
|
||
|
||
<details> | ||
<summary>Implementation</summary> | ||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_le">is_le</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">Ordering</a>): bool { | ||
!(self is Ordering::Greater) | ||
} | ||
</code></pre> | ||
|
||
|
||
|
||
</details> | ||
|
||
<a id="0x1_cmp_is_gt"></a> | ||
|
||
## Function `is_gt` | ||
|
||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_gt">is_gt</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">cmp::Ordering</a>): bool | ||
</code></pre> | ||
|
||
|
||
|
||
<details> | ||
<summary>Implementation</summary> | ||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_gt">is_gt</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">Ordering</a>): bool { | ||
self is Ordering::Greater | ||
} | ||
</code></pre> | ||
|
||
|
||
|
||
</details> | ||
|
||
<a id="0x1_cmp_is_ge"></a> | ||
|
||
## Function `is_ge` | ||
|
||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_ge">is_ge</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">cmp::Ordering</a>): bool | ||
</code></pre> | ||
|
||
|
||
|
||
<details> | ||
<summary>Implementation</summary> | ||
|
||
|
||
<pre><code><b>public</b> <b>fun</b> <a href="cmp.md#0x1_cmp_is_ge">is_ge</a>(self: &<a href="cmp.md#0x1_cmp_Ordering">Ordering</a>): bool { | ||
!(self is Ordering::Less) | ||
} | ||
</code></pre> | ||
|
||
|
||
|
||
</details> | ||
|
||
|
||
[move-book]: https://aptos.dev/move/book/SUMMARY |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
module std::cmp { | ||
enum Ordering has copy, drop { | ||
/// First value is less than the second value. | ||
Less, | ||
/// First value is equal to the second value. | ||
Equal, | ||
/// First value is greater than the second value. | ||
Greater, | ||
} | ||
|
||
// TODO - functions here are `public(friend)` here for one release, | ||
// and to be changed to `public` one release later. | ||
#[test_only] | ||
friend std::bcs_tests; | ||
|
||
/// Compares two values with the natural ordering: | ||
/// - native types are compared identically to `<` and other operators | ||
/// - complex types | ||
/// - Structs and vectors - are compared lexicographically - first field/element is compared first, | ||
/// and if equal we proceed to the next. | ||
/// - enum's are compared first by their variant, and if equal - they are compared as structs are. | ||
native public(friend) fun compare<T>(first: &T, second: &T): Ordering; | ||
|
||
public fun is_eq(self: &Ordering): bool { | ||
self is Ordering::Equal | ||
} | ||
|
||
public fun is_lt(self: &Ordering): bool { | ||
self is Ordering::Less | ||
} | ||
|
||
public fun is_le(self: &Ordering): bool { | ||
!(self is Ordering::Greater) | ||
} | ||
|
||
public fun is_gt(self: &Ordering): bool { | ||
self is Ordering::Greater | ||
} | ||
|
||
public fun is_ge(self: &Ordering): bool { | ||
!(self is Ordering::Less) | ||
} | ||
|
||
#[test_only] | ||
struct SomeStruct has drop { | ||
field_1: u64, | ||
field_2: u64, | ||
} | ||
#[test_only] | ||
enum SimpleEnum has drop { | ||
V { field: u64 }, | ||
} | ||
|
||
#[test_only] | ||
enum SomeEnum has drop { | ||
V1 { field_1: u64 }, | ||
V2 { field_2: u64 }, | ||
V3 { field_3: SomeStruct }, | ||
V4 { field_4: vector<u64> }, | ||
V5 { field_5: SimpleEnum }, | ||
} | ||
|
||
#[test] | ||
fun test_compare_numbers() { | ||
assert!(!is_eq(&compare(&1, &5)), 0); | ||
assert!(is_lt(&compare(&1, &5)), 1); | ||
assert!(is_le(&compare(&1, &5)), 2); | ||
assert!(is_eq(&compare(&5, &5)), 3); | ||
assert!(!is_lt(&compare(&5, &5)), 4); | ||
assert!(is_le(&compare(&5, &5)), 5); | ||
assert!(!is_eq(&compare(&7, &5)), 6); | ||
assert!(!is_lt(&compare(&7, &5)), 7); | ||
assert!(!is_le(&compare(&7, &5)), 8); | ||
|
||
assert!(!compare(&1, &5).is_eq(), 0); | ||
assert!(compare(&1, &5).is_lt(), 1); | ||
assert!(compare(&1, &5).is_le(), 2); | ||
assert!(compare(&5, &5).is_eq(), 3); | ||
assert!(!compare(&5, &5).is_lt(), 4); | ||
assert!(compare(&5, &5).is_le(), 5); | ||
assert!(!compare(&7, &5).is_eq(), 6); | ||
assert!(!compare(&7, &5).is_lt(), 7); | ||
assert!(!compare(&7, &5).is_le(), 8); | ||
} | ||
|
||
#[test] | ||
fun test_compare_vectors() { | ||
let empty = vector[]; // here for typing, for the second line | ||
assert!(compare(&empty, &vector[1] ) is Ordering::Less, 0); | ||
assert!(compare(&empty, &vector[] ) is Ordering::Equal, 1); | ||
assert!(compare(&vector[1], &vector[] ) is Ordering::Greater, 2); | ||
assert!(compare(&vector[1, 2], &vector[1, 2] ) is Ordering::Equal, 3); | ||
assert!(compare(&vector[1, 2, 3], &vector[5] ) is Ordering::Less, 4); | ||
assert!(compare(&vector[1, 2, 3], &vector[5, 6, 7]) is Ordering::Less, 5); | ||
assert!(compare(&vector[1, 2, 3], &vector[1, 2, 7]) is Ordering::Less, 6); | ||
} | ||
|
||
#[test] | ||
fun test_compare_structs() { | ||
assert!(compare(&SomeStruct { field_1: 1, field_2: 2}, &SomeStruct { field_1: 1, field_2: 2}) is Ordering::Equal, 0); | ||
assert!(compare(&SomeStruct { field_1: 1, field_2: 2}, &SomeStruct { field_1: 1, field_2: 3}) is Ordering::Less, 1); | ||
assert!(compare(&SomeStruct { field_1: 1, field_2: 2}, &SomeStruct { field_1: 1, field_2: 1}) is Ordering::Greater, 2); | ||
assert!(compare(&SomeStruct { field_1: 1, field_2: 2}, &SomeStruct { field_1: 1, field_2: 1}) is Ordering::Greater, 3); | ||
} | ||
|
||
#[test] | ||
fun test_compare_vector_of_structs() { | ||
assert!(compare(&vector[SomeStruct { field_1: 1, field_2: 2}, SomeStruct { field_1: 3, field_2: 4}], &vector[SomeStruct { field_1: 1, field_2: 3}]) is Ordering::Less, 0); | ||
assert!(compare(&vector[SomeStruct { field_1: 1, field_2: 2}, SomeStruct { field_1: 3, field_2: 4}], &vector[SomeStruct { field_1: 1, field_2: 2}, SomeStruct { field_1: 1, field_2: 3}]) is Ordering::Greater, 1); | ||
} | ||
|
||
#[test] | ||
fun test_compare_enums() { | ||
assert!(compare(&SomeEnum::V1 { field_1: 6}, &SomeEnum::V1 { field_1: 6}) is Ordering::Equal, 0); | ||
assert!(compare(&SomeEnum::V1 { field_1: 6}, &SomeEnum::V2 { field_2: 1}) is Ordering::Less, 1); | ||
assert!(compare(&SomeEnum::V1 { field_1: 6}, &SomeEnum::V2 { field_2: 8}) is Ordering::Less, 2); | ||
assert!(compare(&SomeEnum::V1 { field_1: 6}, &SomeEnum::V1 { field_1: 5}) is Ordering::Greater, 3); | ||
|
||
assert!(compare(&SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 2}}, &SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 2}}) is Ordering::Equal, 4); | ||
assert!(compare(&SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 2}}, &SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 3}}) is Ordering::Less, 5); | ||
assert!(compare(&SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 2}}, &SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 1}}) is Ordering::Greater, 6); | ||
assert!(compare(&SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 2}}, &SomeEnum::V3 { field_3: SomeStruct { field_1: 1, field_2: 1}}) is Ordering::Greater, 7); | ||
|
||
assert!(compare(&SomeEnum::V4 { field_4: vector[1, 2]}, &SomeEnum::V4 { field_4: vector[1, 2]}) is Ordering::Equal, 8); | ||
assert!(compare(&SomeEnum::V4 { field_4: vector[1, 2, 3]}, &SomeEnum::V4 { field_4: vector[5]}) is Ordering::Less, 9); | ||
assert!(compare(&SomeEnum::V4 { field_4: vector[1, 2, 3]}, &SomeEnum::V4 { field_4: vector[5, 6, 7]}) is Ordering::Less, 10); | ||
assert!(compare(&SomeEnum::V4 { field_4: vector[1, 2, 3]}, &SomeEnum::V4 { field_4: vector[1, 2, 7]}) is Ordering::Less, 11); | ||
|
||
assert!(compare(&SomeEnum::V5 { field_5: SimpleEnum::V { field: 3}}, &SomeEnum::V5 { field_5: SimpleEnum::V { field: 3}}) is Ordering::Equal, 12); | ||
assert!(compare(&SomeEnum::V5 { field_5: SimpleEnum::V { field: 5}}, &SomeEnum::V5 { field_5: SimpleEnum::V { field: 3}}) is Ordering::Greater, 13); | ||
assert!(compare(&SomeEnum::V5 { field_5: SimpleEnum::V { field: 3}}, &SomeEnum::V5 { field_5: SimpleEnum::V { field: 5}}) is Ordering::Less, 14); | ||
} | ||
} |
Oops, something went wrong.