--- a/Array.st Tue Sep 18 14:54:40 2018 +0200
+++ b/Array.st Tue Sep 18 14:55:11 2018 +0200
@@ -305,6 +305,7 @@
"Modified: 23.4.1996 / 15:55:06 / cg"
! !
+
!Array methodsFor:'accessing'!
at:index
@@ -2490,6 +2491,103 @@
}
%}.
^ super indexOf:anElement startingAt:start endingAt:stop
+!
+
+indexOf:anElement startingAt:start step:stepArg
+ "search the array for anElement; return index if found, 0 otherwise
+ - reimplemented for speed"
+
+ |element elementIsSharedInstance|
+
+ elementIsSharedInstance := anElement isSharedInstance.
+
+%{
+ static struct inlineCache eq = _ILC1;
+
+ if ( __bothSmallInteger(start, stepArg) ) {
+ INT index = __intVal(start) - 1;
+ if (index >= 0) {
+ INT step = __intVal(stepArg);
+ unsigned INT nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+ OBJ e = anElement;
+ unsigned INT nInsts = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
+ index += nInsts;
+
+ if (elementIsSharedInstance == false) {
+ /*
+ * special kludge to search for a string;
+ * this is so common, that its worth a special case
+ */
+#define SPECIAL_STRING_OPT
+#ifdef SPECIAL_STRING_OPT
+ if (__isStringLike(e)) {
+ for ( ;index < nIndex; index += step) {
+ element = __InstPtr(self)->i_instvars[index];
+ if (__isNonNilObject(element)) {
+ if (element == e) {
+ RETURN ( __mkSmallInteger(index+1 - nInsts) );
+ }
+ if (__qClass(element) == @global(String)) {
+ if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
+ RETURN ( __mkSmallInteger(index+1 - nInsts) );
+ }
+ } else {
+ if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
+ RETURN ( __mkSmallInteger(index+1 - nInsts) );
+ }
+ /*
+ * send of #= could have lead to a GC - refetch e
+ */
+ e = anElement;
+ }
+ }
+ }
+ RETURN (__mkSmallInteger(0));
+ }
+#endif
+
+ for ( ;index < nIndex; index += step) {
+ element = __InstPtr(self)->i_instvars[index];
+ if (element != nil) {
+ if ((element == e)
+ || ((*eq.ilc_func)(e,
+ @symbol(=),
+ nil,&eq,
+ element) == true)) {
+ RETURN ( __mkSmallInteger(index + 1 - nInsts) );
+ }
+ /*
+ * send of #= could have lead to a GC - refetch e
+ */
+ e = anElement;
+ }
+ }
+ } else {
+ OBJ slf = self;
+
+ /*
+ * search for a sharedInstance - do an identity-search
+ */
+ for ( ; index < nIndex; index += step) {
+ if (__InstPtr(slf)->i_instvars[index] == e) {
+ RETURN ( __mkSmallInteger(index + 1 - nInsts) );
+ }
+ }
+ }
+ }
+ RETURN (__mkSmallInteger(0));
+ }
+%}.
+ ^ super indexOf:anElement startingAt:start step:stepArg
+
+ "
+ #(1 2 3 4 5 6 7) indexOf:5 startingAt:1 step:2
+ #(1 2 3 4 5 6 7) indexOf:6 startingAt:1 step:2
+ #(1 2 3 4 5 6 bla) indexOf:#bla startingAt:1 step:2
+ #(1 2 3 4 5 6 'bla') indexOf:'bla' startingAt:1 step:2
+ "
+
+ "Created: / 18-09-2018 / 14:05:53 / Stefan Vogel"
! !
!Array methodsFor:'testing'!