mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Pair and Triple Compare w/ Unit Tests (#2359)
* Pair and Triple Compare w/ Unit Tests * scope creep myself by adding date-time eq op * make Pair and Triple printable * Update releasenotes. Restrict equals on tuples to when underlying type supports `==`. Remove unnecessary Time.eq. --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
@@ -1,11 +1,17 @@
|
|||||||
module std::collections::pair{Type1, Type2};
|
module std::collections::pair{Type1, Type2};
|
||||||
|
import std::io;
|
||||||
|
|
||||||
struct Pair
|
struct Pair (Printable)
|
||||||
{
|
{
|
||||||
Type1 first;
|
Type1 first;
|
||||||
Type2 second;
|
Type2 second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn usz? Pair.to_format(&self, Formatter* f) @dynamic
|
||||||
|
{
|
||||||
|
return f.printf("{ %s, %s }", self.first, self.second);
|
||||||
|
}
|
||||||
|
|
||||||
<*
|
<*
|
||||||
@param [&out] a
|
@param [&out] a
|
||||||
@param [&out] b
|
@param [&out] b
|
||||||
@@ -18,15 +24,27 @@ macro void Pair.unpack(&self, a, b)
|
|||||||
*b = self.second;
|
*b = self.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
module std::collections::triple{Type1, Type2, Type3};
|
fn bool Pair.equal(self, Pair other) @operator(==) @if (types::has_equals(Type1) &&& types::has_equals(Type2))
|
||||||
|
{
|
||||||
|
return self.first == other.first && self.second == other.second;
|
||||||
|
}
|
||||||
|
|
||||||
struct Triple
|
|
||||||
|
|
||||||
|
module std::collections::triple{Type1, Type2, Type3};
|
||||||
|
import std::io;
|
||||||
|
|
||||||
|
struct Triple (Printable)
|
||||||
{
|
{
|
||||||
Type1 first;
|
Type1 first;
|
||||||
Type2 second;
|
Type2 second;
|
||||||
Type3 third;
|
Type3 third;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn usz? Triple.to_format(&self, Formatter* f) @dynamic
|
||||||
|
{
|
||||||
|
return f.printf("{ %s, %s, %s }", self.first, self.second, self.third);
|
||||||
|
}
|
||||||
<*
|
<*
|
||||||
@param [&out] a
|
@param [&out] a
|
||||||
@param [&out] b
|
@param [&out] b
|
||||||
@@ -42,6 +60,12 @@ macro void Triple.unpack(&self, a, b, c)
|
|||||||
*c = self.third;
|
*c = self.third;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bool Triple.equal(self, Triple other) @operator(==) @if (types::has_equals(Type1) &&& types::has_equals(Type2) &&& types::has_equals(Type3))
|
||||||
|
{
|
||||||
|
return self.first == other.first && self.second == other.second && self.third == other.third;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module std::collections::tuple{Type1, Type2};
|
module std::collections::tuple{Type1, Type2};
|
||||||
|
|
||||||
struct Tuple @deprecated("Use 'Pair' instead")
|
struct Tuple @deprecated("Use 'Pair' instead")
|
||||||
|
|||||||
@@ -339,6 +339,8 @@ macro bool is_same_vector_type($Type1, $Type2) @const
|
|||||||
$endif
|
$endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro bool has_equals($Type) @const => $defined(($Type){} == ($Type){});
|
||||||
|
|
||||||
macro bool is_equatable_type($Type) @const
|
macro bool is_equatable_type($Type) @const
|
||||||
{
|
{
|
||||||
$if $defined($Type.less) || $defined($Type.compare_to) || $defined($Type.equals):
|
$if $defined($Type.less) || $defined($Type.compare_to) || $defined($Type.equals):
|
||||||
|
|||||||
@@ -112,6 +112,11 @@ fn TzDateTime TzDateTime.to_gmt_offset(self, int gmt_offset) {
|
|||||||
return { dt, gmt_offset };
|
return { dt, gmt_offset };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bool TzDateTime.eq(self, TzDateTime other) @operator(==) @inline
|
||||||
|
{
|
||||||
|
return self.to_gmt_offset(0).time == other.to_gmt_offset(0).time;
|
||||||
|
}
|
||||||
|
|
||||||
<*
|
<*
|
||||||
@require day >= 1 && day < 32
|
@require day >= 1 && day < 32
|
||||||
@require hour >= 0 && hour < 24
|
@require hour >= 0 && hour < 24
|
||||||
@@ -257,3 +262,5 @@ fn Duration DateTime.diff_us(self, DateTime from) @operator(-)
|
|||||||
{
|
{
|
||||||
return self.time.diff_us(from.time);
|
return self.time.diff_us(from.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bool DateTime.eq(self, DateTime other) @operator(==) @inline => self.time == other.time;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
- With avx512, passing a 512 bit vector in a union would be lowered incorrectly, causing an assert. #2362
|
- With avx512, passing a 512 bit vector in a union would be lowered incorrectly, causing an assert. #2362
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
|
- Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`.
|
||||||
|
|
||||||
## 0.7.4 Change list
|
## 0.7.4 Change list
|
||||||
|
|
||||||
|
|||||||
71
test/unit/stdlib/collections/tuple.c3
Normal file
71
test/unit/stdlib/collections/tuple.c3
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
module tuple_test;
|
||||||
|
|
||||||
|
struct TestStruct
|
||||||
|
{
|
||||||
|
String a;
|
||||||
|
int b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bool TestStruct.eq(self, TestStruct other) @operator(==)
|
||||||
|
=> self.a == other.a && self.b == other.b;
|
||||||
|
|
||||||
|
|
||||||
|
module tuple_test @test;
|
||||||
|
|
||||||
|
import std::collections::pair;
|
||||||
|
import std::collections::triple;
|
||||||
|
|
||||||
|
|
||||||
|
fn void pair_make_and_unpack()
|
||||||
|
{
|
||||||
|
Pair { ulong, String } x = { 0x8034534, "some string" };
|
||||||
|
|
||||||
|
assert(x.first == 0x8034534);
|
||||||
|
assert(x.second == "some string");
|
||||||
|
|
||||||
|
ulong a;
|
||||||
|
String b;
|
||||||
|
x.unpack(&a, &b);
|
||||||
|
|
||||||
|
assert(a == 0x8034534);
|
||||||
|
assert(b == "some string");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void pair_compare()
|
||||||
|
{
|
||||||
|
Pair { TestStruct, String } x = { {"left", -123}, "right" };
|
||||||
|
Pair { TestStruct, String } y = { {"left", -123}, "right" };
|
||||||
|
Pair { TestStruct, String } z = { {"left", 4096}, "right" };
|
||||||
|
|
||||||
|
assert(x == y);
|
||||||
|
assert(x != z);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void triple_make_and_unpack()
|
||||||
|
{
|
||||||
|
int myval = 7;
|
||||||
|
Triple { ulong, String, int* } x = { 0xA_DEAD_C0DE, "yet another string", &myval };
|
||||||
|
|
||||||
|
assert(x.first == 0xA_DEAD_C0DE);
|
||||||
|
assert(x.second == "yet another string");
|
||||||
|
assert(x.third == &myval);
|
||||||
|
|
||||||
|
ulong a;
|
||||||
|
String b;
|
||||||
|
int* c;
|
||||||
|
x.unpack(&a, &b, &c);
|
||||||
|
|
||||||
|
assert(a == 0xA_DEAD_C0DE);
|
||||||
|
assert(b == "yet another string");
|
||||||
|
assert(c == &myval);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void triple_compare()
|
||||||
|
{
|
||||||
|
Triple { TestStruct, String, String } x = { {"in", 42}, "left", "right" };
|
||||||
|
Triple { TestStruct, String, String } y = { {"in", 42}, "left", "right" };
|
||||||
|
Triple { TestStruct, String, String } z = { {"in", 42}, "up", "down" };
|
||||||
|
|
||||||
|
assert(x == y);
|
||||||
|
assert(x != z);
|
||||||
|
}
|
||||||
@@ -49,6 +49,44 @@ fn void test_parse_and_add()
|
|||||||
test::eq(x.day, 4);
|
test::eq(x.day, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn void datetime_eq()
|
||||||
|
{
|
||||||
|
DateTime d = datetime::from_date(1973, APRIL, 27, 12, 23, 55, 34);
|
||||||
|
DateTime d2 = d;
|
||||||
|
|
||||||
|
assert(d == d2);
|
||||||
|
|
||||||
|
d2 = d2.add_days(6);
|
||||||
|
assert(d != d2);
|
||||||
|
|
||||||
|
d2 = d2.add_days(-5);
|
||||||
|
assert(d != d2);
|
||||||
|
|
||||||
|
d2 = d2.add_days(-1);
|
||||||
|
assert(d == d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void tzdatetime_eq()
|
||||||
|
{
|
||||||
|
int offset1_hours = 7;
|
||||||
|
int offset2_hours = -1;
|
||||||
|
|
||||||
|
TzDateTime d1 = datetime::from_date_tz(2022, OCTOBER, 15, 9, 07, 45, gmt_offset: offset1_hours * 3600);
|
||||||
|
TzDateTime d2 = datetime::from_date_tz(2022, OCTOBER, 15, 1, 07, 45, gmt_offset: offset2_hours * 3600);
|
||||||
|
|
||||||
|
assert(d1 == d2);
|
||||||
|
|
||||||
|
d2 = d2.add_years(30);
|
||||||
|
assert(d1 != d2);
|
||||||
|
|
||||||
|
offset1_hours = 12;
|
||||||
|
offset2_hours = -10;
|
||||||
|
|
||||||
|
d1 = datetime::from_date_tz(2022, OCTOBER, 15, 20, 15, 31, gmt_offset: offset1_hours * 3600);
|
||||||
|
d2 = datetime::from_date_tz(2022, OCTOBER, 14, 22, 15, 31, gmt_offset: offset2_hours * 3600);
|
||||||
|
assert(d1 == d2);
|
||||||
|
}
|
||||||
|
|
||||||
fn void test_timezone()
|
fn void test_timezone()
|
||||||
{
|
{
|
||||||
int offset_hours = 7;
|
int offset_hours = 7;
|
||||||
|
|||||||
@@ -13,6 +13,20 @@ fn void time_diff()
|
|||||||
test::eq(t, t2);
|
test::eq(t, t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn void time_eq()
|
||||||
|
{
|
||||||
|
Time t = time::now();
|
||||||
|
Time t2 = t;
|
||||||
|
|
||||||
|
assert(t == t2);
|
||||||
|
|
||||||
|
t2 += time::US;
|
||||||
|
assert(t != t2);
|
||||||
|
|
||||||
|
t2 -= time::US;
|
||||||
|
assert(t == t2);
|
||||||
|
}
|
||||||
|
|
||||||
fn void clock_diff()
|
fn void clock_diff()
|
||||||
{
|
{
|
||||||
Clock c = clock::now();
|
Clock c = clock::now();
|
||||||
|
|||||||
Reference in New Issue
Block a user