Skip to content

Commit

Permalink
Implement various default mutable sequence function variants
Browse files Browse the repository at this point in the history
Only a couple of sort() overloads are still missing
  • Loading branch information
GrieferAtWork committed May 18, 2024
1 parent 7322ede commit e0ad9b8
Show file tree
Hide file tree
Showing 22 changed files with 1,438 additions and 550 deletions.
1 change: 1 addition & 0 deletions .vs/deemon-v141.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@
<ClInclude Include="..\src\deemon\objects\seq\set.h" />
<ClInclude Include="..\src\deemon\objects\seq\simpleproxy.h" />
<ClInclude Include="..\src\deemon\objects\seq\smap.h" />
<ClInclude Include="..\src\deemon\objects\seq\sort-impl.c.inl" />
<ClInclude Include="..\src\deemon\objects\seq\sort.h" />
<ClInclude Include="..\src\deemon\objects\seq\subrange.h" />
<ClInclude Include="..\src\deemon\objects\seq\svec.h" />
Expand Down
3 changes: 3 additions & 0 deletions .vs/deemon-v141.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,9 @@
<ClInclude Include="..\src\deemon\objects\seq\smap.h">
<Filter>src\objects\seq</Filter>
</ClInclude>
<ClInclude Include="..\src\deemon\objects\seq\sort-impl.c.inl">
<Filter>src\objects\seq</Filter>
</ClInclude>
<ClInclude Include="..\src\deemon\objects\seq\sort.h">
<Filter>src\objects\seq</Filter>
</ClInclude>
Expand Down
1 change: 1 addition & 0 deletions .vs/deemon-v142.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@
<ClInclude Include="..\src\deemon\objects\seq\set.h" />
<ClInclude Include="..\src\deemon\objects\seq\simpleproxy.h" />
<ClInclude Include="..\src\deemon\objects\seq\smap.h" />
<ClInclude Include="..\src\deemon\objects\seq\sort-impl.c.inl" />
<ClInclude Include="..\src\deemon\objects\seq\sort.h" />
<ClInclude Include="..\src\deemon\objects\seq\subrange.h" />
<ClInclude Include="..\src\deemon\objects\seq\svec.h" />
Expand Down
3 changes: 3 additions & 0 deletions .vs/deemon-v142.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,9 @@
<ClInclude Include="..\src\deemon\objects\seq\smap.h">
<Filter>src\objects\seq</Filter>
</ClInclude>
<ClInclude Include="..\src\deemon\objects\seq\sort-impl.c.inl">
<Filter>src\objects\seq</Filter>
</ClInclude>
<ClInclude Include="..\src\deemon\objects\seq\sort.h">
<Filter>src\objects\seq</Filter>
</ClInclude>
Expand Down
9 changes: 5 additions & 4 deletions include/deemon/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,14 @@ DeeList_Pop(DeeObject *__restrict self, Dee_ssize_t index);
DFUNDEF NONNULL((1)) bool DCALL
DeeList_Clear(DeeObject *__restrict self);

/* Sort the given list ascendingly, or according to `key' */
DFUNDEF WUNUSED NONNULL((1)) int DCALL
DeeList_Sort(DeeObject *self, DeeObject *key);
/* Sort the given list ascendingly, or according to `key'
* To use default sorting, pass `Dee_None' for `key' */
DFUNDEF WUNUSED NONNULL((1, 4)) int DCALL
DeeList_Sort(DeeObject *self, size_t start, size_t end, DeeObject *key);

/* Reverse the order of the elements of `self' */
DFUNDEF NONNULL((1)) void DCALL
DeeList_Reverse(DeeObject *__restrict self);
DeeList_Reverse(DeeObject *__restrict self, size_t start, size_t end);

/* Remove all items matching `!!should(item)'
* @return: * : The number of removed items.
Expand Down
3 changes: 2 additions & 1 deletion include/deemon/tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ DDATDEF DeeObject DeeTuple_Empty;
#define Dee_return_empty_tuple Dee_return_reference_(Dee_EmptyTuple)

DDATDEF DeeTypeObject DeeTuple_Type;
DDATDEF DeeTypeObject DeeNullableTuple_Type; /* Same as "DeeTuple_Type", but items are allowed to be NULL (meaning unbound) */
#define DeeTuple_Check(x) DeeObject_InstanceOfExact(x, &DeeTuple_Type) /* `Tuple' is final */
#define DeeTuple_CheckExact(x) DeeObject_InstanceOfExact(x, &DeeTuple_Type)

Expand Down Expand Up @@ -129,7 +130,7 @@ DeeTuple_FreeUninitialized(DREF DeeTupleObject *__restrict self);

/* Create a new tuple object from a sequence or iterator. */
DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeTuple_FromSequence(DeeObject *__restrict self);
DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeTuple_FromIterator(DeeObject *__restrict self);
DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeTuple_FromIterator(DeeObject *__restrict self); /* TODO: Deprecated */

/* Return a new tuple object containing the types of each object of the given tuple. */
DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeTuple_Types(DeeObject *__restrict self);
Expand Down
4 changes: 2 additions & 2 deletions src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ EXPORTS
_DeeList_Pop@8=DeeList_Pop@8
_DeeList_RemoveIf@20=DeeList_RemoveIf@20
_DeeList_Resize@12=DeeList_Resize@12
_DeeList_Reverse@4=DeeList_Reverse@4
_DeeList_Sort@8=DeeList_Sort@8
_DeeList_Reverse@12=DeeList_Reverse@12
_DeeList_Sort@16=DeeList_Sort@16
_DeeMapFile_Fini@4=DeeMapFile_Fini@4
_DeeMapFile_InitFile@32=DeeMapFile_InitFile@32
_DeeMapFile_InitSysFd@32=DeeMapFile_InitSysFd@32
Expand Down
4 changes: 2 additions & 2 deletions src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ EXPORTS
DeeList_Pop@8=_DeeList_Pop@8
DeeList_RemoveIf@20=_DeeList_RemoveIf@20
DeeList_Resize@12=_DeeList_Resize@12
DeeList_Reverse@4=_DeeList_Reverse@4
DeeList_Sort@8=_DeeList_Sort@8
DeeList_Reverse@12=_DeeList_Reverse@12
DeeList_Sort@16=_DeeList_Sort@16
DeeMapFile_Fini@4=_DeeMapFile_Fini@4
DeeMapFile_InitFile@32=_DeeMapFile_InitFile@32
DeeMapFile_InitSysFd@32=_DeeMapFile_InitSysFd@32
Expand Down
210 changes: 137 additions & 73 deletions src/deemon/objects/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -2874,12 +2874,16 @@ list_shrink(List *me, size_t argc, DeeObject *const *argv) {

/* Reverse the order of the elements of `self' */
PUBLIC NONNULL((1)) void DCALL
DeeList_Reverse(DeeObject *__restrict self) {
DeeList_Reverse(DeeObject *__restrict self, size_t start, size_t end) {
List *me = (List *)self;
DeeObject **lo, **hi;
DeeList_LockWrite(me);
lo = DeeList_ELEM(me);
hi = lo + DeeList_SIZE(me);
if (end > me->l_list.ol_elemc)
end = me->l_list.ol_elemc;
if unlikely(start > end)
start = end;
lo = DeeList_ELEM(me) + start;
hi = DeeList_ELEM(me) + end;
while (lo < hi) {
DeeObject *temp;
temp = *lo;
Expand All @@ -2890,61 +2894,103 @@ DeeList_Reverse(DeeObject *__restrict self) {
}

PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
list_reverse(List *me, size_t argc, DeeObject *const *argv) {
if (DeeArg_Unpack(argc, argv, ":reverse"))
list_reverse(List *me, size_t argc, DeeObject *const *argv, DeeObject *kw) {
size_t start = 0, end = (size_t)-1;
if (DeeArg_UnpackKw(argc, argv, kw, kwlist__start_end,
"|" UNPuSIZ UNPuSIZ ":reverse",
&start, &end))
goto err;
DeeList_Reverse((DeeObject *)me);
DeeList_Reverse((DeeObject *)me, start, end);
return_none;
err:
return NULL;
}



/* Sort the given list ascendingly, or according to `key' */
PUBLIC WUNUSED NONNULL((1)) int DCALL
DeeList_Sort(DeeObject *self, DeeObject *key) {
/* Sort the given list ascendingly, or according to `key'
* To use default sorting, pass `Dee_None' for `key' */
PUBLIC WUNUSED NONNULL((1, 4)) int DCALL
DeeList_Sort(DeeObject *self, size_t start, size_t end, DeeObject *key) {
List *me = (List *)self;
DeeObject **oldv, **newv;
size_t oldc, objc;
objc = DeeList_SIZE_ATOMIC(me);
size_t oldc, objc, list_objc;
size_t used_start = start;
size_t used_end = end;
list_objc = DeeList_SIZE_ATOMIC(me);
if (used_end > list_objc)
used_end = list_objc;
if unlikely(used_start > used_end)
used_start = used_end;
objc = used_end - used_start;
oldv = (DeeObject **)Dee_Mallocc(objc, sizeof(DeeObject *));
if unlikely(!oldv)
goto err;
again:
DeeList_LockRead(me);
if unlikely(me->l_list.ol_elemc > objc) {
DeeObject **new_objv;
objc = me->l_list.ol_elemc;
DeeList_LockEndRead(me);
new_objv = (DeeObject **)Dee_Reallocc(oldv, objc, sizeof(DeeObject *));
if unlikely(!new_objv)
goto err_oldv;
oldv = new_objv;
goto again;
if unlikely(me->l_list.ol_elemc != list_objc) {
size_t new_used_start = start;
size_t new_used_end = end;
list_objc = me->l_list.ol_elemc;
if (new_used_end > list_objc)
new_used_end = list_objc;
if unlikely(new_used_start > new_used_end)
new_used_start = new_used_end;
if (new_used_start != used_start || new_used_end != used_end) {
DeeObject **new_objv;
DeeList_LockEndRead(me);
new_objv = (DeeObject **)Dee_Reallocc(oldv, list_objc, sizeof(DeeObject *));
if unlikely(!new_objv)
goto err_oldv;
oldv = new_objv;
used_start = new_used_start;
used_end = new_used_end;
oldc = used_end - used_start;
goto again;
}
}

/* Read all the old elements from the list. */
Dee_Movrefv(oldv, me->l_list.ol_elemv, objc);
Dee_Movrefv(oldv, me->l_list.ol_elemv + used_start, objc);
DeeList_LockEndRead(me);

/* Allocate the new list */
newv = (DeeObject **)Dee_Mallocc(objc, sizeof(DeeObject *));
if unlikely(!newv)
goto err_oldv_elem;
/* Do the actual sorting. */
if unlikely(DeeSeq_MergeSort(newv, oldv, objc, key))
if unlikely(!DeeNone_Check(key)
? DeeSeq_SortVectorWithKey(objc, newv, oldv, key)
: DeeSeq_SortVector(objc, newv, oldv))
goto err_newv;
Dee_Free(oldv);
DeeList_LockWrite(me);
oldv = me->l_list.ol_elemv;
oldc = me->l_list.ol_elemc;
me->l_list.ol_elemc = objc;
me->l_list.ol_elemv = newv;
_DeeList_SetAlloc(me, objc);
DeeList_LockEndWrite(me);
Dee_Decrefv(oldv, oldc);
Dee_Free(oldv);
if likely(objc == list_objc) {
/* Likely case: sort the whole list (replace the entire vector) */
Dee_Free(oldv);
DeeList_LockWrite(me);
oldv = me->l_list.ol_elemv;
oldc = me->l_list.ol_elemc;
me->l_list.ol_elemc = objc;
me->l_list.ol_elemv = newv;
_DeeList_SetAlloc(me, objc);
DeeList_LockEndWrite(me);
Dee_Decrefv(oldv, oldc);
Dee_Free(oldv);
} else {
/* Special case: only a sub-range of the list was sorted; must override that sub-range. */
DeeList_LockWrite(me);
if unlikely(me->l_list.ol_elemc < (used_start + objc)) {
DeeList_LockEndWrite(me);
Dee_Decrefv(newv, objc);
Dee_Free(newv);
goto again;
}
memcpyc(oldv, me->l_list.ol_elemv + used_start, objc, sizeof(DREF DeeObject *));
memcpyc(me->l_list.ol_elemv + used_start, newv, objc, sizeof(DREF DeeObject *));
DeeList_LockEndWrite(me);
Dee_Decrefv(oldv, objc);
Dee_Free(oldv);
Dee_Free(newv);
}
return 0;
err_newv:
Dee_Free(newv);
Expand All @@ -2956,44 +3002,62 @@ DeeList_Sort(DeeObject *self, DeeObject *key) {
return -1;
}

PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
DeeList_Sorted(DeeObject *self, DeeObject *key) {
List *me = (List *)self;
PRIVATE WUNUSED NONNULL((1, 4)) DREF DeeTupleObject *DCALL
DeeList_Sorted(List *me, size_t start, size_t end, DeeObject *key) {
DREF DeeTupleObject *result;
DeeObject **oldv;
size_t objc;
DeeTupleObject *result;
objc = DeeList_SIZE_ATOMIC(me);
size_t oldc, objc, list_objc;

Check warning on line 3009 in src/deemon/objects/list.c

View workflow job for this annotation

GitHub Actions / build

variable ‘oldc’ set but not used [-Wunused-but-set-variable]
size_t used_start = start;
size_t used_end = end;
list_objc = DeeList_SIZE_ATOMIC(me);
if (used_end > list_objc)
used_end = list_objc;
if unlikely(used_start > used_end)
used_start = used_end;
objc = used_end - used_start;
oldv = (DeeObject **)Dee_Mallocc(objc, sizeof(DeeObject *));
if unlikely(!oldv)
goto err;
again:
DeeList_LockRead(me);
if unlikely(DeeList_SIZE(me) > objc) {
DeeObject **new_objv;
objc = DeeList_SIZE(me);
DeeList_LockEndRead(me);
new_objv = (DeeObject **)Dee_Reallocc(oldv, objc, sizeof(DeeObject *));
if unlikely(!new_objv)
goto err_oldv;
oldv = new_objv;
goto again;
if unlikely(me->l_list.ol_elemc != list_objc) {
size_t new_used_start = start;
size_t new_used_end = end;
list_objc = me->l_list.ol_elemc;
if (new_used_end > list_objc)
new_used_end = list_objc;
if unlikely(new_used_start > new_used_end)
new_used_start = new_used_end;
if (new_used_start != used_start || new_used_end != used_end) {
DeeObject **new_objv;
DeeList_LockEndRead(me);
new_objv = (DeeObject **)Dee_Reallocc(oldv, list_objc, sizeof(DeeObject *));
if unlikely(!new_objv)
goto err_oldv;
oldv = new_objv;
used_start = new_used_start;
used_end = new_used_end;
oldc = used_end - used_start;
goto again;
}
}

/* Read all the old elements from the list. */
Dee_Movrefv(oldv, DeeList_ELEM(me), objc);
Dee_Movrefv(oldv, me->l_list.ol_elemv + used_start, objc);
DeeList_LockEndRead(me);

/* Allocate the new list */
/* Allocate the new tuple */
result = DeeTuple_NewUninitialized(objc);
if unlikely(!result)
goto err_oldv_elem;

/* Do the actual sorting. */
if (DeeSeq_MergeSort(DeeTuple_ELEM(result), oldv, objc, key))
goto err_result;
if unlikely(key ? DeeSeq_SortVectorWithKey(objc, result->t_elem, oldv, key)
: DeeSeq_SortVector(objc, result->t_elem, oldv))
goto err_oldv_elem_result;
Dee_Free(oldv);
return (DeeObject *)result;
err_result:
return result;
err_oldv_elem_result:
DeeTuple_FreeUninitialized(result);
err_oldv_elem:
Dee_Decrefv(oldv, objc);
Expand All @@ -3007,27 +3071,29 @@ DeeList_Sorted(DeeObject *self, DeeObject *key) {
PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
list_sort(List *me, size_t argc,
DeeObject *const *argv, DeeObject *kw) {
DeeObject *key = NULL;
if (DeeArg_UnpackKw(argc, argv, kw, kwlist__key, "|o:sort", &key))
size_t start = 0, end = (size_t)-1;
DeeObject *key = Dee_None;
if (DeeArg_UnpackKw(argc, argv, kw, kwlist__start_end_key,
"|" UNPuSIZ UNPuSIZ "o:sort",
&start, &end, &key))
goto err;
if (DeeNone_Check(key))
key = NULL;
if (DeeList_Sort((DeeObject *)me, key))
if unlikely(DeeList_Sort((DeeObject *)me, start, end, key))
goto err;
return_none;
err:
return NULL;
}

PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
PRIVATE WUNUSED NONNULL((1)) DREF DeeTupleObject *DCALL
list_sorted(List *me, size_t argc,
DeeObject *const *argv, DeeObject *kw) {
DeeObject *key = NULL;
if (DeeArg_UnpackKw(argc, argv, kw, kwlist__key, "|o:sorted", &key))
size_t start = 0, end = (size_t)-1;
DeeObject *key = Dee_None;
if (DeeArg_UnpackKw(argc, argv, kw, kwlist__start_end_key,
"|" UNPuSIZ UNPuSIZ "o:sorted",
&start, &end, &key))
goto err;
if (DeeNone_Check(key))
key = NULL;
return DeeList_Sorted((DeeObject *)me, key);
return DeeList_Sorted(me, start, end, key);
err:
return NULL;
}
Expand Down Expand Up @@ -3139,16 +3205,14 @@ PRIVATE struct type_method tpconst list_methods[] = {
"Same as ${this.pop(-1)}"),

/* List ordering functions. */
TYPE_METHOD_F("reverse", &list_reverse, METHOD_FNOREFESCAPE,
"()\n"
"Reverse the order of all the elements of @this List"),
TYPE_KWMETHOD_F("sort", &list_sort, METHOD_FNOREFESCAPE,
"()\n"
"(key:?DCallable)\n"
TYPE_KWMETHOD_F(STR_reverse, &list_reverse, METHOD_FNOREFESCAPE,
"(start=!0,end=!-1)\n"
"Reverse the order of all the elements of @this List"),
TYPE_KWMETHOD_F(STR_sort, &list_sort, METHOD_FNOREFESCAPE,
"(start=!0,end=!-1,key:?DCallable=!N)\n"
"Sort the elements of @this List in ascending order, or in accordance to @key"),
TYPE_KWMETHOD_F("sorted", &list_sorted, METHOD_FNOREFESCAPE,
"->?S?O\n"
"(key:?DCallable)->?S?O\n"
TYPE_KWMETHOD_F(STR_sorted, &list_sorted, METHOD_FNOREFESCAPE,
"(start=!0,end=!-1,key:?DCallable=!N)->?S?O\n"
"Return a sequence that contains all elements from @this sequence, "
/**/ "but sorted in ascending order, or in accordance to @key\n"
"The type of sequence returned is implementation-defined"),
Expand Down
Loading

0 comments on commit e0ad9b8

Please sign in to comment.