Array.st
changeset 23359 6cdbc4771427
parent 23277 fbf70468abb5
child 23361 140395c0ae98
--- 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'!