diff --git a/.vs/deemon-v141.vcxproj b/.vs/deemon-v141.vcxproj
index f23c3cd45..64a0653d3 100644
--- a/.vs/deemon-v141.vcxproj
+++ b/.vs/deemon-v141.vcxproj
@@ -267,6 +267,7 @@
+
diff --git a/.vs/deemon-v141.vcxproj.filters b/.vs/deemon-v141.vcxproj.filters
index d7cf3a849..3d58fd9e6 100644
--- a/.vs/deemon-v141.vcxproj.filters
+++ b/.vs/deemon-v141.vcxproj.filters
@@ -774,6 +774,9 @@
src\objects\seq
+
+ src\objects\seq
+
src\objects\seq
diff --git a/.vs/deemon-v142.vcxproj b/.vs/deemon-v142.vcxproj
index 376680759..abbb99a7c 100644
--- a/.vs/deemon-v142.vcxproj
+++ b/.vs/deemon-v142.vcxproj
@@ -267,6 +267,7 @@
+
diff --git a/.vs/deemon-v142.vcxproj.filters b/.vs/deemon-v142.vcxproj.filters
index d7cf3a849..3d58fd9e6 100644
--- a/.vs/deemon-v142.vcxproj.filters
+++ b/.vs/deemon-v142.vcxproj.filters
@@ -774,6 +774,9 @@
src\objects\seq
+
+ src\objects\seq
+
src\objects\seq
diff --git a/include/deemon/list.h b/include/deemon/list.h
index 3f7d118fe..83f16e3d7 100644
--- a/include/deemon/list.h
+++ b/include/deemon/list.h
@@ -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.
diff --git a/include/deemon/tuple.h b/include/deemon/tuple.h
index 313aefc66..a8a8d18ee 100644
--- a/include/deemon/tuple.h
+++ b/include/deemon/tuple.h
@@ -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)
@@ -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);
diff --git a/src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def b/src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def
index a27e40976..4db232e05 100644
--- a/src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def
+++ b/src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def
@@ -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
diff --git a/src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def b/src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def
index 54d216c48..892bf8926 100644
--- a/src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def
+++ b/src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def
@@ -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
diff --git a/src/deemon/objects/list.c b/src/deemon/objects/list.c
index 44430fd11..c7aa87ca4 100644
--- a/src/deemon/objects/list.c
+++ b/src/deemon/objects/list.c
@@ -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;
@@ -2890,10 +2894,13 @@ 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;
@@ -2901,31 +2908,50 @@ list_reverse(List *me, size_t argc, DeeObject *const *argv) {
-/* 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 */
@@ -2933,18 +2959,38 @@ DeeList_Sort(DeeObject *self, DeeObject *key) {
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);
@@ -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;
+ 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);
@@ -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;
}
@@ -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"),
diff --git a/src/deemon/objects/seq.c b/src/deemon/objects/seq.c
index e44a35e2f..13d572270 100644
--- a/src/deemon/objects/seq.c
+++ b/src/deemon/objects/seq.c
@@ -4041,12 +4041,14 @@ seq_rindex(DeeObject *self, size_t argc, DeeObject *const *argv, DeeObject *kw)
PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
seq_reversed(DeeObject *self, size_t argc, DeeObject *const *argv, DeeObject *kw) {
DREF DeeObject *result;
- (void)kw;
- if (DeeArg_Unpack(argc, argv, ":reversed"))
+ size_t start = 0, end = (size_t)-1;
+ if (DeeArg_UnpackKw(argc, argv, kw, kwlist__start_end,
+ "|" UNPuSIZ UNPuSIZ ":reverse",
+ &start, &end))
goto err;
result = DeeList_FromSequence(self);
if likely(result)
- DeeList_Reverse(result);
+ DeeList_Reverse(result, start, end);
return result;
err:
return NULL;
@@ -4064,7 +4066,7 @@ seq_sorted(DeeObject *self, size_t argc,
result = DeeList_FromSequence(self);
if unlikely(!result)
goto err;
- if unlikely(DeeList_Sort(result, key))
+ if unlikely(DeeList_Sort(result, 0, (size_t)-1, key))
Dee_Clear(result);
return result;
err:
@@ -4408,12 +4410,20 @@ seq_resize(DeeObject *self, size_t argc,
PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
seq_reverse(DeeObject *self, size_t argc, DeeObject *const *argv, DeeObject *kw) {
+ DREF DeeObject *reversed;
(void)kw;
if (DeeArg_Unpack(argc, argv, ":reverse"))
goto err;
- if (DeeSeq_Reverse(self))
+ reversed = DeeList_FromSequence(self);
+ if unlikely(!reversed)
goto err;
+ DeeList_Reverse(reversed, 0, (size_t)-1);
+ if unlikely(DeeObject_Assign(self, reversed))
+ goto err_reversed;
+ Dee_Decref(reversed);
return_none;
+err_reversed:
+ Dee_Decref(reversed);
err:
return NULL;
}
@@ -4421,14 +4431,21 @@ seq_reverse(DeeObject *self, size_t argc, DeeObject *const *argv, DeeObject *kw)
PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
seq_sort(DeeObject *self, size_t argc,
DeeObject *const *argv, DeeObject *kw) {
- DeeObject *key = NULL;
+ DREF DeeObject *sorted;
+ DeeObject *key = Dee_None;
if (DeeArg_UnpackKw(argc, argv, kw, kwlist__key, "|o:sort", &key))
goto err;
- if (DeeNone_Check(key))
- key = NULL;
- if (DeeSeq_Sort(self, key))
+ sorted = DeeList_FromSequence(self);
+ if unlikely(!sorted)
goto err;
+ if unlikely(DeeList_Sort(sorted, 0, (size_t)-1, key))
+ goto err_sorted;
+ if unlikely(DeeObject_Assign(self, sorted))
+ goto err_sorted;
+ Dee_Decref(sorted);
return_none;
+err_sorted:
+ Dee_Decref(sorted);
err:
return NULL;
}
diff --git a/src/deemon/objects/seq/default-api-mutable-require-impl.c.inl b/src/deemon/objects/seq/default-api-mutable-require-impl.c.inl
index 469f0f42f..db694f6bc 100644
--- a/src/deemon/objects/seq/default-api-mutable-require-impl.c.inl
+++ b/src/deemon/objects/seq/default-api-mutable-require-impl.c.inl
@@ -274,7 +274,7 @@ DECL_BEGIN
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataFunction DeeSeq_DefaultReversedWithCallReversedDataFunction
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataMethod DeeSeq_DefaultReversedWithCallReversedDataMethod
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataKwMethod DeeSeq_DefaultReversedWithCallReversedDataKwMethod
-#define LOCAL_DeeSeq_DefaultFooWithError DeeSeq_DefaultReversedWithProxyCopyDefault
+#define LOCAL_DeeSeq_DefaultFooWithError DeeSeq_DefaultReversedWithCopyForeachDefault
#elif defined(DEFINE_DeeType_SeqCache_RequireSort)
#define LOCAL_CANONICAL_NAME sort
#define LOCAL_generic_seq_foo generic_seq_sort
@@ -304,7 +304,7 @@ DECL_BEGIN
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataFunction DeeSeq_DefaultSortedWithCallSortedDataFunction
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataMethod DeeSeq_DefaultSortedWithCallSortedDataMethod
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataKwMethod DeeSeq_DefaultSortedWithCallSortedDataKwMethod
-#define LOCAL_DeeSeq_DefaultFooWithError DeeSeq_DefaultSortedWithEnumerateDefaultAndCopy
+#define LOCAL_DeeSeq_DefaultFooWithError DeeSeq_DefaultSortedWithCopyForeachDefault
#elif defined(DEFINE_DeeType_SeqCache_RequireSortedWithKey)
#define LOCAL_CANONICAL_NAME sorted
#define LOCAL_generic_seq_foo generic_seq_sorted
@@ -314,7 +314,7 @@ DECL_BEGIN
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataFunction DeeSeq_DefaultSortedWithKeyWithCallSortedDataFunction
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataMethod DeeSeq_DefaultSortedWithKeyWithCallSortedDataMethod
#define LOCAL_DeeSeq_DefaultFooWithCallFooDataKwMethod DeeSeq_DefaultSortedWithKeyWithCallSortedDataKwMethod
-#define LOCAL_DeeSeq_DefaultFooWithError DeeSeq_DefaultSortedWithKeyWithEnumerateDefaultAndCopy
+#define LOCAL_DeeSeq_DefaultFooWithError DeeSeq_DefaultSortedWithKeyWithCopyForeachDefault
#else /* DEFINE_DeeType_SeqCache_Require... */
#error "Invalid configuration"
#endif /* !DEFINE_DeeType_SeqCache_Require... */
@@ -656,7 +656,7 @@ LOCAL_DeeType_SeqCache_RequireFoo_private_uncached(DeeTypeObject *orig_type, Dee
return &DeeSeq_DefaultReversedWithProxySizeAndGetItemIndex;
}
if (DeeType_HasPrivateOperator(self, OPERATOR_ITER))
- return &DeeSeq_DefaultReversedWithProxyCopyDefault; /* non-Default would also be OK */
+ return &DeeSeq_DefaultReversedWithCopyForeachDefault; /* non-Default would also be OK */
#elif defined(DEFINE_DeeType_SeqCache_RequireSort)
if (DeeType_HasPrivateOperator(self, OPERATOR_SETRANGE))
return &DeeSeq_DefaultSortWithTSCSortedAndSetRangeIndex;
@@ -674,11 +674,25 @@ LOCAL_DeeType_SeqCache_RequireFoo_private_uncached(DeeTypeObject *orig_type, Dee
DeeType_HasOperator(orig_type, OPERATOR_SIZE))
return &DeeSeq_DefaultSortWithKeyWithSizeAndGetItemIndexAndSetItemIndex;
#elif defined(DEFINE_DeeType_SeqCache_RequireSorted)
+ if (DeeType_GetSeqClass(self) == Dee_SEQCLASS_SEQ &&
+ DeeType_HasPrivateOperator(self, OPERATOR_GETITEM) &&
+ DeeType_HasOperator(orig_type, OPERATOR_SIZE)) {
+ if (orig_type->tp_seq->tp_getitem_index_fast)
+ return &DeeSeq_DefaultSortedWithCopySizeAndGetItemIndexFast;
+ return &DeeSeq_DefaultSortedWithCopySizeAndTryGetItemIndex;
+ }
if (DeeType_HasPrivateOperator(self, OPERATOR_ITER))
- return &DeeSeq_DefaultSortedWithEnumerateDefaultAndCopy; /* non-Default would also be OK */
+ return &DeeSeq_DefaultSortedWithCopyForeachDefault; /* non-Default would also be OK */
#elif defined(DEFINE_DeeType_SeqCache_RequireSortedWithKey)
+ if (DeeType_GetSeqClass(self) == Dee_SEQCLASS_SEQ &&
+ DeeType_HasPrivateOperator(self, OPERATOR_GETITEM) &&
+ DeeType_HasOperator(orig_type, OPERATOR_SIZE)) {
+ if (orig_type->tp_seq->tp_getitem_index_fast)
+ return &DeeSeq_DefaultSortedWithKeyWithCopySizeAndGetItemIndexFast;
+ return &DeeSeq_DefaultSortedWithKeyWithCopySizeAndTryGetItemIndex;
+ }
if (DeeType_HasPrivateOperator(self, OPERATOR_ITER))
- return &DeeSeq_DefaultSortedWithKeyWithEnumerateDefaultAndCopy; /* non-Default would also be OK */
+ return &DeeSeq_DefaultSortedWithKeyWithCopyForeachDefault; /* non-Default would also be OK */
#endif /* ... */
return NULL;
}
diff --git a/src/deemon/objects/seq/default-api-mutable.c b/src/deemon/objects/seq/default-api-mutable.c
index ecd9b7c69..8e301885f 100644
--- a/src/deemon/objects/seq/default-api-mutable.c
+++ b/src/deemon/objects/seq/default-api-mutable.c
@@ -45,6 +45,7 @@
/**/
#include "default-reversed.h"
#include "repeat.h"
+#include "sort.h"
/**/
#include "../../runtime/kwlist.h"
@@ -1685,7 +1686,7 @@ DeeSeq_DefaultReversedWithProxySizeAndGetItemIndexFast(DeeObject *self, size_t s
goto err;
if (end > selfsize)
end = selfsize;
- if (start > end)
+ if unlikely(start > end)
start = end;
result = DeeObject_MALLOC(DefaultReversed_WithGetItemIndex);
if unlikely(!result)
@@ -1710,7 +1711,7 @@ DeeSeq_DefaultReversedWithProxySizeAndGetItemIndex(DeeObject *self, size_t start
goto err;
if (end > selfsize)
end = selfsize;
- if (start > end)
+ if unlikely(start > end)
start = end;
result = DeeObject_MALLOC(DefaultReversed_WithGetItemIndex);
if unlikely(!result)
@@ -1735,7 +1736,7 @@ DeeSeq_DefaultReversedWithProxySizeAndTryGetItemIndex(DeeObject *self, size_t st
goto err;
if (end > selfsize)
end = selfsize;
- if (start > end)
+ if unlikely(start > end)
start = end;
result = DeeObject_MALLOC(DefaultReversed_WithGetItemIndex);
if unlikely(!result)
@@ -1751,16 +1752,95 @@ DeeSeq_DefaultReversedWithProxySizeAndTryGetItemIndex(DeeObject *self, size_t st
return NULL;
}
-INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL
-DeeSeq_DefaultReversedWithProxyCopyDefault(DeeObject *self, size_t start, size_t end) {
- /* TODO */
- (void)self;
- (void)start;
- (void)end;
- DeeError_NOTIMPLEMENTED();
+struct foreach_subrange_as_tuple_data {
+ DREF DeeTupleObject *fesrat_result; /* [1..1] The tuple being constructed. */
+ size_t fesrat_used; /* Used # of elements of `fesrat_result' */
+ size_t fesrat_maxsize; /* Max value for `fesrat_used' */
+ size_t fesrat_start; /* # of elements that still need to be skipped. */
+};
+
+PRIVATE WUNUSED NONNULL((1, 2)) Dee_ssize_t DCALL
+foreach_subrange_as_tuple_cb(void *arg, DeeObject *elem) {
+ struct foreach_subrange_as_tuple_data *data;
+ data = (struct foreach_subrange_as_tuple_data *)arg;
+ if (data->fesrat_start) {
+ --data->fesrat_start; /* Skip leading. */
+ return 0;
+ }
+ if (data->fesrat_used >= DeeTuple_SIZE(data->fesrat_result)) {
+ DREF DeeTupleObject *new_tuple;
+ size_t new_size = DeeTuple_SIZE(data->fesrat_result) * 2;
+ if (new_size < 16)
+ new_size = 16;
+ new_tuple = DeeTuple_TryResizeUninitialized(data->fesrat_result, new_size);
+ if unlikely(!new_tuple) {
+ new_size = data->fesrat_used + 1;
+ new_tuple = DeeTuple_ResizeUninitialized(data->fesrat_result, new_size);
+ if unlikely(!new_tuple)
+ goto err;
+ }
+ data->fesrat_result = new_tuple;
+ }
+ Dee_Incref(elem);
+ data->fesrat_result->t_elem[data->fesrat_used++] = elem;
+ if (data->fesrat_used >= data->fesrat_maxsize)
+ return -2; /* Stop enumeration */
+ return 0;
+err:
+ return -1;
+}
+
+
+PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
+DeeSeq_GetForeachSubRangeAsTuple(DeeObject *self, size_t start, size_t end) {
+ size_t fast_size;
+ Dee_ssize_t foreach_status;
+ struct foreach_subrange_as_tuple_data data;
+ if unlikely(start >= end)
+ return_empty_tuple;
+ fast_size = (*Dee_TYPE(self)->tp_seq->tp_size_fast)(self);
+ if (fast_size != (size_t)-1) {
+ data.fesrat_result = DeeTuple_NewUninitialized(fast_size);
+ if unlikely(!data.fesrat_result)
+ goto err;
+ } else {
+ Dee_Incref(Dee_EmptyTuple);
+ data.fesrat_result = (DREF DeeTupleObject *)Dee_EmptyTuple;
+ }
+ data.fesrat_used = 0;
+ data.fesrat_maxsize = end - start;
+ data.fesrat_start = start;
+ foreach_status = (*Dee_TYPE(self)->tp_seq->tp_foreach)(self, &foreach_subrange_as_tuple_cb, &data);
+ ASSERT(foreach_status == 0 || foreach_status == -1);
+ if unlikely(foreach_status < 0)
+ goto err_r;
+ data.fesrat_result = DeeTuple_TruncateUninitialized(data.fesrat_result, data.fesrat_used);
+ return (DREF DeeObject *)data.fesrat_result;
+err_r:
+ Dee_Decrefv(data.fesrat_result->t_elem, data.fesrat_used);
+ DeeTuple_FreeUninitialized(data.fesrat_result);
+err:
return NULL;
}
+INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL
+DeeSeq_DefaultReversedWithCopyForeachDefault(DeeObject *self, size_t start, size_t end) {
+ DREF DeeObject *result;
+ result = DeeSeq_GetForeachSubRangeAsTuple(self, start, end);
+ if likely(result) {
+ DREF DeeObject **lo, **hi;
+ lo = DeeTuple_ELEM(result);
+ hi = lo + DeeTuple_SIZE(result);
+ while (lo < hi) {
+ DeeObject *temp;
+ temp = *lo;
+ *lo++ = *--hi;
+ *hi = temp;
+ }
+ }
+ return result;
+}
+
/************************************************************************/
/* sort() */
@@ -1832,13 +1912,80 @@ DeeSeq_DefaultSortWithKeyWithError(DeeObject *self, size_t start, size_t end, De
/************************************************************************/
/* sorted() */
/************************************************************************/
+INTERN WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL
+DeeSeq_DefaultSortedWithCopySizeAndGetItemIndexFast(DeeObject *self, size_t start, size_t end) {
+ size_t selfsize;
+ DREF DeeTupleObject *result;
+ struct type_seq *seq = Dee_TYPE(self)->tp_seq;
+ selfsize = (*seq->tp_size)(self);
+ if unlikely(selfsize == (size_t)-1)
+ goto err;
+ if (end > selfsize)
+ end = selfsize;
+ if unlikely(start > end)
+ start = end;
+ result = DeeTuple_NewUninitialized(end - start);
+ if unlikely(!result)
+ goto err;
+ if unlikely(DeeSeq_SortGetItemIndexFast(DeeTuple_SIZE(result), DeeTuple_ELEM(result),
+ self, start, seq->tp_getitem_index_fast))
+ goto err_r;
+ if unlikely(DeeTuple_GET(result, 0) == NULL) {
+ /* Must trim unbound items (which were sorted to the start of the tuple) */
+
+ }
+ return (DREF DeeObject *)result;
+err_r:
+ DeeTuple_FreeUninitialized(result);
+err:
+ return NULL;
+}
+
+INTERN WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL
+DeeSeq_DefaultSortedWithCopySizeAndTryGetItemIndex(DeeObject *self, size_t start, size_t end) {
+ size_t selfsize;
+ DREF DeeTupleObject *result;
+ struct type_seq *seq = Dee_TYPE(self)->tp_seq;
+ selfsize = (*seq->tp_size)(self);
+ if unlikely(selfsize == (size_t)-1)
+ goto err;
+ if (end > selfsize)
+ end = selfsize;
+ if unlikely(start > end)
+ start = end;
+ result = DeeTuple_NewUninitialized(end - start);
+ if unlikely(!result)
+ goto err;
+ if unlikely(DeeSeq_SortTryGetItemIndex(DeeTuple_SIZE(result), DeeTuple_ELEM(result),
+ self, start, seq->tp_trygetitem_index))
+ goto err_r;
+ return (DREF DeeObject *)result;
+err_r:
+ DeeTuple_FreeUninitialized(result);
+err:
+ return NULL;
+}
+
INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL
-DeeSeq_DefaultSortedWithEnumerateDefaultAndCopy(DeeObject *self, size_t start, size_t end) {
- /* TODO */
- (void)self;
- (void)start;
- (void)end;
- DeeError_NOTIMPLEMENTED();
+DeeSeq_DefaultSortedWithCopyForeachDefault(DeeObject *self, size_t start, size_t end) {
+ DREF DeeTupleObject *base, *result;
+ base = (DREF DeeTupleObject *)DeeSeq_GetForeachSubRangeAsTuple(self, start, end);
+ if unlikely(!base)
+ goto err;
+ result = DeeTuple_NewUninitialized(DeeTuple_SIZE(base));
+ if unlikely(!result)
+ goto err_base;
+ if unlikely(DeeSeq_SortVector(DeeTuple_SIZE(result),
+ DeeTuple_ELEM(result),
+ DeeTuple_ELEM(base)))
+ goto err_base_r;
+ DeeTuple_FreeUninitialized(base);
+ return (DREF DeeObject *)result;
+err_base_r:
+ DeeTuple_FreeUninitialized(result);
+err_base:
+ Dee_Decref(base);
+err:
return NULL;
}
@@ -1847,13 +1994,76 @@ DeeSeq_DefaultSortedWithEnumerateDefaultAndCopy(DeeObject *self, size_t start, s
/* sorted() (with key) */
/************************************************************************/
INTERN WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL
-DeeSeq_DefaultSortedWithKeyWithEnumerateDefaultAndCopy(DeeObject *self, size_t start, size_t end, DeeObject *key) {
- /* TODO */
- (void)self;
- (void)start;
- (void)end;
- (void)key;
- DeeError_NOTIMPLEMENTED();
+DeeSeq_DefaultSortedWithKeyWithCopySizeAndGetItemIndexFast(DeeObject *self, size_t start, size_t end, DeeObject *key) {
+ size_t selfsize;
+ DREF DeeTupleObject *result;
+ struct type_seq *seq = Dee_TYPE(self)->tp_seq;
+ selfsize = (*seq->tp_size)(self);
+ if unlikely(selfsize == (size_t)-1)
+ goto err;
+ if (end > selfsize)
+ end = selfsize;
+ if unlikely(start > end)
+ start = end;
+ result = DeeTuple_NewUninitialized(end - start);
+ if unlikely(!result)
+ goto err;
+ if unlikely(DeeSeq_SortGetItemIndexFastWithKey(DeeTuple_SIZE(result), DeeTuple_ELEM(result),
+ self, start, seq->tp_getitem_index_fast, key))
+ goto err_r;
+ return (DREF DeeObject *)result;
+err_r:
+ DeeTuple_FreeUninitialized(result);
+err:
+ return NULL;
+}
+
+INTERN WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL
+DeeSeq_DefaultSortedWithKeyWithCopySizeAndTryGetItemIndex(DeeObject *self, size_t start, size_t end, DeeObject *key) {
+ size_t selfsize;
+ DREF DeeTupleObject *result;
+ struct type_seq *seq = Dee_TYPE(self)->tp_seq;
+ selfsize = (*seq->tp_size)(self);
+ if unlikely(selfsize == (size_t)-1)
+ goto err;
+ if (end > selfsize)
+ end = selfsize;
+ if unlikely(start > end)
+ start = end;
+ result = DeeTuple_NewUninitialized(end - start);
+ if unlikely(!result)
+ goto err;
+ if unlikely(DeeSeq_SortTryGetItemIndexWithKey(DeeTuple_SIZE(result), DeeTuple_ELEM(result),
+ self, start, seq->tp_trygetitem_index, key))
+ goto err_r;
+ return (DREF DeeObject *)result;
+err_r:
+ DeeTuple_FreeUninitialized(result);
+err:
+ return NULL;
+}
+
+INTERN WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL
+DeeSeq_DefaultSortedWithKeyWithCopyForeachDefault(DeeObject *self, size_t start, size_t end, DeeObject *key) {
+ DREF DeeObject *base;
+ DREF DeeTupleObject *result;
+ base = DeeSeq_GetForeachSubRangeAsTuple(self, start, end);
+ if unlikely(!base)
+ goto err;
+ result = DeeTuple_NewUninitialized(DeeTuple_SIZE(base));
+ if unlikely(!result)
+ goto err_base;
+ if unlikely(DeeSeq_SortVectorWithKey(DeeTuple_SIZE(result),
+ DeeTuple_ELEM(result),
+ DeeTuple_ELEM(base),
+ key))
+ goto err_base_r;
+ return (DREF DeeObject *)result;
+err_base_r:
+ DeeTuple_FreeUninitialized(result);
+err_base:
+ Dee_Decref(base);
+err:
return NULL;
}
diff --git a/src/deemon/objects/seq/default-api.h b/src/deemon/objects/seq/default-api.h
index 6f7db2e33..000daf0c4 100644
--- a/src/deemon/objects/seq/default-api.h
+++ b/src/deemon/objects/seq/default-api.h
@@ -521,7 +521,7 @@ INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultReversedWithCall
INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultReversedWithProxySizeAndGetItemIndexFast(DeeObject *self, size_t start, size_t end);
INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultReversedWithProxySizeAndGetItemIndex(DeeObject *self, size_t start, size_t end);
INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultReversedWithProxySizeAndTryGetItemIndex(DeeObject *self, size_t start, size_t end);
-INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultReversedWithProxyCopyDefault(DeeObject *self, size_t start, size_t end);
+INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultReversedWithCopyForeachDefault(DeeObject *self, size_t start, size_t end);
INTDEF WUNUSED NONNULL((1)) int DCALL DeeSeq_DefaultSortWithCallAttrSort(DeeObject *self, size_t start, size_t end);
INTDEF WUNUSED NONNULL((1)) int DCALL DeeSeq_DefaultSortWithCallSortDataFunction(DeeObject *self, size_t start, size_t end);
@@ -543,13 +543,17 @@ INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithCallAt
INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithCallSortedDataFunction(DeeObject *self, size_t start, size_t end);
INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithCallSortedDataMethod(DeeObject *self, size_t start, size_t end);
INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithCallSortedDataKwMethod(DeeObject *self, size_t start, size_t end);
-INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithProxyCopyDefault(DeeObject *self, size_t start, size_t end);
+INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithCopySizeAndGetItemIndexFast(DeeObject *self, size_t start, size_t end);
+INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithCopySizeAndTryGetItemIndex(DeeObject *self, size_t start, size_t end);
+INTDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithCopyForeachDefault(DeeObject *self, size_t start, size_t end);
INTDEF WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithKeyWithCallAttrSorted(DeeObject *self, size_t start, size_t end, DeeObject *key);
INTDEF WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithKeyWithCallSortedDataFunction(DeeObject *self, size_t start, size_t end, DeeObject *key);
INTDEF WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithKeyWithCallSortedDataMethod(DeeObject *self, size_t start, size_t end, DeeObject *key);
INTDEF WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithKeyWithCallSortedDataKwMethod(DeeObject *self, size_t start, size_t end, DeeObject *key);
-INTDEF WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithKeyWithProxyCopyDefault(DeeObject *self, size_t start, size_t end, DeeObject *key);
+INTDEF WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithKeyWithCopySizeAndGetItemIndexFast(DeeObject *self, size_t start, size_t end, DeeObject *key);
+INTDEF WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithKeyWithCopySizeAndTryGetItemIndex(DeeObject *self, size_t start, size_t end, DeeObject *key);
+INTDEF WUNUSED NONNULL((1, 4)) DREF DeeObject *DCALL DeeSeq_DefaultSortedWithKeyWithCopyForeachDefault(DeeObject *self, size_t start, size_t end, DeeObject *key);
diff --git a/src/deemon/objects/seq/sort-impl.c.inl b/src/deemon/objects/seq/sort-impl.c.inl
new file mode 100644
index 000000000..afbccf247
--- /dev/null
+++ b/src/deemon/objects/seq/sort-impl.c.inl
@@ -0,0 +1,593 @@
+/* Copyright (c) 2018-2024 Griefer@Work *
+ * *
+ * This software is provided 'as-is', without any express or implied *
+ * warranty. In no event will the authors be held liable for any damages *
+ * arising from the use of this software. *
+ * *
+ * Permission is granted to anyone to use this software for any purpose, *
+ * including commercial applications, and to alter it and redistribute it *
+ * freely, subject to the following restrictions: *
+ * *
+ * 1. The origin of this software must not be misrepresented; you must not *
+ * claim that you wrote the original software. If you use this software *
+ * in a product, an acknowledgement (see the following) in the product *
+ * documentation is required: *
+ * Portions Copyright (c) 2018-2024 Griefer@Work *
+ * 2. Altered source versions must be plainly marked as such, and must not be *
+ * misrepresented as being the original software. *
+ * 3. This notice may not be removed or altered from any source distribution. *
+ */
+#ifdef __INTELLISENSE__
+#include "sort.c"
+//#define DEFINE_DeeSeq_SortVector
+#define DEFINE_DeeSeq_SortVectorWithKey
+//#define DEFINE_DeeSeq_SortGetItemIndexFast
+//#define DEFINE_DeeSeq_SortGetItemIndexFastWithKey
+//#define DEFINE_DeeSeq_SortTryGetItemIndex
+//#define DEFINE_DeeSeq_SortTryGetItemIndexWithKey
+#endif /* __INTELLISENSE__ */
+
+#if (defined(DEFINE_DeeSeq_SortVector) + \
+ defined(DEFINE_DeeSeq_SortVectorWithKey) + \
+ defined(DEFINE_DeeSeq_SortGetItemIndexFast) + \
+ defined(DEFINE_DeeSeq_SortGetItemIndexFastWithKey) + \
+ defined(DEFINE_DeeSeq_SortTryGetItemIndex) + \
+ defined(DEFINE_DeeSeq_SortTryGetItemIndexWithKey)) != 1
+#error "Must #define exactly one of these macros"
+#endif /* DEFINE_DeeSeq_Sort... */
+
+DECL_BEGIN
+
+#ifdef DEFINE_DeeSeq_SortVector
+#define LOCAL_DeeSeq_Sort DeeSeq_SortVector
+#define LOCAL_HAS_VECTOR
+#elif defined(DEFINE_DeeSeq_SortVectorWithKey)
+#define LOCAL_DeeSeq_Sort DeeSeq_SortVectorWithKey
+#define LOCAL_HAS_VECTOR
+#define LOCAL_HAS_KEY
+#elif defined(DEFINE_DeeSeq_SortGetItemIndexFast)
+#define LOCAL_DeeSeq_Sort DeeSeq_SortGetItemIndexFast
+#define LOCAL_HAS_GETITEM
+#define LOCAL_HAS_GETITEM_FAST
+#elif defined(DEFINE_DeeSeq_SortGetItemIndexFastWithKey)
+#define LOCAL_DeeSeq_Sort DeeSeq_SortGetItemIndexFastWithKey
+#define LOCAL_HAS_GETITEM
+#define LOCAL_HAS_GETITEM_FAST
+#define LOCAL_HAS_KEY
+#elif defined(DEFINE_DeeSeq_SortTryGetItemIndex)
+#define LOCAL_DeeSeq_Sort DeeSeq_SortTryGetItemIndex
+#define LOCAL_HAS_GETITEM
+#elif defined(DEFINE_DeeSeq_SortTryGetItemIndexWithKey)
+#define LOCAL_DeeSeq_Sort DeeSeq_SortTryGetItemIndexWithKey
+#define LOCAL_HAS_GETITEM
+#define LOCAL_HAS_KEY
+#else /* DEFINE_DeeSeq_Sort... */
+#error "Invalid configuration"
+#endif /* !DEFINE_DeeSeq_Sort... */
+
+#define F(x) PP_CAT3(LOCAL_DeeSeq_Sort, _impl__, x)
+
+#define LOCAL_mergesort_impl F(mergesort_impl)
+#define LOCAL_mergesort_impl_with_key_cache F(mergesort_impl_with_key_cache)
+#define LOCAL_insertsort_impl F(insertsort_impl)
+
+#ifdef LOCAL_HAS_KEY
+#define LOCAL__PARAM_KEY , DeeObject *key
+#define LOCAL__ARG_KEY , key
+#define LOCAL_DeeObject_CmpLoAsBool(lhs, rhs) \
+ DeeObject_CmpLoAsBoolWithKey(lhs, rhs, key)
+#ifndef DeeObject_CmpLoAsBoolWithKey_DEFINED
+#define DeeObject_CmpLoAsBoolWithKey_DEFINED
+PRIVATE WUNUSED NONNULL((1, 2, 3)) int DCALL
+DeeObject_CmpLoAsBoolWithKey(DeeObject *lhs, DeeObject *rhs, DeeObject *key) {
+ int result;
+ lhs = DeeObject_Call(key, 1, (DeeObject **)&lhs);
+ if unlikely(!lhs)
+ goto err;
+ rhs = DeeObject_Call(key, 1, (DeeObject **)&rhs);
+ if unlikely(!rhs)
+ goto err_lhs;
+ result = DeeObject_CmpLoAsBool(lhs, rhs);
+ Dee_Decref(rhs);
+ Dee_Decref(lhs);
+ return result;
+err_lhs:
+ Dee_Decref(lhs);
+err:
+ return -1;
+}
+#endif /* !DeeObject_CmpLoAsBoolWithKey_DEFINED */
+#else /* LOCAL_HAS_KEY */
+#define LOCAL__PARAM_KEY /* nothing */
+#define LOCAL__ARG_KEY /* nothing */
+#define LOCAL_DeeObject_CmpLoAsBool(lhs, rhs) \
+ DeeObject_CmpLoAsBool(lhs, rhs)
+#endif /* !LOCAL_HAS_KEY */
+
+
+#ifdef LOCAL_HAS_GETITEM_FAST
+#define LOCAL_PARAM_SRC DeeObject *src, size_t src_start, DREF DeeObject *(DCALL *src_getitem_index_fast)(DeeObject *__restrict self, size_t index)
+#define LOCAL_ARG_SRC(skip) src, src_start + (skip), src_getitem_index_fast
+#define LOCAL_GETITEM(i) (*src_getitem_index_fast)(src, src_start + (i))
+#define LOCAL_GETITEM_UNBOUND NULL
+#define LOCAL_GETITEM_ISREF
+#elif defined(LOCAL_HAS_GETITEM)
+#define LOCAL_PARAM_SRC DeeObject *src, size_t src_start, DREF DeeObject *(DCALL *src_trygetitem_index)(DeeObject *__restrict self, size_t index)
+#define LOCAL_ARG_SRC(skip) src, src_start + (skip), src_trygetitem_index
+#define LOCAL_GETITEM(i) (*src_trygetitem_index)(src, src_start + (i))
+#define LOCAL_GETITEM_UNBOUND ITER_DONE
+#define LOCAL_GETITEM_ERROR NULL
+#define LOCAL_GETITEM_ISREF
+#elif defined(LOCAL_HAS_VECTOR)
+#define LOCAL_PARAM_SRC /*inherit(on_success)*/ DREF DeeObject *const *__restrict src
+#define LOCAL_ARG_SRC(skip) src + (skip)
+#define LOCAL_GETITEM(i) src[i]
+#else /* ... */
+#error "Invalid configuration"
+#endif /* !... */
+
+
+#ifdef LOCAL_GETITEM_ISREF
+#define LOCAL_IF_GETITEM_ISREF(...) __VA_ARGS__
+#else /* LOCAL_GETITEM_ISREF */
+#define LOCAL_IF_GETITEM_ISREF(...) /* nothing */
+#endif /* !LOCAL_GETITEM_ISREF */
+
+#ifdef LOCAL_GETITEM_UNBOUND
+#define LOCAL_DecrefIfNotUnbound(x) \
+ do { \
+ if ((x) != LOCAL_GETITEM_UNBOUND) \
+ Dee_Decref(x); \
+ } __WHILE0
+#define LOCAL_DecrefvIfNotUnbound(v, s) \
+ do { \
+ size_t _i; \
+ for (_i = 0; _i < (s); ++_i) { \
+ DeeObject *_o = (v)[_i]; \
+ if (_o != LOCAL_GETITEM_UNBOUND) \
+ Dee_Decref(_o); \
+ } \
+ } __WHILE0
+#else /* LOCAL_GETITEM_UNBOUND */
+#define LOCAL_DecrefIfNotUnbound(x) Dee_Decref(x)
+#define LOCAL_DecrefvIfNotUnbound(v, s) Dee_Decrefv(v, s)
+#endif /* !LOCAL_GETITEM_UNBOUND */
+
+
+PRIVATE WUNUSED ATTR_OUTS(2, 1) int DCALL
+LOCAL_mergesort_impl(size_t objc, DREF DeeObject **__restrict dst,
+ DeeObject **__restrict scratch, /* Scratch buffer area */
+ LOCAL_PARAM_SRC LOCAL__PARAM_KEY) {
+ int error;
+ switch (objc) {
+
+ case 1: {
+ DREF DeeObject *src0;
+ src0 = LOCAL_GETITEM(0);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src0 == LOCAL_GETITEM_ERROR)
+ goto err;
+#endif /* LOCAL_GETITEM_ERROR */
+ dst[0] = src0;
+ } break;
+
+ case 2: { /* Optimization for sorting 2 objects. */
+ int src0_lo_src1;
+ DREF DeeObject *src0, *src1;
+ src0 = LOCAL_GETITEM(0);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src0 == LOCAL_GETITEM_ERROR)
+ goto err;
+#endif /* LOCAL_GETITEM_ERROR */
+ src1 = LOCAL_GETITEM(1);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src1 == LOCAL_GETITEM_ERROR) {
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefIfNotUnbound(src0));
+ goto err;
+ }
+#endif /* LOCAL_GETITEM_ERROR */
+#ifdef LOCAL_GETITEM_UNBOUND
+ if (src0 == LOCAL_GETITEM_UNBOUND) {
+ src0_lo_src1 = src1 == LOCAL_GETITEM_UNBOUND ? 0 : 1;
+ } else if (src1 == LOCAL_GETITEM_UNBOUND) {
+ src0_lo_src1 = 0;
+ } else
+#endif /* LOCAL_GETITEM_UNBOUND */
+ {
+ src0_lo_src1 = LOCAL_DeeObject_CmpLoAsBool(src0, src1);
+ }
+ if (src0_lo_src1 <= 0) {
+ if unlikely(src0_lo_src1 < 0)
+ goto err;
+ dst[0] = src1; /* Inherit reference */
+ dst[1] = src0; /* Inherit reference */
+ } else {
+ dst[0] = src0; /* Inherit reference */
+ dst[1] = src1; /* Inherit reference */
+ }
+ } break;
+
+ default: {
+ size_t s1, s2;
+ DREF DeeObject **iter1;
+ DREF DeeObject **iter2;
+ s1 = objc / 2;
+ s2 = objc - s1;
+ error = LOCAL_mergesort_impl(s1, scratch, dst, LOCAL_ARG_SRC(0) LOCAL__ARG_KEY);
+ if unlikely(error < 0)
+ goto err;
+ error = LOCAL_mergesort_impl(s2, scratch + s1, dst + s1, LOCAL_ARG_SRC(s1) LOCAL__ARG_KEY);
+ if unlikely(error < 0) {
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefvIfNotUnbound(scratch, s1));
+ goto err;
+ }
+ iter1 = scratch;
+ iter2 = scratch + s1;
+ while (s1 && s2) {
+ DREF DeeObject *iter1_value = *iter1;
+ DREF DeeObject *iter2_value = *iter2;
+#ifdef LOCAL_GETITEM_UNBOUND
+ if (iter1_value == LOCAL_GETITEM_UNBOUND) {
+ error = iter2_value == LOCAL_GETITEM_UNBOUND ? 0 : 1;
+ } else if (iter2_value == LOCAL_GETITEM_UNBOUND) {
+ error = 0;
+ } else
+#endif /* LOCAL_GETITEM_UNBOUND */
+ {
+ error = LOCAL_DeeObject_CmpLoAsBool(iter1_value, iter2_value);
+ }
+ if (error <= 0) {
+ if unlikely(error < 0) {
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefvIfNotUnbound(scratch, objc));
+ goto err;
+ }
+ *dst = iter2_value;
+ ++iter2;
+ --s2;
+ } else {
+ *dst = iter1_value;
+ ++iter1;
+ --s1;
+ }
+ ++dst;
+ }
+ if (s1) {
+ ASSERT(!s2);
+ memcpyc(dst, iter1, s1, sizeof(DREF DeeObject *));
+ } else if (s2) {
+ memcpyc(dst, iter2, s2, sizeof(DREF DeeObject *));
+ }
+ } break;
+
+ }
+ return 0;
+err:
+ return -1;
+}
+
+#ifdef LOCAL_HAS_KEY
+PRIVATE WUNUSED ATTR_OUTS(2, 1) ATTR_OUTS(3, 1) int DCALL
+LOCAL_mergesort_impl_with_key_cache(size_t objc,
+ DREF DeeObject **__restrict dst,
+ DREF DeeObject **__restrict dst_keyed,
+ DeeObject **__restrict scratch, /* Scratch buffer area */
+ DeeObject **__restrict scratch_keyed, /* Scratch buffer area */
+ LOCAL_PARAM_SRC LOCAL__PARAM_KEY) {
+ int error;
+ switch (objc) {
+
+ case 1: {
+ DREF DeeObject *src0;
+ src0 = LOCAL_GETITEM(0);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src0 == LOCAL_GETITEM_ERROR)
+ goto err;
+#endif /* LOCAL_GETITEM_ERROR */
+ dst[0] = src0;
+#ifdef LOCAL_GETITEM_UNBOUND
+ if (src0 == LOCAL_GETITEM_UNBOUND) {
+ dst_keyed[0] = LOCAL_GETITEM_UNBOUND;
+ } else
+#endif /* LOCAL_GETITEM_UNBOUND */
+ {
+ dst_keyed[0] = DeeObject_Call(key, 1, &dst[0]);
+ if unlikely(!dst_keyed[0]) {
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefIfNotUnbound(dst[0]));
+ goto err;
+ }
+ }
+ } break;
+
+ case 2: { /* Optimization for sorting 2 objects. */
+ int src0_lo_src1;
+ DREF DeeObject *src0, *src1;
+ DREF DeeObject *src0_keyed, *src1_keyed;
+ src0 = LOCAL_GETITEM(0);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src0 == LOCAL_GETITEM_ERROR)
+ goto err;
+#endif /* LOCAL_GETITEM_ERROR */
+ src1 = LOCAL_GETITEM(1);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src1 == LOCAL_GETITEM_ERROR)
+ goto err_src0;
+#endif /* LOCAL_GETITEM_ERROR */
+#ifdef LOCAL_GETITEM_UNBOUND
+ if (src0 == LOCAL_GETITEM_UNBOUND) {
+ src0_keyed = LOCAL_GETITEM_UNBOUND;
+ if (src1 == LOCAL_GETITEM_UNBOUND) {
+ src0_lo_src1 = 0;
+ src1_keyed = LOCAL_GETITEM_UNBOUND;
+ } else {
+ src0_lo_src1 = 1;
+ src1_keyed = DeeObject_Call(key, 1, &src1);
+ if unlikely(!src1_keyed)
+ goto err_src0_src1;
+ }
+ } else if (src1 == LOCAL_GETITEM_UNBOUND) {
+ src0_lo_src1 = 0;
+ src0_keyed = DeeObject_Call(key, 1, &src0);
+ if unlikely(!src0_keyed)
+ goto err_src0_src1;
+ src1_keyed = LOCAL_GETITEM_UNBOUND;
+ } else
+#endif /* LOCAL_GETITEM_UNBOUND */
+ {
+ src0_keyed = DeeObject_Call(key, 1, &src0);
+ if unlikely(!src0_keyed)
+ goto err_src0_src1;
+ src1_keyed = DeeObject_Call(key, 1, &src1);
+ if unlikely(!src1_keyed) {
+ Dee_Decref(src0_keyed);
+err_src0_src1:
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefIfNotUnbound(src1));
+#ifdef LOCAL_GETITEM_ERROR
+err_src0:
+#endif /* LOCAL_GETITEM_ERROR */
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefIfNotUnbound(src0));
+ goto err;
+ }
+ src0_lo_src1 = DeeObject_CmpLoAsBool(src0_keyed, src1_keyed);
+ }
+ if (src0_lo_src1 <= 0) {
+ if unlikely(src0_lo_src1 < 0)
+ goto err;
+ dst[0] = src1; /* Inherit reference */
+ dst[1] = src0; /* Inherit reference */
+ dst_keyed[0] = src1_keyed; /* Inherit reference */
+ dst_keyed[1] = src0_keyed; /* Inherit reference */
+ } else {
+ dst[0] = src0; /* Inherit reference */
+ dst[1] = src1; /* Inherit reference */
+ dst_keyed[0] = src0_keyed; /* Inherit reference */
+ dst_keyed[1] = src1_keyed; /* Inherit reference */
+ }
+ } break;
+
+ default: {
+ size_t s1, s2;
+ DREF DeeObject **iter1, **iter1_keyed;
+ DREF DeeObject **iter2, **iter2_keyed;
+ s1 = objc / 2;
+ s2 = objc - s1;
+ error = LOCAL_mergesort_impl_with_key_cache(s1,
+ scratch, scratch_keyed,
+ dst, dst_keyed,
+ LOCAL_ARG_SRC(0) LOCAL__ARG_KEY);
+ if unlikely(error < 0)
+ goto err;
+ error = LOCAL_mergesort_impl_with_key_cache(s2,
+ scratch + s1, scratch_keyed + s1,
+ dst + s1, dst_keyed + s1,
+ LOCAL_ARG_SRC(s1) LOCAL__ARG_KEY);
+ if unlikely(error < 0) {
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefvIfNotUnbound(scratch, s1));
+ LOCAL_DecrefvIfNotUnbound(scratch_keyed, s1);
+ goto err;
+ }
+ iter1 = scratch;
+ iter1_keyed = scratch_keyed;
+ iter2 = scratch + s1;
+ iter2_keyed = scratch_keyed + s1;
+ while (s1 && s2) {
+#ifdef LOCAL_GETITEM_UNBOUND
+ if (*iter1_keyed == LOCAL_GETITEM_UNBOUND) {
+ error = *iter2_keyed == LOCAL_GETITEM_UNBOUND ? 0 : 1;
+ } else if (*iter2_keyed == LOCAL_GETITEM_UNBOUND) {
+ error = 0;
+ } else
+#endif /* LOCAL_GETITEM_UNBOUND */
+ {
+ error = DeeObject_CmpLoAsBool(*iter1_keyed, *iter2_keyed);
+ }
+ if (error <= 0) {
+ if unlikely(error < 0) {
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefvIfNotUnbound(scratch, objc));
+ LOCAL_DecrefvIfNotUnbound(scratch_keyed, objc);
+ goto err;
+ }
+ *dst++ = *iter2++;
+ *dst_keyed++ = *iter2_keyed++;
+ --s2;
+ } else {
+ *dst++ = *iter1++;
+ *dst_keyed++ = *iter1_keyed++;
+ --s1;
+ }
+ }
+ if (s1) {
+ ASSERT(!s2);
+ memcpyc(dst, iter1, s1, sizeof(DREF DeeObject *));
+ memcpyc(dst_keyed, iter1_keyed, s1, sizeof(DREF DeeObject *));
+ } else if (s2) {
+ memcpyc(dst, iter2, s2, sizeof(DREF DeeObject *));
+ memcpyc(dst_keyed, iter2_keyed, s2, sizeof(DREF DeeObject *));
+ }
+ } break;
+
+ }
+ return 0;
+err:
+ return -1;
+}
+#endif /* LOCAL_HAS_KEY */
+
+
+PRIVATE WUNUSED ATTR_OUTS(1, 2) int DCALL
+LOCAL_insertsort_impl(DREF DeeObject **__restrict dst, size_t objc,
+ LOCAL_PARAM_SRC LOCAL__PARAM_KEY) {
+ int temp;
+ size_t i, j;
+ for (i = 0; i < objc; ++i) {
+ DREF DeeObject *ob = LOCAL_GETITEM(i);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(ob == LOCAL_GETITEM_ERROR)
+ goto err_dst_i;
+#endif /* LOCAL_GETITEM_ERROR */
+ j = 0;
+#ifdef LOCAL_GETITEM_UNBOUND
+ if (ob != LOCAL_GETITEM_UNBOUND)
+#endif /* LOCAL_GETITEM_UNBOUND */
+ {
+#ifdef LOCAL_HAS_KEY
+ DREF DeeObject *keyed_ob = DeeObject_Call(key, 1, &ob);
+ if unlikely(!keyed_ob) {
+ LOCAL_IF_GETITEM_ISREF(Dee_Decref(ob));
+ goto err_dst_i;
+ }
+#endif /* LOCAL_HAS_KEY */
+ for (; j < i; ++j) {
+ /* Check if we need to insert the object in this location. */
+#ifdef LOCAL_HAS_KEY
+ DREF DeeObject *keyed_dst_j;
+ keyed_dst_j = DeeObject_Call(key, 1, &dst[j]);
+ if unlikely(!keyed_dst_j) {
+err_dst_i_keyed_ob:
+ Dee_Decref(keyed_ob);
+ goto err_dst_i;
+ }
+ temp = DeeObject_CmpLoAsBool(ob, keyed_dst_j);
+ Dee_Decref(keyed_dst_j);
+ if unlikely(temp < 0)
+ goto err_dst_i_keyed_ob;
+#else /* LOCAL_HAS_KEY */
+ temp = DeeObject_CmpLoAsBool(ob, dst[j]);
+ if unlikely(temp < 0)
+ goto err_dst_i;
+#endif /* !LOCAL_HAS_KEY */
+ if (temp > 0)
+ break;
+ }
+ }
+ memmoveupc(&dst[j + 1], &dst[j], i - j, sizeof(DREF DeeObject *));
+ dst[j] = ob;
+ }
+ return 0;
+err_dst_i:
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefvIfNotUnbound(dst, i));
+ return -1;
+}
+
+INTERN WUNUSED ATTR_OUTS(2, 1) int DCALL
+LOCAL_DeeSeq_Sort(size_t objc, DREF DeeObject **__restrict dst,
+ LOCAL_PARAM_SRC LOCAL__PARAM_KEY) {
+ int result = 0;
+ switch (objc) {
+
+ case 0:
+ break;
+
+ case 1: {
+ DREF DeeObject *src0;
+ src0 = LOCAL_GETITEM(0);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src0 == LOCAL_GETITEM_ERROR)
+ goto err;
+#endif /* LOCAL_GETITEM_ERROR */
+ dst[0] = src0;
+ } break;
+
+ case 2: { /* Optimization for sorting 2 objects. */
+ int src0_lo_src1;
+ DREF DeeObject *src0, *src1;
+ src0 = LOCAL_GETITEM(0);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src0 == LOCAL_GETITEM_ERROR)
+ goto err;
+#endif /* LOCAL_GETITEM_ERROR */
+ src1 = LOCAL_GETITEM(1);
+#ifdef LOCAL_GETITEM_ERROR
+ if unlikely(src1 == LOCAL_GETITEM_ERROR) {
+ LOCAL_IF_GETITEM_ISREF(LOCAL_DecrefIfNotUnbound(src0));
+ goto err;
+ }
+#endif /* LOCAL_GETITEM_ERROR */
+ src0_lo_src1 = LOCAL_DeeObject_CmpLoAsBool(src0, src1);
+ if (src0_lo_src1 <= 0) {
+ if unlikely(src0_lo_src1 < 0)
+ goto err;
+ dst[0] = src1; /* Inherit reference */
+ dst[1] = src0; /* Inherit reference */
+ } else {
+ dst[0] = src0; /* Inherit reference */
+ dst[1] = src1; /* Inherit reference */
+ }
+ } break;
+
+ default: {
+ DREF DeeObject **scratch;
+#ifdef LOCAL_HAS_KEY
+ scratch = (DeeObject **)Dee_TryMallocc(objc * 3, sizeof(DeeObject *));
+ if likely(scratch) {
+ result = LOCAL_mergesort_impl_with_key_cache(objc, dst, scratch, scratch + objc, scratch + objc * 2,
+ LOCAL_ARG_SRC(0) LOCAL__ARG_KEY);
+ if likely(result == 0) /* Drop references still held on cached keys */
+ LOCAL_DecrefvIfNotUnbound(scratch, objc);
+ Dee_Free(scratch);
+ } else
+#endif /* LOCAL_HAS_KEY */
+ {
+ scratch = (DeeObject **)Dee_TryMallocc(objc, sizeof(DeeObject *));
+ if likely(scratch) {
+ result = LOCAL_mergesort_impl(objc, dst, scratch, LOCAL_ARG_SRC(0) LOCAL__ARG_KEY);
+ Dee_Free(scratch);
+ } else {
+ result = LOCAL_insertsort_impl(dst, objc, LOCAL_ARG_SRC(0) LOCAL__ARG_KEY);
+ }
+ }
+ } break;
+ }
+ return result;
+err:
+ return -1;
+}
+
+#undef LOCAL_DecrefIfNotUnbound
+#undef LOCAL_DecrefvIfNotUnbound
+#undef LOCAL_IF_GETITEM_ISREF
+#undef LOCAL__PARAM_KEY
+#undef LOCAL__ARG_KEY
+#undef LOCAL_DeeObject_CmpLoAsBool
+#undef LOCAL_PARAM_SRC
+#undef LOCAL_ARG_SRC
+#undef LOCAL_GETITEM
+#undef LOCAL_GETITEM_UNBOUND
+#undef LOCAL_GETITEM_ERROR
+#undef LOCAL_GETITEM_ISREF
+#undef LOCAL_mergesort_impl
+#undef LOCAL_insertsort_impl
+#undef F
+#undef LOCAL_DeeSeq_Sort
+#undef LOCAL_HAS_VECTOR
+#undef LOCAL_HAS_KEY
+#undef LOCAL_HAS_GETITEM
+#undef LOCAL_HAS_GETITEM_FAST
+
+DECL_END
+
+#undef DEFINE_DeeSeq_SortVector
+#undef DEFINE_DeeSeq_SortVectorWithKey
+#undef DEFINE_DeeSeq_SortGetItemIndexFast
+#undef DEFINE_DeeSeq_SortGetItemIndexFastWithKey
+#undef DEFINE_DeeSeq_SortTryGetItemIndex
+#undef DEFINE_DeeSeq_SortTryGetItemIndexWithKey
diff --git a/src/deemon/objects/seq/sort.c b/src/deemon/objects/seq/sort.c
index 6955d3ade..9dcdc5129 100644
--- a/src/deemon/objects/seq/sort.c
+++ b/src/deemon/objects/seq/sort.c
@@ -23,344 +23,25 @@
#include
#include
#include
-#include
#include
-#include
-#include
-
-DECL_BEGIN
-
-PRIVATE WUNUSED ATTR_OUTS(1, 4) ATTR_INS(3, 4) int DCALL
-mergesort_impl(DREF DeeObject **__restrict dst,
- DeeObject **__restrict temp,
- DREF DeeObject *const *__restrict src,
- size_t objc) {
- int error;
- switch (objc) {
-
- case 0:
- break;
-
- case 1:
- dst[0] = src[0];
- break;
-
- case 2:
- error = DeeObject_CmpLoAsBool(src[0], src[1]);
- if unlikely(error < 0 &&
- !DeeError_Catch(&DeeError_TypeError) &&
- !DeeError_Catch(&DeeError_NotImplemented))
- goto err;
- if (error <= 0) {
- dst[0] = src[1];
- dst[1] = src[0];
- } else {
- dst[0] = src[0];
- dst[1] = src[1];
- }
- break;
-
- default: {
- size_t s1, s2;
- DeeObject **iter1;
- DeeObject **iter2;
- s1 = objc / 2;
- s2 = objc - s1;
- error = mergesort_impl(temp, dst, src, s1);
- if unlikely(error < 0)
- goto err;
- error = mergesort_impl(temp + s1, dst + s1, src + s1, s2);
- if unlikely(error < 0)
- goto err;
- iter1 = temp;
- iter2 = temp + s1;
- while (s1 && s2) {
- error = DeeObject_CmpLoAsBool(*iter1, *iter2);
- if unlikely(error < 0) {
- if (!DeeError_Catch(&DeeError_TypeError) &&
- !DeeError_Catch(&DeeError_NotImplemented))
- goto err;
- }
- if (error <= 0) {
- *dst++ = *iter2++;
- --s2;
- } else {
- *dst++ = *iter1++;
- --s1;
- }
- }
- if (s1) {
- ASSERT(!s2);
- memcpyc(dst, iter1, s1,
- sizeof(DREF DeeObject *));
- } else if (s2) {
- memcpyc(dst, iter2, s2,
- sizeof(DREF DeeObject *));
- }
- } break;
-
- }
- return 0;
-err:
- return -1;
-}
-
-
-PRIVATE WUNUSED NONNULL((1, 2, 3)) int DCALL
-compare_lo(DeeObject *lhs, DeeObject *rhs, DeeObject *key) {
- int result;
- lhs = DeeObject_Call(key, 1, (DeeObject **)&lhs);
- if unlikely(!lhs)
- goto err;
- rhs = DeeObject_Call(key, 1, (DeeObject **)&rhs);
- if unlikely(!rhs)
- goto err_lhs;
- result = DeeObject_CmpLoAsBool(lhs, rhs);
- Dee_Decref(rhs);
- Dee_Decref(lhs);
- return result;
-err_lhs:
- Dee_Decref(lhs);
-err:
- return -1;
-}
-
-PRIVATE WUNUSED ATTR_OUTS(1, 4) ATTR_INS(3, 4) NONNULL((5)) int DCALL
-mergesort_impl_p(DREF DeeObject **__restrict dst,
- DeeObject **__restrict temp,
- DREF DeeObject *const *__restrict src,
- size_t objc,
- DeeObject *key) {
- int error;
- switch (objc) {
-
- case 0:
- break;
-
- case 1:
- dst[0] = src[0];
- break;
-
- case 2:
- error = compare_lo(src[0], src[1], key);
- if (error <= 0) {
- if unlikely(error < 0 &&
- !DeeError_Catch(&DeeError_TypeError) &&
- !DeeError_Catch(&DeeError_NotImplemented))
- goto err;
- dst[0] = src[1];
- dst[1] = src[0];
- } else {
- dst[0] = src[0];
- dst[1] = src[1];
- }
- break;
-
- default: {
- size_t s1, s2;
- DeeObject *const *iter1;
- DeeObject *const *iter2;
- s1 = objc / 2;
- s2 = objc - s1;
- error = mergesort_impl_p(temp, dst, src, s1, key);
- if unlikely(error < 0)
- goto err;
- error = mergesort_impl_p(temp + s1, dst + s1, src + s1, s2, key);
- if unlikely(error < 0)
- goto err;
- iter1 = temp;
- iter2 = temp + s1;
- while (s1 && s2) {
- error = compare_lo(*iter1, *iter2, key);
- if (error <= 0) {
- if unlikely(error < 0 &&
- !DeeError_Catch(&DeeError_TypeError) &&
- !DeeError_Catch(&DeeError_NotImplemented))
- goto err;
- *dst++ = *iter2++;
- --s2;
- } else {
- *dst++ = *iter1++;
- --s1;
- }
- }
- if (s1) {
- ASSERT(!s2);
- memcpyc(dst, iter1, s1,
- sizeof(DREF DeeObject *));
- } else if (s2) {
- memcpyc(dst, iter2, s2,
- sizeof(DREF DeeObject *));
- }
- } break;
-
- }
- return 0;
-err:
- return -1;
-}
-
-
-
-PRIVATE WUNUSED ATTR_OUTS(1, 3) ATTR_INS(2, 3) int DCALL
-insertsort_impl(DREF DeeObject **__restrict dst,
- DREF DeeObject *const *__restrict src,
- size_t objc) {
- int temp;
- size_t i, j;
- for (i = 0; i < objc; ++i) {
- DeeObject *ob = src[i];
- for (j = 0; j < i; ++j) {
- /* Check if we need to insert the object in this location. */
- temp = DeeObject_CmpLoAsBool(ob, dst[j]);
- if unlikely(temp < 0 &&
- !DeeError_Catch(&DeeError_TypeError) &&
- !DeeError_Catch(&DeeError_NotImplemented))
- goto err;
- if (temp > 0)
- break;
- }
- memmoveupc(&dst[j + 1], &dst[j],
- i - j, sizeof(DREF DeeObject *));
- dst[j] = ob;
- }
- return 0;
-err:
- return -1;
-}
-
-PRIVATE WUNUSED ATTR_OUTS(1, 3) ATTR_INS(2, 3) NONNULL((4)) int DCALL
-insertsort_impl_p(DREF DeeObject **__restrict dst,
- DREF DeeObject *const *__restrict src,
- size_t objc, DeeObject *key) {
- int temp;
- size_t i, j;
- for (i = 0; i < objc; ++i) {
- DeeObject *src_ob = src[i];
- for (j = 0; j < i; ++j) {
- /* Check if we need to insert the object in this location. */
- temp = compare_lo(src_ob, dst[j], key);
- if unlikely(temp < 0 &&
- !DeeError_Catch(&DeeError_TypeError) &&
- !DeeError_Catch(&DeeError_NotImplemented))
- goto err;
- if (temp > 0)
- break;
- }
- memmoveupc(&dst[j + 1], &dst[j],
- i - j, sizeof(DREF DeeObject *));
- dst[j] = src_ob;
- }
- return 0;
-err:
- return -1;
-}
-
-
-
-INTERN WUNUSED ATTR_OUTS(1, 3) ATTR_INS(2, 3) int DCALL
-DeeSeq_MergeSort(DREF DeeObject **__restrict dst,
- DREF DeeObject *const *__restrict src,
- size_t objc, DeeObject *key) {
- int result = 0;
- ASSERT(dst != src);
- switch (objc) {
-
- case 0:
- break;
-
- case 1:
- dst[0] = src[0];
- break;
-
- case 2: {
- int temp;
- /* Optimization for sorting 2 objects. */
- temp = key
- ? compare_lo(src[0], src[1], key)
- : DeeObject_CmpLoAsBool(src[0], src[1]);
- if (temp <= 0) {
- if unlikely(temp < 0 &&
- !DeeError_Catch(&DeeError_TypeError) &&
- !DeeError_Catch(&DeeError_NotImplemented))
- goto err;
- dst[0] = src[1];
- dst[1] = src[0];
- } else {
- dst[0] = src[0];
- dst[1] = src[1];
- }
- } break;
-
- default: {
- DeeObject **temp;
- /* Default case: Do an actual merge-sort. */
- temp = (DeeObject **)Dee_TryMallocc(objc, sizeof(DeeObject *));
- if unlikely(!temp) {
- /* Use a fallback sorting function */
- result = key
- ? insertsort_impl_p(dst, src, objc, key)
- : insertsort_impl(dst, src, objc);
- } else {
- result = key
- ? mergesort_impl_p(dst, temp, src, objc, key)
- : mergesort_impl(dst, temp, src, objc);
- Dee_Free(temp);
- }
- } break;
- }
- return result;
-err:
- return -1;
-}
-
-
-
-INTERN WUNUSED ATTR_OUTS(1, 3) ATTR_INS(2, 3) int DCALL
-DeeSeq_InsertionSort(DREF DeeObject **__restrict dst,
- DREF DeeObject *const *__restrict src,
- size_t objc, DeeObject *key) {
- int result = 0;
- ASSERT(dst != src);
- switch (objc) {
-
- case 0:
- break;
-
- case 1:
- dst[0] = src[0];
- break;
-
- case 2: {
- int temp;
- /* Optimization for sorting 2 objects. */
- temp = key
- ? compare_lo(src[0], src[1], key)
- : DeeObject_CmpLoAsBool(src[0], src[1]);
- if unlikely(temp < 0 &&
- !DeeError_Catch(&DeeError_TypeError) &&
- !DeeError_Catch(&DeeError_NotImplemented))
- goto err;
- if (temp <= 0) {
- dst[0] = src[0];
- dst[1] = src[1];
- } else {
- dst[0] = src[1];
- dst[1] = src[0];
- }
- } break;
-
- default:
- result = key
- ? insertsort_impl_p(dst, src, objc, key)
- : insertsort_impl(dst, src, objc);
- break;
- }
- return result;
-err:
- return -1;
-}
-
-DECL_END
+#include /* memcpyc */
+/**/
+
+#include "sort.h"
+
+#ifndef __INTELLISENSE__
+#define DEFINE_DeeSeq_SortVector
+#include "sort-impl.c.inl"
+#define DEFINE_DeeSeq_SortVectorWithKey
+#include "sort-impl.c.inl"
+#define DEFINE_DeeSeq_SortGetItemIndexFast
+#include "sort-impl.c.inl"
+#define DEFINE_DeeSeq_SortGetItemIndexFastWithKey
+#include "sort-impl.c.inl"
+#define DEFINE_DeeSeq_SortTryGetItemIndex
+#include "sort-impl.c.inl"
+#define DEFINE_DeeSeq_SortTryGetItemIndexWithKey
+#include "sort-impl.c.inl"
+#endif /* !__INTELLISENSE__ */
#endif /* !GUARD_DEEMON_OBJECTS_SEQ_SORT_C */
diff --git a/src/deemon/objects/seq/sort.h b/src/deemon/objects/seq/sort.h
index d51431dc3..dc9d888db 100644
--- a/src/deemon/objects/seq/sort.h
+++ b/src/deemon/objects/seq/sort.h
@@ -25,15 +25,13 @@
DECL_BEGIN
-/* Vector-sorting functions. */
-INTDEF WUNUSED ATTR_OUTS(1, 3) ATTR_INS(2, 3) int DCALL
-DeeSeq_MergeSort(DREF DeeObject **__restrict dst,
- DREF DeeObject *const *__restrict src,
- size_t objc, DeeObject *key);
-INTDEF WUNUSED ATTR_OUTS(1, 3) ATTR_INS(2, 3) int DCALL
-DeeSeq_InsertionSort(DREF DeeObject **__restrict dst,
- DREF DeeObject *const *__restrict src,
- size_t objc, DeeObject *key);
+/* Generic sorting functions */
+INTDEF WUNUSED ATTR_OUTS(2, 1) ATTR_INS(3, 1) int DCALL DeeSeq_SortVector(size_t objc, DREF DeeObject **__restrict dst, /*inherit(on_success)*/ DREF DeeObject *const *__restrict src); /* source elements are never unbound */
+INTDEF WUNUSED ATTR_OUTS(2, 1) ATTR_INS(3, 1) NONNULL((4)) int DCALL DeeSeq_SortVectorWithKey(size_t objc, DREF DeeObject **__restrict dst, /*inherit(on_success)*/ DREF DeeObject *const *__restrict src, DeeObject *key); /* source elements are never unbound */
+INTDEF WUNUSED ATTR_OUTS(2, 1) NONNULL((3, 5)) int DCALL DeeSeq_SortGetItemIndexFast(size_t objc, DREF DeeObject **__restrict dst, DeeObject *src, size_t src_start, DREF DeeObject *(DCALL *src_getitem_index_fast)(DeeObject *__restrict self, size_t index));
+INTDEF WUNUSED ATTR_OUTS(2, 1) NONNULL((3, 5, 6)) int DCALL DeeSeq_SortGetItemIndexFastWithKey(size_t objc, DREF DeeObject **__restrict dst, DeeObject *src, size_t src_start, DREF DeeObject *(DCALL *src_getitem_index_fast)(DeeObject *__restrict self, size_t index), DeeObject *key);
+INTDEF WUNUSED ATTR_OUTS(2, 1) NONNULL((3, 5)) int DCALL DeeSeq_SortTryGetItemIndex(size_t objc, DREF DeeObject **__restrict dst, DeeObject *src, size_t src_start, DREF DeeObject *(DCALL *src_trygetitem_index)(DeeObject *__restrict self, size_t index));
+INTDEF WUNUSED ATTR_OUTS(2, 1) NONNULL((3, 5, 6)) int DCALL DeeSeq_SortTryGetItemIndexWithKey(size_t objc, DREF DeeObject **__restrict dst, DeeObject *src, size_t src_start, DREF DeeObject *(DCALL *src_trygetitem_index)(DeeObject *__restrict self, size_t index), DeeObject *key);
DECL_END
diff --git a/src/deemon/objects/seq_functions.h b/src/deemon/objects/seq_functions.h
index d23482feb..5019505b1 100644
--- a/src/deemon/objects/seq_functions.h
+++ b/src/deemon/objects/seq_functions.h
@@ -81,8 +81,6 @@ INTDEF WUNUSED NONNULL((1, 4)) int DCALL DeeSeq_RRemove(DeeObject *self, size_t
INTDEF WUNUSED NONNULL((1, 4)) size_t DCALL DeeSeq_RemoveAll(DeeObject *self, size_t start, size_t end, DeeObject *elem, DeeObject *key);
INTDEF WUNUSED NONNULL((1, 4)) size_t DCALL DeeSeq_RemoveIf(DeeObject *self, size_t start, size_t end, DeeObject *should);
INTDEF WUNUSED NONNULL((1, 4)) size_t DCALL DeeSeq_Fill(DeeObject *self, size_t start, size_t end, DeeObject *value);
-INTDEF WUNUSED NONNULL((1)) int DCALL DeeSeq_Reverse(DeeObject *__restrict self);
-INTDEF WUNUSED NONNULL((1)) int DCALL DeeSeq_Sort(DeeObject *self, DeeObject *key);
/* Determine if a given sequence is mutable or resizable.
* @return: 1: The sequence is mutable or resizable.
diff --git a/src/deemon/objects/seq_mutable.c b/src/deemon/objects/seq_mutable.c
index 36a728db4..80794c466 100644
--- a/src/deemon/objects/seq_mutable.c
+++ b/src/deemon/objects/seq_mutable.c
@@ -4275,41 +4275,6 @@ DeeSeq_Fill(DeeObject *self, size_t start, size_t end,
return (size_t)-1;
}
-INTERN WUNUSED NONNULL((1)) int DCALL
-DeeSeq_Reverse(DeeObject *__restrict self) {
- int result;
- DREF DeeObject *reversed;
- reversed = DeeList_FromSequence(self);
- if unlikely(!reversed)
- goto err;
- DeeList_Reverse(reversed);
- result = DeeObject_Assign(self, reversed);
- Dee_Decref(reversed);
- return result;
-err:
- return -1;
-}
-
-INTERN WUNUSED NONNULL((1)) int DCALL
-DeeSeq_Sort(DeeObject *self, DeeObject *key) {
- int result;
- DREF DeeObject *sorted;
- sorted = DeeList_FromSequence(self);
- if unlikely(!sorted)
- goto err;
- if unlikely(DeeList_Sort(sorted, key))
- goto err_sorted;
- result = DeeObject_Assign(self, sorted);
- Dee_Decref(sorted);
- return result;
-err_sorted:
- Dee_Decref(sorted);
-err:
- return -1;
-}
-
-
-
PRIVATE DeeStringObject *tpconst mutable_sequence_attributes[] = {
&str_remove,
&str_rremove,
diff --git a/src/deemon/objects/tuple.c b/src/deemon/objects/tuple.c
index ebc94bc82..683454c73 100644
--- a/src/deemon/objects/tuple.c
+++ b/src/deemon/objects/tuple.c
@@ -43,6 +43,11 @@
#include
+/**/
+#include "seq/sort.h"
+
+/**/
+#include "../runtime/kwlist.h"
#include "../runtime/runtime_error.h"
#include "../runtime/strings.h"
@@ -1402,10 +1407,10 @@ tuple_deepcopy(Tuple *__restrict self) {
PRIVATE WUNUSED DREF Tuple *DCALL
tuple_init(size_t argc, DeeObject *const *argv) {
- DeeObject *seq;
- if (DeeArg_Unpack(argc, argv, "o:Tuple", &seq))
+ DeeObject *items;
+ if (DeeArg_Unpack(argc, argv, "o:Tuple", &items))
goto err;
- return (DREF Tuple *)DeeTuple_FromSequence(seq);
+ return (DREF Tuple *)DeeTuple_FromSequence(items);
err:
return NULL;
}
@@ -1471,7 +1476,7 @@ tuple_getitem(Tuple *self, DeeObject *index) {
INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL
tuple_getrange_index(Tuple *__restrict self,
- dssize_t begin, dssize_t end) {
+ Dee_ssize_t begin, Dee_ssize_t end) {
size_t range_size;
struct Dee_seq_range range;
DeeSeqRange_Clamp(&range, begin, end, self->t_size);
@@ -1483,7 +1488,7 @@ tuple_getrange_index(Tuple *__restrict self,
INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL
tuple_getrange_index_n(Tuple *__restrict self,
- dssize_t begin) {
+ Dee_ssize_t begin) {
#ifdef __OPTIMIZE_SIZE__
return tuple_getrange_index(self, begin, SSIZE_MAX);
#else /* __OPTIMIZE_SIZE__ */
@@ -1500,7 +1505,7 @@ PRIVATE WUNUSED NONNULL((1, 2, 3)) DREF DeeObject *DCALL
tuple_getrange(Tuple *__restrict self,
DeeObject *__restrict begin,
DeeObject *__restrict end) {
- dssize_t i_begin, i_end;
+ Dee_ssize_t i_begin, i_end;
if (DeeObject_AsSSize(begin, &i_begin))
goto err;
if (DeeNone_Check(end))
@@ -1536,6 +1541,13 @@ tuple_getitem_index_fast(Tuple *__restrict self, size_t index) {
return_reference(self->t_elem[index]);
}
+PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
+tuple_trygetitem_index(Tuple *__restrict self, size_t index) {
+ if unlikely(index >= self->t_size)
+ return ITER_DONE;
+ return_reference(self->t_elem[index]);
+}
+
PRIVATE WUNUSED NONNULL((1, 4)) size_t DCALL
tuple_nsi_find(Tuple *__restrict self, size_t start, size_t end,
DeeObject *__restrict keyed_search_item,
@@ -1678,7 +1690,7 @@ PRIVATE struct type_seq tuple_seq = {
/* .tp_delrange_index_n = */ NULL,
/* .tp_setrange_index_n = */ NULL,
/* .tp_trygetitem = */ NULL,
- /* .tp_trygetitem_index = */ NULL,
+ /* .tp_trygetitem_index = */ (DREF DeeObject *(DCALL *)(DeeObject *, size_t))&tuple_trygetitem_index,
/* .tp_trygetitem_string_hash = */ NULL,
/* .tp_getitem_string_hash = */ NULL,
/* .tp_delitem_string_hash = */ NULL,
@@ -1735,11 +1747,11 @@ tuple_visit(Tuple *__restrict self, dvisit_t proc, void *arg) {
/* Print all elements of the given tuple without any separators in-between
* elements. This is equivalent to `Tuple.operator str' and is related to
* the change introduced for handling `print("foo", "bar");'-like statements */
-INTERN WUNUSED NONNULL((1, 2)) dssize_t DCALL
+INTERN WUNUSED NONNULL((1, 2)) Dee_ssize_t DCALL
tuple_print(Tuple *__restrict self,
Dee_formatprinter_t printer, void *arg) {
size_t i;
- dssize_t temp, result = 0;
+ Dee_ssize_t temp, result = 0;
for (i = 0; i < DeeTuple_SIZE(self); ++i) {
DeeObject *elem;
elem = DeeTuple_GET(self, i);
@@ -1788,7 +1800,7 @@ tuple_str(Tuple *__restrict self) {
return NULL;
}
-INTERN WUNUSED NONNULL((1, 2)) dssize_t DCALL
+PRIVATE WUNUSED NONNULL((1, 2)) Dee_ssize_t DCALL
tuple_printrepr(Tuple *__restrict self,
Dee_formatprinter_t printer, void *arg) {
Dee_ssize_t temp, result;
@@ -1890,10 +1902,44 @@ tuple_last(Tuple *__restrict self) {
return NULL;
}
+INTDEF WUNUSED NONNULL((1)) DREF Tuple *DCALL
+tuple_sorted(Tuple *self, size_t argc, DeeObject *const *argv, DeeObject *kw) {
+ DREF Tuple *result;
+ 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 (end > self->t_size)
+ end = self->t_size;
+ if unlikely(start > end)
+ start = end;
+ result = DeeTuple_NewUninitialized(end - start);
+ if unlikely(!result)
+ goto err;
+ if unlikely(!DeeNone_Check(key)
+ ? DeeSeq_SortVectorWithKey(result->t_size, result->t_elem, self->t_elem + start, key)
+ : DeeSeq_SortVector(result->t_size, result->t_elem, self->t_elem + start))
+ goto err_r;
+ Dee_Increfv(result->t_elem, result->t_size);
+ return result;
+err_r:
+ DeeTuple_FreeUninitialized(result);
+err:
+ return NULL;
+}
+
+
+PRIVATE struct type_method tpconst tuple_methods[] = {
+ TYPE_KWMETHOD(STR_sorted, &tuple_sorted, "(start=!0,end=!-1,key=!n)->?."),
+ TYPE_METHOD_END
+};
PRIVATE struct type_getset tpconst tuple_getsets[] = {
TYPE_GETTER_F_NODOC(STR_first, &tuple_first, METHOD_FNOREFESCAPE),
TYPE_GETTER_F_NODOC(STR_last, &tuple_last, METHOD_FNOREFESCAPE),
+#define nullable_tuple_getsets (tuple_getsets + 2)
TYPE_GETTER(STR_frozen, &DeeObject_NewRef, "->?."),
TYPE_GETTER_F("__sizeof__", &tuple_sizeof, METHOD_FNOREFESCAPE, "->?Dint"),
TYPE_GETSET_END
@@ -2207,8 +2253,8 @@ PUBLIC DeeTypeObject DeeTuple_Type = {
/* .tp_str = */ (DREF DeeObject *(DCALL *)(DeeObject *__restrict))&tuple_str,
/* .tp_repr = */ (DREF DeeObject *(DCALL *)(DeeObject *__restrict))&tuple_repr,
/* .tp_bool = */ (int (DCALL *)(DeeObject *__restrict))&tuple_bool,
- /* .tp_print = */ (dssize_t (DCALL *)(DeeObject *__restrict, dformatprinter, void *))&tuple_print,
- /* .tp_printrepr = */ (dssize_t (DCALL *)(DeeObject *__restrict, dformatprinter, void *))&tuple_printrepr
+ /* .tp_print = */ (Dee_ssize_t (DCALL *)(DeeObject *__restrict, dformatprinter, void *))&tuple_print,
+ /* .tp_printrepr = */ (Dee_ssize_t (DCALL *)(DeeObject *__restrict, dformatprinter, void *))&tuple_printrepr
},
/* .tp_call = */ NULL,
/* .tp_visit = */ (void (DCALL *)(DeeObject *__restrict, dvisit_t, void *))&tuple_visit,
@@ -2220,7 +2266,7 @@ PUBLIC DeeTypeObject DeeTuple_Type = {
/* .tp_attr = */ NULL,
/* .tp_with = */ NULL,
/* .tp_buffer = */ NULL,
- /* .tp_methods = */ NULL,
+ /* .tp_methods = */ tuple_methods,
/* .tp_getsets = */ tuple_getsets,
/* .tp_members = */ NULL,
/* .tp_class_methods = */ tuple_class_methods,
@@ -2242,6 +2288,296 @@ PUBLIC struct empty_tuple_object DeeTuple_Empty = {
0
};
+
+
+
+PRIVATE struct empty_tuple_object DeeNullableTuple_Empty = {
+ OBJECT_HEAD_INIT(&DeeNullableTuple_Type),
+ 0
+};
+
+
+LOCAL ATTR_RETNONNULL WUNUSED NONNULL((1)) DREF DeeTupleObject *DCALL
+make_nullable(DREF DeeTupleObject *__restrict self) {
+ if unlikely(self == (DREF DeeTupleObject *)Dee_EmptyTuple) {
+ Dee_DecrefNokill(Dee_EmptyTuple);
+ Dee_Incref(&DeeNullableTuple_Empty);
+ return (DREF DeeTupleObject *)&DeeNullableTuple_Empty;
+ }
+ Dee_DecrefNokill(&DeeTuple_Type);
+ Dee_Incref(&DeeNullableTuple_Type);
+ self->ob_type = &DeeNullableTuple_Type;
+ return self;
+}
+
+PRIVATE WUNUSED NONNULL((1)) DREF Tuple *DCALL
+nullable_tuple_unpack(DeeObject *UNUSED(self), size_t argc, DeeObject *const *argv) {
+ DREF Tuple *result;
+ size_t num_items;
+ DeeObject *init;
+ if (DeeArg_Unpack(argc, argv, UNPuSIZ "o:unpack", &num_items, &init))
+ goto err;
+ result = DeeTuple_NewUninitialized(num_items);
+ if unlikely(!result)
+ goto done;
+ if unlikely(DeeObject_UnpackWithUnbound(init, num_items, DeeTuple_ELEM(result))) {
+ DeeTuple_FreeUninitialized(result);
+err:
+ result = NULL;
+ } else {
+ result = make_nullable(result);
+ }
+done:
+ return result;
+}
+
+
+PRIVATE WUNUSED DREF Tuple *DCALL nullable_tuple_ctor(void) {
+ return_reference_((DREF Tuple *)&DeeNullableTuple_Empty);
+}
+
+INTERN WUNUSED NONNULL((1)) DREF Tuple *DCALL
+nullable_tuple_deepcopy(Tuple *__restrict self) {
+ DREF Tuple *result;
+ size_t i, size = DeeTuple_SIZE(self);
+ result = DeeTuple_NewUninitialized(size);
+ if unlikely(!result)
+ goto err;
+ for (i = 0; i < size; ++i) {
+ DREF DeeObject *temp;
+ temp = DeeTuple_GET(self, i);
+ if (temp) {
+ temp = DeeObject_DeepCopy(DeeTuple_GET(self, i));
+ if unlikely(!temp)
+ goto err_r;
+ }
+ DeeTuple_SET(result, i, temp); /* Inherit reference. */
+ }
+ return make_nullable(result);
+err_r:
+ Dee_XDecrefv_likely(DeeTuple_ELEM(result), i);
+ DeeTuple_FreeUninitialized(result);
+err:
+ return NULL;
+}
+
+PRIVATE WUNUSED DREF Tuple *DCALL
+nullable_tuple_init(size_t argc, DeeObject *const *argv) {
+ DREF Tuple *result;
+ DeeObject *items;
+ if (DeeArg_Unpack(argc, argv, "o:NullableTuple", &items))
+ goto err;
+ result = (DREF Tuple *)DeeTuple_FromSequence(items);
+ if likely(result)
+ result = make_nullable(result);
+ return result;
+err:
+ return NULL;
+}
+
+PRIVATE NONNULL((1)) void DCALL
+nullable_tuple_fini(Tuple *__restrict self) {
+ Dee_XDecrefv(DeeTuple_ELEM(self),
+ DeeTuple_SIZE(self));
+}
+
+PRIVATE NONNULL((1, 2)) void DCALL
+nullable_tuple_visit(Tuple *__restrict self, dvisit_t proc, void *arg) {
+ Dee_XVisitv(DeeTuple_ELEM(self),
+ DeeTuple_SIZE(self));
+}
+
+PRIVATE WUNUSED NONNULL((1, 2)) DREF DeeObject *DCALL
+nullable_tuple_contains(Tuple *self, DeeObject *item) {
+ int error;
+ size_t i, mylen;
+ mylen = DeeTuple_SIZE(self);
+ for (i = 0; i < mylen; ++i) {
+ DeeObject *ob;
+ ob = DeeTuple_GET(self, i);
+ if (!ob)
+ continue;
+ error = DeeObject_TryCompareEq(item, ob);
+ if unlikely(error == Dee_COMPARE_ERR)
+ goto err;
+ if (error == 0)
+ return_true;
+ }
+ return_false;
+err:
+ return NULL;
+}
+
+#define nullable_tuple_enumerate_index \
+ tuple_enumerate_index /* Actually works the same! */
+
+PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
+nullable_tuple_getitem_index(Tuple *__restrict self, size_t index) {
+ if unlikely(index >= self->t_size)
+ goto err_bounds;
+ if (!self->t_elem[index])
+ goto err_unbound;
+ return_reference(self->t_elem[index]);
+err_unbound:
+ err_unbound_index((DeeObject *)self, index);
+ return NULL;
+err_bounds:
+ err_index_out_of_bounds((DeeObject *)self, index, self->t_size);
+ return NULL;
+}
+
+PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
+nullable_tuple_getitem_index_fast(Tuple *__restrict self, size_t index) {
+ DREF DeeObject *result;
+ ASSERT(index < self->t_size);
+ result = self->t_elem[index];
+ Dee_XIncref(result);
+ return result;
+}
+
+PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL
+nullable_tuple_trygetitem_index(Tuple *__restrict self, size_t index) {
+ if unlikely(index >= self->t_size)
+ return ITER_DONE;
+ if (!self->t_elem[index])
+ return ITER_DONE;
+ return_reference(self->t_elem[index]);
+}
+
+
+PRIVATE struct type_seq nullable_tuple_seq = {
+ /* .tp_iter = */ NULL,
+ /* .tp_sizeob = */ (DREF DeeObject *(DCALL *)(DeeObject *__restrict))&tuple_sizeob,
+ /* .tp_contains = */ (DREF DeeObject *(DCALL *)(DeeObject *, DeeObject *))&nullable_tuple_contains,
+ /* .tp_getitem = */ NULL,
+ /* .tp_delitem = */ NULL,
+ /* .tp_setitem = */ NULL,
+ /* .tp_getrange = */ NULL,
+ /* .tp_delrange = */ NULL,
+ /* .tp_setrange = */ NULL,
+ /* .tp_nsi = */ NULL,
+ /* .tp_foreach = */ NULL,
+ /* .tp_foreach_pair = */ NULL,
+ /* .tp_enumerate = */ NULL,
+ /* .tp_enumerate_index = */ (Dee_ssize_t (DCALL *)(DeeObject *__restrict, Dee_enumerate_index_t, void *, size_t, size_t))&nullable_tuple_enumerate_index,
+ /* .tp_bounditem = */ NULL,
+ /* .tp_hasitem = */ NULL,
+ /* .tp_size = */ (size_t (DCALL *)(DeeObject *__restrict))&tuple_size,
+ /* .tp_size_fast = */ (size_t (DCALL *)(DeeObject *__restrict))&tuple_size,
+ /* .tp_getitem_index = */ (DREF DeeObject *(DCALL *)(DeeObject *, size_t))&nullable_tuple_getitem_index,
+ /* .tp_getitem_index_fast = */ (DREF DeeObject *(DCALL *)(DeeObject *, size_t))&nullable_tuple_getitem_index_fast,
+ /* .tp_delitem_index = */ NULL,
+ /* .tp_setitem_index = */ NULL,
+ /* .tp_bounditem_index = */ NULL,
+ /* .tp_hasitem_index = */ NULL,
+ /* .tp_getrange_index = */ NULL,
+ /* .tp_delrange_index = */ NULL,
+ /* .tp_setrange_index = */ NULL,
+ /* .tp_getrange_index_n = */ NULL,
+ /* .tp_delrange_index_n = */ NULL,
+ /* .tp_setrange_index_n = */ NULL,
+ /* .tp_trygetitem = */ NULL,
+ /* .tp_trygetitem_index = */ (DREF DeeObject *(DCALL *)(DeeObject *, size_t))&nullable_tuple_trygetitem_index,
+ /* .tp_trygetitem_string_hash = */ NULL,
+ /* .tp_getitem_string_hash = */ NULL,
+ /* .tp_delitem_string_hash = */ NULL,
+ /* .tp_setitem_string_hash = */ NULL,
+ /* .tp_bounditem_string_hash = */ NULL,
+ /* .tp_hasitem_string_hash = */ NULL,
+ /* .tp_trygetitem_string_len_hash = */ NULL,
+ /* .tp_getitem_string_len_hash = */ NULL,
+ /* .tp_delitem_string_len_hash = */ NULL,
+ /* .tp_setitem_string_len_hash = */ NULL,
+ /* .tp_bounditem_string_len_hash = */ NULL,
+ /* .tp_hasitem_string_len_hash = */ NULL,
+};
+
+PRIVATE struct type_method tpconst nullable_tuple_class_methods[] = {
+ TYPE_METHOD("unpack", &nullable_tuple_unpack,
+ "(num:?Dint,seq:?S?O)->?.\n"
+ "#tUnpackError{The given @seq doesn't contain exactly @num elements}"
+ "Unpack the given sequence @seq into a Tuple consisting of @num elements.\n"
+ "Same as ?Aunpack?DTuple, except that unbound items are not silently skipped"),
+ TYPE_METHOD_END
+};
+
+PRIVATE struct type_member tpconst nullable_tuple_class_members[] = {
+ TYPE_MEMBER_CONST("Frozen", &DeeNullableTuple_Type),
+ TYPE_MEMBER_END
+};
+
+PRIVATE struct type_operator const nullable_tuple_operators[] = {
+ TYPE_OPERATOR_FLAGS(OPERATOR_0000_CONSTRUCTOR, METHOD_FCONSTCALL | METHOD_FCONSTCALL_IF_ARGSELEM_CONSTCAST),
+ TYPE_OPERATOR_FLAGS(OPERATOR_0001_COPY, METHOD_FCONSTCALL | METHOD_FNOTHROW),
+ TYPE_OPERATOR_FLAGS(OPERATOR_0002_DEEPCOPY, METHOD_FCONSTCALL | METHOD_FCONSTCALL_IF_THISELEM_CONSTDEEP | METHOD_FNOREFESCAPE),
+ TYPE_OPERATOR_FLAGS(OPERATOR_0008_BOOL, METHOD_FCONSTCALL | METHOD_FNOTHROW | METHOD_FNOREFESCAPE),
+ TYPE_OPERATOR_FLAGS(OPERATOR_0030_SIZE, METHOD_FCONSTCALL | METHOD_FNOREFESCAPE),
+ TYPE_OPERATOR_FLAGS(OPERATOR_0031_CONTAINS, METHOD_FCONSTCALL | METHOD_FCONSTCALL_IF_SEQ_CONSTCONTAINS | METHOD_FNOREFESCAPE),
+ TYPE_OPERATOR_FLAGS(OPERATOR_0032_GETITEM, METHOD_FCONSTCALL | METHOD_FCONSTCALL_IF_ARGS_CONSTCAST | METHOD_FNOREFESCAPE),
+ TYPE_OPERATOR_FLAGS(OPERATOR_0035_GETRANGE, METHOD_FCONSTCALL | METHOD_FCONSTCALL_IF_ARGS_CONSTCAST),
+};
+
+PUBLIC DeeTypeObject DeeNullableTuple_Type = {
+ OBJECT_HEAD_INIT(&DeeType_Type),
+ /* .tp_name = */ "NullableTuple",
+ /* .tp_doc = */ DOC("Same as ?DTuple, but able to represent unbound elements\n"
+ "\n"
+
+ "()\n"
+ "Construct an empty ?.\n"
+ "\n"
+
+ "(items:?S?O)\n"
+ "Construct a new ?. that is pre-initializes with the elements from @items"),
+ /* .tp_flags = */ TP_FNORMAL | TP_FVARIABLE | TP_FFINAL,
+ /* .tp_weakrefs = */ 0,
+ /* .tp_features = */ TF_NONE,
+ /* .tp_base = */ &DeeSeq_Type,
+ /* .tp_init = */ {
+ {
+ /* .tp_var = */ {
+ /* .tp_ctor = */ (dfunptr_t)&nullable_tuple_ctor,
+ /* .tp_copy_ctor = */ (dfunptr_t)&DeeObject_NewRef,
+ /* .tp_deep_ctor = */ (dfunptr_t)&nullable_tuple_deepcopy,
+ /* .tp_any_ctor = */ (dfunptr_t)&nullable_tuple_init,
+#if CONFIG_TUPLE_CACHE_MAXCOUNT != 0
+ /* .tp_free = */ (dfunptr_t)&tuple_tp_free
+#else /* CONFIG_TUPLE_CACHE_MAXCOUNT != 0 */
+ /* .tp_free = */ (dfunptr_t)NULL
+#endif /* CONFIG_TUPLE_CACHE_MAXCOUNT == 0 */
+ }
+ },
+ /* .tp_dtor = */ (void (DCALL *)(DeeObject *__restrict))&nullable_tuple_fini,
+ /* .tp_assign = */ NULL,
+ /* .tp_move_assign = */ NULL
+ },
+ /* .tp_cast = */ {
+ /* .tp_str = */ NULL,
+ /* .tp_repr = */ NULL,
+ /* .tp_bool = */ (int (DCALL *)(DeeObject *__restrict))&tuple_bool
+ },
+ /* .tp_call = */ NULL,
+ /* .tp_visit = */ (void (DCALL *)(DeeObject *__restrict, dvisit_t, void *))&nullable_tuple_visit,
+ /* .tp_gc = */ NULL,
+ /* .tp_math = */ NULL,
+ /* .tp_cmp = */ NULL,
+ /* .tp_seq = */ &nullable_tuple_seq,
+ /* .tp_iter_next = */ NULL,
+ /* .tp_attr = */ NULL,
+ /* .tp_with = */ NULL,
+ /* .tp_buffer = */ NULL,
+ /* .tp_methods = */ NULL,
+ /* .tp_getsets = */ nullable_tuple_getsets,
+ /* .tp_members = */ NULL,
+ /* .tp_class_methods = */ nullable_tuple_class_methods,
+ /* .tp_class_getsets = */ NULL,
+ /* .tp_class_members = */ tuple_class_members,
+ /* .tp_call_kw = */ NULL,
+ /* .tp_mro = */ NULL,
+ /* .tp_operators = */ nullable_tuple_operators,
+ /* .tp_operators_size= */ COMPILER_LENOF(nullable_tuple_operators)
+};
+
DECL_END
#endif /* !GUARD_DEEMON_OBJECTS_TUPLE_C */
diff --git a/src/deemon/objects/unicode/codec.h b/src/deemon/objects/unicode/codec.h
index 37caeba59..d3366cd55 100644
--- a/src/deemon/objects/unicode/codec.h
+++ b/src/deemon/objects/unicode/codec.h
@@ -79,7 +79,7 @@ local codecs = List {
("backslash-escape\0", "CODEC_C_ESCAPE"),
("c-escape\0", "CODEC_C_ESCAPE"),
};
-codecs.sort([](x) -> x[0]);
+codecs.sort(key: x -> x[0]);
local inset = "\t";
diff --git a/src/deemon/runtime/operator.c b/src/deemon/runtime/operator.c
index 1bfa76f43..44a1cf53b 100644
--- a/src/deemon/runtime/operator.c
+++ b/src/deemon/runtime/operator.c
@@ -14481,9 +14481,9 @@ DeeSeqType_SubstituteDefaultOperators(DeeTypeObject *self, seq_featureset_t feat
seq->tp_enumerate = &DeeSeq_DefaultEnumerateWithSizeAndGetItemIndex;
} else if (seq_featureset_test(features, FEAT_tp_sizeob) && seq_featureset_test(features, FEAT_tp_getitem) && seqclass == Dee_SEQCLASS_SEQ) {
seq->tp_enumerate = &DeeSeq_DefaultEnumerateWithSizeObAndGetItem;
- } else if (seq_featureset_test(features, FEAT_tp_foreach) && seqclass == Dee_SEQCLASS_SEQ) {
+ } else if (seq_featureset_test(features, FEAT_tp_foreach) && (seqclass == Dee_SEQCLASS_SEQ || seqclass == Dee_SEQCLASS_SET)) {
seq->tp_enumerate = &DeeSeq_DefaultEnumerateWithCounterAndForeach;
- } else if (seq_featureset_test(features, FEAT_tp_iter) && seqclass == Dee_SEQCLASS_SEQ) {
+ } else if (seq_featureset_test(features, FEAT_tp_iter) && (seqclass == Dee_SEQCLASS_SEQ || seqclass == Dee_SEQCLASS_SET)) {
seq->tp_enumerate = &DeeSeq_DefaultEnumerateWithCounterAndIter;
} else if (seq_featureset_test(features, FEAT_tp_iter) && seqclass == Dee_SEQCLASS_MAP) {
seq->tp_enumerate = &DeeMap_DefaultEnumerateWithIter;
diff --git a/src/dex/rt/librt.c b/src/dex/rt/librt.c
index d6a735590..46bdae23d 100644
--- a/src/dex/rt/librt.c
+++ b/src/dex/rt/librt.c
@@ -2184,7 +2184,6 @@ PRIVATE struct dex_symbol symbols[] = {
{ NULL, NULL, MODSYM_FNORMAL },
{ NULL, (DeeObject *)&librt_argv_set, MODSYM_FNORMAL },
-
/* Internal types used to drive sequence proxies */
{ "SeqCombinations", (DeeObject *)&librt_get_SeqCombinations, MODSYM_FREADONLY | MODSYM_FPROPERTY | MODSYM_FCONSTEXPR }, /* SeqCombinations_Type */
{ "SeqCombinationsIterator", (DeeObject *)&librt_get_SeqCombinationsIterator, MODSYM_FREADONLY | MODSYM_FPROPERTY | MODSYM_FCONSTEXPR }, /* SeqCombinationsIterator_Type */
@@ -2234,7 +2233,31 @@ PRIVATE struct dex_symbol symbols[] = {
{ "SeqEachCallAttrIterator", (DeeObject *)&librt_get_SeqEachCallAttrIterator, MODSYM_FREADONLY | MODSYM_FPROPERTY | MODSYM_FCONSTEXPR }, /* SeqEachCallAttrIterator_Type */
{ "SeqEachCallAttrKw", (DeeObject *)&librt_get_SeqEachCallAttrKw, MODSYM_FREADONLY | MODSYM_FPROPERTY | MODSYM_FCONSTEXPR }, /* SeqEachCallAttrKw_Type */
{ "SeqEachCallAttrKwIterator", (DeeObject *)&librt_get_SeqEachCallAttrKwIterator, MODSYM_FREADONLY | MODSYM_FPROPERTY | MODSYM_FCONSTEXPR }, /* SeqEachCallAttrKwIterator_Type */
- /* TODO: SeqRemoveIfAllWrapper_Type */
+#ifdef CONFIG_EXPERIMENTAL_NEW_SEQUENCE_OPERATORS
+ /* TODO: IterWithGetItemIndex = DefaultIterator_WithGetItemIndex_Type */
+ /* TODO: IterWithSizeAndGetItemIndex = DefaultIterator_WithSizeAndGetItemIndex_Type */
+ /* TODO: IterWithSizeAndGetItemIndexFast = DefaultIterator_WithSizeAndGetItemIndexFast_Type */
+ /* TODO: IterWithGetItem = DefaultIterator_WithGetItem_Type */
+ /* TODO: IterWithTGetItem = DefaultIterator_WithTGetItem_Type */
+ /* TODO: IterWithSizeAndGetItem = DefaultIterator_WithSizeAndGetItem_Type */
+ /* TODO: IterWithTSizeAndGetItem = DefaultIterator_WithTSizeAndGetItem_Type */
+ /* TODO: IterWithNextAndLimit = DefaultIterator_WithNextAndLimit_Type */
+ /* TODO: SeqWithSizeAndGetItemIndex = DefaultSequence_WithSizeAndGetItemIndex_Type */
+ /* TODO: SeqWithSizeAndGetItemIndexFast = DefaultSequence_WithSizeAndGetItemIndexFast_Type */
+ /* TODO: SeqWithSizeAndGetItem = DefaultSequence_WithSizeAndGetItem_Type */
+ /* TODO: SeqWithTSizeAndGetItem = DefaultSequence_WithTSizeAndGetItem_Type */
+ /* TODO: SeqWithIter = DefaultSequence_WithIter_Type */
+ /* TODO: SeqWithTIter = DefaultSequence_WithTIter_Type */
+ /* TODO: SeqReversedWithGetItemIndex = DefaultReversed_WithGetItemIndex_Type */
+ /* TODO: SeqReversedWithGetItemIndexFast = DefaultReversed_WithGetItemIndexFast_Type */
+ /* TODO: SeqReversedWithTryGetItemIndex = DefaultReversed_WithTryGetItemIndex_Type */
+ /* TODO: SeqRemoveWithRemoveIfPredicate = SeqRemoveWithRemoveIfPredicate_Type */
+ /* TODO: SeqRemoveWithRemoveIfPredicateWithKey = SeqRemoveWithRemoveIfPredicateWithKey_Type */
+ /* TODO: SeqRemoveIfWithRemoveAllItem = SeqRemoveIfWithRemoveAllItem_Type */
+ /* TODO: SeqRemoveIfWithRemoveAllItem_DummyInstance = SeqRemoveIfWithRemoveAllItem_DummyInstance */
+ /* TODO: SeqRemoveIfWithRemoveAllKey = SeqRemoveIfWithRemoveAllKey_Type */
+#endif /* CONFIG_EXPERIMENTAL_NEW_SEQUENCE_OPERATORS */
+ { "NullableTuple", (DeeObject *)&DeeNullableTuple_Type, MODSYM_FREADONLY },
/* Internal types used to drive set proxies */
{ "SetUnion", (DeeObject *)&librt_get_SetUnion, MODSYM_FREADONLY | MODSYM_FPROPERTY | MODSYM_FCONSTEXPR }, /* SetUnion_Type */
@@ -2589,31 +2612,6 @@ PRIVATE struct dex_symbol symbols[] = {
{ "FrameSymbolsByName", (DeeObject *)&librt_get_FrameSymbolsByName, MODSYM_FREADONLY | MODSYM_FPROPERTY | MODSYM_FCONSTEXPR }, /* FrameSymbolsByName_Type */
{ "FrameSymbolsByNameIterator", (DeeObject *)&librt_get_FrameSymbolsByNameIterator, MODSYM_FREADONLY | MODSYM_FPROPERTY | MODSYM_FCONSTEXPR }, /* FrameSymbolsByName_Type */
-#ifdef CONFIG_EXPERIMENTAL_NEW_SEQUENCE_OPERATORS
- /* TODO: IterWithGetItemIndex = DefaultIterator_WithGetItemIndex_Type */
- /* TODO: IterWithSizeAndGetItemIndex = DefaultIterator_WithSizeAndGetItemIndex_Type */
- /* TODO: IterWithSizeAndGetItemIndexFast = DefaultIterator_WithSizeAndGetItemIndexFast_Type */
- /* TODO: IterWithGetItem = DefaultIterator_WithGetItem_Type */
- /* TODO: IterWithTGetItem = DefaultIterator_WithTGetItem_Type */
- /* TODO: IterWithSizeAndGetItem = DefaultIterator_WithSizeAndGetItem_Type */
- /* TODO: IterWithTSizeAndGetItem = DefaultIterator_WithTSizeAndGetItem_Type */
- /* TODO: IterWithNextAndLimit = DefaultIterator_WithNextAndLimit_Type */
- /* TODO: SeqWithSizeAndGetItemIndex = DefaultSequence_WithSizeAndGetItemIndex_Type */
- /* TODO: SeqWithSizeAndGetItemIndexFast = DefaultSequence_WithSizeAndGetItemIndexFast_Type */
- /* TODO: SeqWithSizeAndGetItem = DefaultSequence_WithSizeAndGetItem_Type */
- /* TODO: SeqWithTSizeAndGetItem = DefaultSequence_WithTSizeAndGetItem_Type */
- /* TODO: SeqWithIter = DefaultSequence_WithIter_Type */
- /* TODO: SeqWithTIter = DefaultSequence_WithTIter_Type */
- /* TODO: SeqReversedWithGetItemIndex = DefaultReversed_WithGetItemIndex_Type */
- /* TODO: SeqReversedWithGetItemIndexFast = DefaultReversed_WithGetItemIndexFast_Type */
- /* TODO: SeqReversedWithTryGetItemIndex = DefaultReversed_WithTryGetItemIndex_Type */
- /* TODO: SeqRemoveWithRemoveIfPredicate = SeqRemoveWithRemoveIfPredicate_Type */
- /* TODO: SeqRemoveWithRemoveIfPredicateWithKey = SeqRemoveWithRemoveIfPredicateWithKey_Type */
- /* TODO: SeqRemoveIfWithRemoveAllItem = SeqRemoveIfWithRemoveAllItem_Type */
- /* TODO: SeqRemoveIfWithRemoveAllItem_DummyInstance = SeqRemoveIfWithRemoveAllItem_DummyInstance */
- /* TODO: SeqRemoveIfWithRemoveAllKey = SeqRemoveIfWithRemoveAllKey_Type */
-#endif /* CONFIG_EXPERIMENTAL_NEW_SEQUENCE_OPERATORS */
-
{ NULL }
};