Array.st
changeset 14632 6fe0dc1d5377
parent 14623 c433536ae3ab
child 14657 6610eb2df25c
equal deleted inserted replaced
14631:501217c542a5 14632:6fe0dc1d5377
    34 "
    34 "
    35 !
    35 !
    36 
    36 
    37 documentation
    37 documentation
    38 "
    38 "
    39     Instances of Array store general objects; the arrays size is fixed, 
    39     Instances of Array store general objects; the arrays size is fixed,
    40     therefore add:/remove: are not allowed. 
    40     therefore add:/remove: are not allowed.
    41     (actually, #add: is implemented for compatibility with smalltalks which 
    41     (actually, #add: is implemented for compatibility with smalltalks which
    42      provide it, but it is very slow and outputs an annoying warning message ...)
    42      provide it, but it is very slow and outputs an annoying warning message ...)
    43 
    43 
    44     Access to the individual elements is via an integer index,
    44     Access to the individual elements is via an integer index,
    45     using the well-known access messages #at: and #at:put:.
    45     using the well-known access messages #at: and #at:put:.
    46 
    46 
    47     Since Arrays are used very often in the system (either directly or a data-container
    47     Since Arrays are used very often in the system (either directly or a data-container
    48     of more complex collection classes), some methods have been tuned by reimplementing 
    48     of more complex collection classes), some methods have been tuned by reimplementing
    49     them as primitives. Also, the compiler inline-codes some operations 
    49     them as primitives. Also, the compiler inline-codes some operations
    50     (especially: the above accessing messages).
    50     (especially: the above accessing messages).
    51 
    51 
    52     Notice that Array is a built-in class 
    52     Notice that Array is a built-in class
    53     (i.e. the VM knows about its representation). 
    53     (i.e. the VM knows about its representation).
    54     Therefore it is NOT possible to add named instance variables or change 
    54     Therefore it is NOT possible to add named instance variables or change
    55     Arrays inheritance. 
    55     Arrays inheritance.
    56     However, subclassing is allowed of course 
    56     However, subclassing is allowed of course
    57     - even with added named instance variables.
    57     - even with added named instance variables.
    58 
    58 
    59     Literal arrays (i.e. array-constants) are entered in source as:
    59     Literal arrays (i.e. array-constants) are entered in source as:
    60 
    60 
    61 	#( element1 element2 ... element-n)
    61 	#( element1 element2 ... element-n)
   246 	^ nil
   246 	^ nil
   247     ].
   247     ].
   248     "
   248     "
   249      memory allocation failed.
   249      memory allocation failed.
   250      When we arrive here, there was no memory, even after
   250      When we arrive here, there was no memory, even after
   251      a garbage collect. 
   251      a garbage collect.
   252      This means, that the VM wanted to get some more memory from the 
   252      This means, that the VM wanted to get some more memory from the
   253      Operatingsystem, which was not kind enough to give it.
   253      Operatingsystem, which was not kind enough to give it.
   254      Bad luck - you should increase the swap space on your machine.
   254      Bad luck - you should increase the swap space on your machine.
   255     "
   255     "
   256     ^ ObjectMemory allocationFailureSignal raise.
   256     ^ ObjectMemory allocationFailureSignal raise.
   257 !
   257 !
   281 !Array methodsFor:'accessing'!
   281 !Array methodsFor:'accessing'!
   282 
   282 
   283 at:index
   283 at:index
   284     "return the indexed instance variable with index, anInteger.
   284     "return the indexed instance variable with index, anInteger.
   285      Reimplemented here to avoid the additional at:->basicAt: send
   285      Reimplemented here to avoid the additional at:->basicAt: send
   286      (which we can do here, since when arriving here, #at: is obviously not 
   286      (which we can do here, since when arriving here, #at: is obviously not
   287       redefined in a subclass).
   287       redefined in a subclass).
   288      This method is the same as basicAt:."
   288      This method is the same as basicAt:."
   289 
   289 
   290 %{  /* NOCONTEXT */
   290 %{  /* NOCONTEXT */
   291 
   291 
   448 
   448 
   449 !Array methodsFor:'copying'!
   449 !Array methodsFor:'copying'!
   450 
   450 
   451 copyWith:something
   451 copyWith:something
   452     "return a new collection containing the receivers elements
   452     "return a new collection containing the receivers elements
   453      and the single new element, newElement. 
   453      and the single new element, newElement.
   454      This is different from concatentation, which expects another collection
   454      This is different from concatentation, which expects another collection
   455      as argument, but equivalent to copy-and-addLast.
   455      as argument, but equivalent to copy-and-addLast.
   456      Reimplemented for speed if receiver is an Array.
   456      Reimplemented for speed if receiver is an Array.
   457      (since the inherited copyWith uses replaceFromTo:, which is also
   457      (since the inherited copyWith uses replaceFromTo:, which is also
   458       tuned, it is questionable, if we need this)"
   458       tuned, it is questionable, if we need this)"
   463     unsigned int nIndex;
   463     unsigned int nIndex;
   464     REGISTER OBJ *srcP, *dstP;
   464     REGISTER OBJ *srcP, *dstP;
   465     REGISTER int spc;
   465     REGISTER int spc;
   466 
   466 
   467     if (__qClass(self) == Array) {
   467     if (__qClass(self) == Array) {
   468         sz = __qSize(self) + sizeof(OBJ);
   468 	sz = __qSize(self) + sizeof(OBJ);
   469         __PROTECT2__(something, self);
   469 	__PROTECT2__(something, self);
   470         __qAlignedNew(nObj, sz);        /* OBJECT ALLOCATION */
   470 	__qAlignedNew(nObj, sz);        /* OBJECT ALLOCATION */
   471         __UNPROTECT2__(self, something);
   471 	__UNPROTECT2__(self, something);
   472 
   472 
   473         if (nObj) {
   473 	if (nObj) {
   474             __InstPtr(nObj)->o_class = Array;
   474 	    __InstPtr(nObj)->o_class = Array;
   475             __qSTORE(nObj, Array);
   475 	    __qSTORE(nObj, Array);
   476 
   476 
   477             nIndex = __BYTES2OBJS__(sz - OHDR_SIZE - sizeof(OBJ));
   477 	    nIndex = __BYTES2OBJS__(sz - OHDR_SIZE - sizeof(OBJ));
   478             /* 
   478 	    /*
   479              * sorry: 
   479 	     * sorry:
   480              *   cannot use bcopy, since we must take care of stores ... 
   480 	     *   cannot use bcopy, since we must take care of stores ...
   481              *   could check for: notRemembered + inOld + notLifoRem
   481 	     *   could check for: notRemembered + inOld + notLifoRem
   482              *                  + not incrGCRunning
   482 	     *                  + not incrGCRunning
   483              * but: copyWith is not heavily used by real programmers ...
   483 	     * but: copyWith is not heavily used by real programmers ...
   484              */
   484 	     */
   485             spc = __qSpace(nObj);
   485 	    spc = __qSpace(nObj);
   486             srcP = __arrayVal(self);
   486 	    srcP = __arrayVal(self);
   487             dstP = __arrayVal(nObj);
   487 	    dstP = __arrayVal(nObj);
   488 
   488 
   489 #ifdef __UNROLL_LOOPS__
   489 #ifdef __UNROLL_LOOPS__
   490             while (nIndex >= 4) {
   490 	    while (nIndex >= 4) {
   491                 OBJ element;
   491 		OBJ element;
   492 
   492 
   493                 element = srcP[0];
   493 		element = srcP[0];
   494                 dstP[0] = element;
   494 		dstP[0] = element;
   495                 __STORE_SPC(nObj, element, spc);
   495 		__STORE_SPC(nObj, element, spc);
   496                 element = srcP[1];
   496 		element = srcP[1];
   497                 dstP[1] = element;
   497 		dstP[1] = element;
   498                 __STORE_SPC(nObj, element, spc);
   498 		__STORE_SPC(nObj, element, spc);
   499                 element = srcP[2];
   499 		element = srcP[2];
   500                 dstP[2] = element;
   500 		dstP[2] = element;
   501                 __STORE_SPC(nObj, element, spc);
   501 		__STORE_SPC(nObj, element, spc);
   502                 element = srcP[3];
   502 		element = srcP[3];
   503                 dstP[3] = element;
   503 		dstP[3] = element;
   504                 __STORE_SPC(nObj, element, spc);
   504 		__STORE_SPC(nObj, element, spc);
   505                 srcP += 4;
   505 		srcP += 4;
   506                 dstP += 4;
   506 		dstP += 4;
   507                 nIndex -= 4;
   507 		nIndex -= 4;
   508             }
   508 	    }
   509 #endif
   509 #endif
   510             while (nIndex--) {
   510 	    while (nIndex--) {
   511                 OBJ element;
   511 		OBJ element;
   512 
   512 
   513                 element = *srcP++;
   513 		element = *srcP++;
   514                 *dstP++ = element;
   514 		*dstP++ = element;
   515                 __STORE_SPC(nObj, element, spc);
   515 		__STORE_SPC(nObj, element, spc);
   516             }
   516 	    }
   517             *dstP = something;
   517 	    *dstP = something;
   518             __STORE_SPC(nObj, something, spc);
   518 	    __STORE_SPC(nObj, something, spc);
   519             RETURN ( nObj );
   519 	    RETURN ( nObj );
   520         }
   520 	}
   521     }
   521     }
   522 %}.
   522 %}.
   523     ^ super copyWith:something
   523     ^ super copyWith:something
   524 ! !
   524 ! !
   525 
   525 
   532 
   532 
   533     |stop "{ Class: SmallInteger }"|
   533     |stop "{ Class: SmallInteger }"|
   534 
   534 
   535     stop := self size.
   535     stop := self size.
   536     1 to:stop do:[:idx |
   536     1 to:stop do:[:idx |
   537         |each|
   537 	|each|
   538         each := self at:idx.
   538 	each := self at:idx.
   539         each notNil ifTrue:[
   539 	each notNil ifTrue:[
   540             aCollection add:each.
   540 	    aCollection add:each.
   541         ].
   541 	].
   542     ].
   542     ].
   543     ^ aCollection
   543     ^ aCollection
   544 
   544 
   545     "
   545     "
   546      #(1 2 3 4 5 1 2 3 symbol 'string' nil) addAllNonNilElementsTo:Set new
   546      #(1 2 3 4 5 1 2 3 symbol 'string' nil) addAllNonNilElementsTo:Set new
   554 
   554 
   555     |stop "{ Class: SmallInteger }"|
   555     |stop "{ Class: SmallInteger }"|
   556 
   556 
   557     stop := self size.
   557     stop := self size.
   558     1 to:stop do:[:idx |
   558     1 to:stop do:[:idx |
   559         aCollection add:(self at:idx)
   559 	aCollection add:(self at:idx)
   560     ].
   560     ].
   561     ^ aCollection
   561     ^ aCollection
   562 !
   562 !
   563 
   563 
   564 do:aBlock
   564 do:aBlock
   744 			__interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &(__InstPtr(self)->i_instvars[index]));
   744 			__interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &(__InstPtr(self)->i_instvars[index]));
   745 #else
   745 #else
   746 			__interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __InstPtr(self)->i_instvars[index]);
   746 			__interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __InstPtr(self)->i_instvars[index]);
   747 #endif
   747 #endif
   748 		    } else {
   748 		    } else {
   749 			(*val.ilc_func)(aBlock, 
   749 			(*val.ilc_func)(aBlock,
   750 					    @symbol(value:), 
   750 					    @symbol(value:),
   751 					    nil, &val, 
   751 					    nil, &val,
   752 					    __InstPtr(self)->i_instvars[index]);
   752 					    __InstPtr(self)->i_instvars[index]);
   753 		    }
   753 		    }
   754 		}
   754 		}
   755 	    }
   755 	    }
   756 
   756 
   763 	/*
   763 	/*
   764 	 * not a block - send it #value:
   764 	 * not a block - send it #value:
   765 	 */
   765 	 */
   766 	for (; index < nIndex; index++) {
   766 	for (; index < nIndex; index++) {
   767 	    if (InterruptPending != nil) __interruptL(@line);
   767 	    if (InterruptPending != nil) __interruptL(@line);
   768 console_printf("el%d -> %lx\n", index, (long)(__InstPtr(self)->i_instvars[index]));
   768 	    // console_printf("el%d -> %"_lx_"\n", index, (long)(__InstPtr(self)->i_instvars[index]));
   769 	    (*val.ilc_func)(aBlock, 
   769 	    (*val.ilc_func)(aBlock,
   770 				@symbol(value:), 
   770 				@symbol(value:),
   771 				nil, &val, 
   771 				nil, &val,
   772 				__InstPtr(self)->i_instvars[index]);
   772 				__InstPtr(self)->i_instvars[index]);
   773 	}
   773 	}
   774 	RETURN ( self );
   774 	RETURN ( self );
   775     }
   775     }
   776     /* 
   776     /*
   777      * I am something, not handled here
   777      * I am something, not handled here
   778      */
   778      */
   779 %}.
   779 %}.
   780     ^ super do:aBlock
   780     ^ super do:aBlock
   781 !
   781 !
  1022 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &el);
  1022 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &el);
  1023 #else
  1023 #else
  1024 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, el);
  1024 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, el);
  1025 #endif
  1025 #endif
  1026 			} else {
  1026 			} else {
  1027 			    (*val.ilc_func)(aBlock, 
  1027 			    (*val.ilc_func)(aBlock,
  1028 					    @symbol(value:), 
  1028 					    @symbol(value:),
  1029 					    nil, &val, 
  1029 					    nil, &val,
  1030 					    el);
  1030 					    el);
  1031 			}
  1031 			}
  1032 		    }
  1032 		    }
  1033 		    n--;
  1033 		    n--;
  1034 		    index++;
  1034 		    index++;
  1044 	     * not a block - send it #value:
  1044 	     * not a block - send it #value:
  1045 	     */
  1045 	     */
  1046 	    while (n > 0) {
  1046 	    while (n > 0) {
  1047 		if (InterruptPending != nil) __interruptL(@line);
  1047 		if (InterruptPending != nil) __interruptL(@line);
  1048 
  1048 
  1049 		(*val.ilc_func)(aBlock, 
  1049 		(*val.ilc_func)(aBlock,
  1050 				@symbol(value:), 
  1050 				@symbol(value:),
  1051 				nil, &val, 
  1051 				nil, &val,
  1052 				__InstPtr(self)->i_instvars[index]);
  1052 				__InstPtr(self)->i_instvars[index]);
  1053 		n--;
  1053 		n--;
  1054 		index++;
  1054 		index++;
  1055 	    }
  1055 	    }
  1056 	    RETURN ( self );
  1056 	    RETURN ( self );
  1111 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &(__InstPtr(self)->i_instvars[index]));
  1111 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &(__InstPtr(self)->i_instvars[index]));
  1112 #else
  1112 #else
  1113 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __InstPtr(self)->i_instvars[index]);
  1113 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __InstPtr(self)->i_instvars[index]);
  1114 #endif
  1114 #endif
  1115 			} else {
  1115 			} else {
  1116 			    (*val.ilc_func)(aBlock, 
  1116 			    (*val.ilc_func)(aBlock,
  1117 					    @symbol(value:), 
  1117 					    @symbol(value:),
  1118 					    nil, &val, 
  1118 					    nil, &val,
  1119 					    __InstPtr(self)->i_instvars[index]);
  1119 					    __InstPtr(self)->i_instvars[index]);
  1120 			}
  1120 			}
  1121 		    }
  1121 		    }
  1122 		}
  1122 		}
  1123 
  1123 
  1131 	     * not a block - send it #value:
  1131 	     * not a block - send it #value:
  1132 	     */
  1132 	     */
  1133 	    for (index=indexHigh; index >= indexLow; index--) {
  1133 	    for (index=indexHigh; index >= indexLow; index--) {
  1134 		if (InterruptPending != nil) __interruptL(@line);
  1134 		if (InterruptPending != nil) __interruptL(@line);
  1135 
  1135 
  1136 		(*val.ilc_func)(aBlock, 
  1136 		(*val.ilc_func)(aBlock,
  1137 				@symbol(value:), 
  1137 				@symbol(value:),
  1138 				nil, &val, 
  1138 				nil, &val,
  1139 				__InstPtr(self)->i_instvars[index]);
  1139 				__InstPtr(self)->i_instvars[index]);
  1140 	    }
  1140 	    }
  1141 	    RETURN ( self );
  1141 	    RETURN ( self );
  1142 	}
  1142 	}
  1143     }
  1143     }
  1200 				(*codeVal)(BLOCK_ARG, __mkSmallInteger(index), el);
  1200 				(*codeVal)(BLOCK_ARG, __mkSmallInteger(index), el);
  1201 			    }
  1201 			    }
  1202 			    RETURN (self);
  1202 			    RETURN (self);
  1203 
  1203 
  1204 		interruptX:
  1204 		interruptX:
  1205 			    __interruptL(@line); 
  1205 			    __interruptL(@line);
  1206 			    el = __InstPtr(self)->i_instvars[index];
  1206 			    el = __InstPtr(self)->i_instvars[index];
  1207 			    goto continueX;
  1207 			    goto continueX;
  1208 			}
  1208 			}
  1209 		    }
  1209 		    }
  1210 		}
  1210 		}
  1249 			    }
  1249 			    }
  1250 #else
  1250 #else
  1251 			    __interpret(aBlock, 2, nil, IBLOCK_ARG, nil, nil, __mkSmallInteger(index), el);
  1251 			    __interpret(aBlock, 2, nil, IBLOCK_ARG, nil, nil, __mkSmallInteger(index), el);
  1252 #endif
  1252 #endif
  1253 			} else {
  1253 			} else {
  1254 			    (*val2.ilc_func)(aBlock, 
  1254 			    (*val2.ilc_func)(aBlock,
  1255 						@symbol(value:value:), 
  1255 						@symbol(value:value:),
  1256 						nil, &val2, 
  1256 						nil, &val2,
  1257 						__mkSmallInteger(index),
  1257 						__mkSmallInteger(index),
  1258 						el);
  1258 						el);
  1259 			}
  1259 			}
  1260 		    }
  1260 		    }
  1261 		}
  1261 		}
  1274 
  1274 
  1275 		if (InterruptPending != nil) __interruptL(@line);
  1275 		if (InterruptPending != nil) __interruptL(@line);
  1276 
  1276 
  1277 		el = __InstPtr(self)->i_instvars[index];
  1277 		el = __InstPtr(self)->i_instvars[index];
  1278 		index++;
  1278 		index++;
  1279 		(*val2.ilc_func)(aBlock, 
  1279 		(*val2.ilc_func)(aBlock,
  1280 				    @symbol(value:value:), 
  1280 				    @symbol(value:value:),
  1281 				    nil, &val2, 
  1281 				    nil, &val2,
  1282 				    __mkSmallInteger(index),
  1282 				    __mkSmallInteger(index),
  1283 				    el);
  1283 				    el);
  1284 	    }
  1284 	    }
  1285 	    RETURN ( self );
  1285 	    RETURN ( self );
  1286 	}
  1286 	}
  1287     }
  1287     }
  1288 %}.
  1288 %}.
  1289     ^ super keysAndValuesDo:aBlock
  1289     ^ super keysAndValuesDo:aBlock
  1290 !
  1290 !
  1291 
  1291 
  1292 modifyingTraverse:aBlock 
  1292 modifyingTraverse:aBlock
  1293     "Evaluate aBlock for every element that is not an Array, 
  1293     "Evaluate aBlock for every element that is not an Array,
  1294      and recursively traverse Arrays.
  1294      and recursively traverse Arrays.
  1295 
  1295 
  1296      aBlock may return the original element or a new element.
  1296      aBlock may return the original element or a new element.
  1297      If a new element is returned, the element is changed to the new element."
  1297      If a new element is returned, the element is changed to the new element."
  1298     
  1298 
  1299     self 
  1299     self
  1300         keysAndValuesDo:[:eachIndex :eachElement | 
  1300 	keysAndValuesDo:[:eachIndex :eachElement |
  1301             eachElement isArray ifTrue:[
  1301 	    eachElement isArray ifTrue:[
  1302                 eachElement modifyingTraverse:aBlock
  1302 		eachElement modifyingTraverse:aBlock
  1303             ] ifFalse:[
  1303 	    ] ifFalse:[
  1304                 |newElement|
  1304 		|newElement|
  1305 
  1305 
  1306                 newElement := aBlock value:eachElement.
  1306 		newElement := aBlock value:eachElement.
  1307                 newElement ~~ eachElement ifTrue:[
  1307 		newElement ~~ eachElement ifTrue:[
  1308                     self at:eachIndex put:newElement.
  1308 		    self at:eachIndex put:newElement.
  1309                 ].
  1309 		].
  1310             ]
  1310 	    ]
  1311         ].
  1311 	].
  1312 
  1312 
  1313     "
  1313     "
  1314      example: replace all elements which are 10 with: 'changed'
  1314      example: replace all elements which are 10 with: 'changed'
  1315 
  1315 
  1316      #(1 2 (3 (4 5 (6 7) 8) 9 10) 11 (12 (13)) 14) copy 
  1316      #(1 2 (3 (4 5 (6 7) 8) 9 10) 11 (12 (13)) 14) copy
  1317          modifyingTraverse:[:el |
  1317 	 modifyingTraverse:[:el |
  1318             el = 10 ifTrue:['changed'] ifFalse:[el]
  1318 	    el = 10 ifTrue:['changed'] ifFalse:[el]
  1319          ];
  1319 	 ];
  1320          inspect
  1320 	 inspect
  1321     "
  1321     "
  1322 !
  1322 !
  1323 
  1323 
  1324 reverseDo:aBlock
  1324 reverseDo:aBlock
  1325     "evaluate the argument, aBlock for each element in the collection in reverse order.
  1325     "evaluate the argument, aBlock for each element in the collection in reverse order.
  1372 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &(__InstPtr(self)->i_instvars[index]));
  1372 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &(__InstPtr(self)->i_instvars[index]));
  1373 #else
  1373 #else
  1374 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __InstPtr(self)->i_instvars[index]);
  1374 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __InstPtr(self)->i_instvars[index]);
  1375 #endif
  1375 #endif
  1376 			} else {
  1376 			} else {
  1377 			    (*val.ilc_func)(aBlock, 
  1377 			    (*val.ilc_func)(aBlock,
  1378 					    @symbol(value:), 
  1378 					    @symbol(value:),
  1379 					    nil, &val, 
  1379 					    nil, &val,
  1380 					    __InstPtr(self)->i_instvars[index]);
  1380 					    __InstPtr(self)->i_instvars[index]);
  1381 			}
  1381 			}
  1382 		    }
  1382 		    }
  1383 		}
  1383 		}
  1384 
  1384 
  1392 	     * not a block - send it #value:
  1392 	     * not a block - send it #value:
  1393 	     */
  1393 	     */
  1394 	    for (index=nIndex-1; index >= endIndex; index--) {
  1394 	    for (index=nIndex-1; index >= endIndex; index--) {
  1395 		if (InterruptPending != nil) __interruptL(@line);
  1395 		if (InterruptPending != nil) __interruptL(@line);
  1396 
  1396 
  1397 		(*val.ilc_func)(aBlock, 
  1397 		(*val.ilc_func)(aBlock,
  1398 				@symbol(value:), 
  1398 				@symbol(value:),
  1399 				nil, &val, 
  1399 				nil, &val,
  1400 				__InstPtr(self)->i_instvars[index]);
  1400 				__InstPtr(self)->i_instvars[index]);
  1401 	    }
  1401 	    }
  1402 	    RETURN ( self );
  1402 	    RETURN ( self );
  1403 	}
  1403 	}
  1404     }
  1404     }
  1405 %}.
  1405 %}.
  1406     ^ super reverseDo:aBlock
  1406     ^ super reverseDo:aBlock
  1407 !
  1407 !
  1408 
  1408 
  1409 traverse:aBlock
  1409 traverse:aBlock
  1410     "Evaluate aBlock for every element that is not an Array, 
  1410     "Evaluate aBlock for every element that is not an Array,
  1411      and recursively traverse Arrays.
  1411      and recursively traverse Arrays.
  1412      Implemented here to support better search for selectors in
  1412      Implemented here to support better search for selectors in
  1413      literal arrays - might be a good idea to move it up in the collection
  1413      literal arrays - might be a good idea to move it up in the collection
  1414      hierarchy, since this may be a useful method for other collections
  1414      hierarchy, since this may be a useful method for other collections
  1415      as well."
  1415      as well."
  1424 
  1424 
  1425      |s|
  1425      |s|
  1426 
  1426 
  1427      s := WriteStream on:Array new.
  1427      s := WriteStream on:Array new.
  1428      #(1 2 (3 (4 5 (6 7) 8) 9 10) 11 (12 (13)) 14) traverse:[:el | s nextPut:el].
  1428      #(1 2 (3 (4 5 (6 7) 8) 9 10) 11 (12 (13)) 14) traverse:[:el | s nextPut:el].
  1429      s contents 
  1429      s contents
  1430     "
  1430     "
  1431     "
  1431     "
  1432      example: deep search
  1432      example: deep search
  1433 
  1433 
  1434      #(1 2 (3 (4 5 (6 7) 8) 9 10) 11 (12 (13)) 14) traverse:[:el | 
  1434      #(1 2 (3 (4 5 (6 7) 8) 9 10) 11 (12 (13)) 14) traverse:[:el |
  1435 	el == 10 ifTrue:[Transcript showCR:'found']
  1435 	el == 10 ifTrue:[Transcript showCR:'found']
  1436      ]
  1436      ]
  1437     "
  1437     "
  1438 
  1438 
  1439     "Modified: 26.3.1996 / 17:08:10 / cg"
  1439     "Modified: 26.3.1996 / 17:08:10 / cg"
  1468 		}
  1468 		}
  1469 #else
  1469 #else
  1470 # ifdef FAST_MEMSET
  1470 # ifdef FAST_MEMSET
  1471 		if ((INT)anObject == 0) {
  1471 		if ((INT)anObject == 0) {
  1472 		    memset(dst, 0, __OBJS2BYTES__(endIndex-index+1));
  1472 		    memset(dst, 0, __OBJS2BYTES__(endIndex-index+1));
  1473 		} else 
  1473 		} else
  1474 # endif
  1474 # endif
  1475 		{
  1475 		{
  1476 # ifdef __UNROLL_LOOPS__
  1476 # ifdef __UNROLL_LOOPS__
  1477 		    {
  1477 		    {
  1478 			int i8;
  1478 			int i8;
  1515     int repStopIndex;
  1515     int repStopIndex;
  1516     REGISTER int repStartIndex;
  1516     REGISTER int repStartIndex;
  1517     REGISTER OBJ t;
  1517     REGISTER OBJ t;
  1518     REGISTER int count;
  1518     REGISTER int count;
  1519     OBJ myClass;
  1519     OBJ myClass;
  1520     
  1520 
  1521     if (
  1521     if (
  1522 	(__ClassInstPtr((myClass = __qClass(self)))->c_ninstvars == __mkSmallInteger(0))
  1522 	(__ClassInstPtr((myClass = __qClass(self)))->c_ninstvars == __mkSmallInteger(0))
  1523      && __isNonNilObject(aCollection)
  1523      && __isNonNilObject(aCollection)
  1524      && (((t = __qClass(aCollection)) == Array) || (t == myClass))
  1524      && (((t = __qClass(aCollection)) == Array) || (t == myClass))
  1525      && __bothSmallInteger(start, stop)
  1525      && __bothSmallInteger(start, stop)
  1538 		    repStopIndex = repStartIndex + (stopIndex - startIndex);
  1538 		    repStopIndex = repStartIndex + (stopIndex - startIndex);
  1539 		    if (repStopIndex < repNIndex) {
  1539 		    if (repStopIndex < repNIndex) {
  1540 			src = &(__InstPtr(aCollection)->i_instvars[repStartIndex]);
  1540 			src = &(__InstPtr(aCollection)->i_instvars[repStartIndex]);
  1541 			dst = &(__InstPtr(self)->i_instvars[startIndex]);
  1541 			dst = &(__InstPtr(self)->i_instvars[startIndex]);
  1542 			if (aCollection == self) {
  1542 			if (aCollection == self) {
  1543 			    /* 
  1543 			    /*
  1544 			     * no need to check stores if copying
  1544 			     * no need to check stores if copying
  1545 			     * from myself
  1545 			     * from myself
  1546 			     */
  1546 			     */
  1547 
  1547 
  1548 			    /* 
  1548 			    /*
  1549 			     * take care of overlapping copy
  1549 			     * take care of overlapping copy
  1550 			     * do not depend on memset being smart enough
  1550 			     * do not depend on memset being smart enough
  1551 			     * (some are not ;-)
  1551 			     * (some are not ;-)
  1552 			     */
  1552 			     */
  1553 			    if (src < dst) {
  1553 			    if (src < dst) {
  1575 			    }
  1575 			    }
  1576 #ifdef SOFTWARE_PIPELINE
  1576 #ifdef SOFTWARE_PIPELINE
  1577 			    {
  1577 			    {
  1578 				OBJ t1;
  1578 				OBJ t1;
  1579 
  1579 
  1580 				/* 
  1580 				/*
  1581 				 * the loop below fetches one longWord behind
  1581 				 * the loop below fetches one longWord behind
  1582 				 * this should not be a problem
  1582 				 * this should not be a problem
  1583 				 */
  1583 				 */
  1584 				t1 = src[0];
  1584 				t1 = src[0];
  1585 				count--;
  1585 				count--;
  1664 
  1664 
  1665 !Array methodsFor:'printing & storing'!
  1665 !Array methodsFor:'printing & storing'!
  1666 
  1666 
  1667 displayStringName
  1667 displayStringName
  1668     self class == Array ifTrue:[
  1668     self class == Array ifTrue:[
  1669         ^ '#'
  1669 	^ '#'
  1670     ].
  1670     ].
  1671     ^ super displayStringName.
  1671     ^ super displayStringName.
  1672 !
  1672 !
  1673 
  1673 
  1674 printOn:aStream
  1674 printOn:aStream
  1675     "append a printed representation of the receiver to aStream"
  1675     "append a printed representation of the receiver to aStream"
  1676 
  1676 
  1677     self isLiteral ifTrue:[
  1677     self isLiteral ifTrue:[
  1678         |limit firstOne s|
  1678 	|limit firstOne s|
  1679 
  1679 
  1680         thisContext isRecursive ifTrue:[
  1680 	thisContext isRecursive ifTrue:[
  1681             'Array [error]: printOn: of self referencing collection.' errorPrintCR.
  1681 	    'Array [error]: printOn: of self referencing collection.' errorPrintCR.
  1682             aStream nextPutAll:'#("recursive")'.
  1682 	    aStream nextPutAll:'#("recursive")'.
  1683             ^ self
  1683 	    ^ self
  1684         ].
  1684 	].
  1685 
  1685 
  1686         aStream nextPutAll:'#('.
  1686 	aStream nextPutAll:'#('.
  1687         firstOne := true.
  1687 	firstOne := true.
  1688 
  1688 
  1689         "
  1689 	"
  1690          if aStream is not positionable, create an temporary positionable stream
  1690 	 if aStream is not positionable, create an temporary positionable stream
  1691          (needed for limit calculation)
  1691 	 (needed for limit calculation)
  1692         "
  1692 	"
  1693         aStream isPositionable ifTrue:[
  1693 	aStream isPositionable ifTrue:[
  1694             s := aStream.
  1694 	    s := aStream.
  1695         ] ifFalse:[
  1695 	] ifFalse:[
  1696             s := WriteStream on:(String uninitializedNew:50).
  1696 	    s := WriteStream on:(String uninitializedNew:50).
  1697         ].
  1697 	].
  1698         limit := s position1Based + self maxPrint.
  1698 	limit := s position1Based + self maxPrint.
  1699 
  1699 
  1700         self printElementsDo:[:element |
  1700 	self printElementsDo:[:element |
  1701             firstOne ifFalse:[
  1701 	    firstOne ifFalse:[
  1702                 s space
  1702 		s space
  1703             ] ifTrue:[
  1703 	    ] ifTrue:[
  1704                 firstOne := false
  1704 		firstOne := false
  1705             ].
  1705 	    ].
  1706             (s position1Based >= limit) ifTrue:[
  1706 	    (s position1Based >= limit) ifTrue:[
  1707                 s ~~ aStream ifTrue:[
  1707 		s ~~ aStream ifTrue:[
  1708                     aStream nextPutAll:(s contents).
  1708 		    aStream nextPutAll:(s contents).
  1709                 ].
  1709 		].
  1710                 aStream nextPutAll:'...etc...)'.
  1710 		aStream nextPutAll:'...etc...)'.
  1711                 ^ self
  1711 		^ self
  1712             ] ifFalse:[
  1712 	    ] ifFalse:[
  1713                 element printOn:s.
  1713 		element printOn:s.
  1714             ].
  1714 	    ].
  1715         ].
  1715 	].
  1716         s ~~ aStream ifTrue:[
  1716 	s ~~ aStream ifTrue:[
  1717             aStream nextPutAll:(s contents).
  1717 	    aStream nextPutAll:(s contents).
  1718         ].
  1718 	].
  1719         aStream nextPut:$)
  1719 	aStream nextPut:$)
  1720     ] ifFalse:[
  1720     ] ifFalse:[
  1721         super printOn:aStream
  1721 	super printOn:aStream
  1722     ]
  1722     ]
  1723 
  1723 
  1724     "
  1724     "
  1725      #(1 2 $a 'hello' sym kewordSymbol:with: #'funny symbol') printString 
  1725      #(1 2 $a 'hello' sym kewordSymbol:with: #'funny symbol') printString
  1726      #(1 2 $a [1 2 3] true false nil #true #false #nil) printString 
  1726      #(1 2 $a [1 2 3] true false nil #true #false #nil) printString
  1727     "
  1727     "
  1728 
  1728 
  1729     "Created: 20.11.1995 / 11:16:58 / cg"
  1729     "Created: 20.11.1995 / 11:16:58 / cg"
  1730 !
  1730 !
  1731 
  1731 
  1732 storeArrayElementOn:aStream
  1732 storeArrayElementOn:aStream
  1733     "Store as element of an array. Omit the leading '#'"
  1733     "Store as element of an array. Omit the leading '#'"
  1734 
  1734 
  1735     self isLiteral ifTrue:[
  1735     self isLiteral ifTrue:[
  1736         aStream nextPut:$(.
  1736 	aStream nextPut:$(.
  1737         self 
  1737 	self
  1738             do:[:element | element storeArrayElementOn:aStream]
  1738 	    do:[:element | element storeArrayElementOn:aStream]
  1739             separatedBy:[aStream space].
  1739 	    separatedBy:[aStream space].
  1740         aStream nextPut:$).
  1740 	aStream nextPut:$).
  1741         ^ self.
  1741 	^ self.
  1742     ].
  1742     ].
  1743     super storeArrayElementOn:aStream
  1743     super storeArrayElementOn:aStream
  1744 
  1744 
  1745     "
  1745     "
  1746      #(1 2 3 4 5) storeOn:Transcript   
  1746      #(1 2 3 4 5) storeOn:Transcript
  1747      #(1 2 3 4 5) storeArrayElementOn:Transcript   
  1747      #(1 2 3 4 5) storeArrayElementOn:Transcript
  1748     "
  1748     "
  1749 !
  1749 !
  1750 
  1750 
  1751 storeOn:aStream
  1751 storeOn:aStream
  1752     "append a printed representation of the receiver to aStream,
  1752     "append a printed representation of the receiver to aStream,
  1753      which allows reconstructing it via readFrom:.
  1753      which allows reconstructing it via readFrom:.
  1754      Redefined to output a somewhat more user friendly string."
  1754      Redefined to output a somewhat more user friendly string."
  1755 
  1755 
  1756     self isLiteral ifTrue:[
  1756     self isLiteral ifTrue:[
  1757         aStream nextPutAll:'#('.
  1757 	aStream nextPutAll:'#('.
  1758         self do:[:element | element storeArrayElementOn:aStream]
  1758 	self do:[:element | element storeArrayElementOn:aStream]
  1759              separatedBy:[aStream space].
  1759 	     separatedBy:[aStream space].
  1760         aStream nextPut:$)
  1760 	aStream nextPut:$)
  1761     ] ifFalse:[
  1761     ] ifFalse:[
  1762         super storeOn:aStream
  1762 	super storeOn:aStream
  1763     ]
  1763     ]
  1764 
  1764 
  1765     "
  1765     "
  1766      #(1 2 $a 'hello' sym kewordSymbol:with: #'funny symbol') storeString 
  1766      #(1 2 $a 'hello' sym kewordSymbol:with: #'funny symbol') storeString
  1767      #(1 2 $a [1 2 3] true false nil #true #false #nil) storeString 
  1767      #(1 2 $a [1 2 3] true false nil #true #false #nil) storeString
  1768     "
  1768     "
  1769 
  1769 
  1770     "Created: 20.11.1995 / 11:16:58 / cg"
  1770     "Created: 20.11.1995 / 11:16:58 / cg"
  1771 ! !
  1771 ! !
  1772 
  1772 
  1784 
  1784 
  1785 refersToLiteral:aLiteral
  1785 refersToLiteral:aLiteral
  1786     "return true if the receiver or recursively any array element in the
  1786     "return true if the receiver or recursively any array element in the
  1787      receiver referes to aLiteral (i.e. a deep search)"
  1787      receiver referes to aLiteral (i.e. a deep search)"
  1788 
  1788 
  1789     self do: [ :el | 
  1789     self do: [ :el |
  1790 	el == aLiteral ifTrue:[^true].
  1790 	el == aLiteral ifTrue:[^true].
  1791 	el class == Array ifTrue:[
  1791 	el class == Array ifTrue:[
  1792 	    (el refersToLiteral: aLiteral) ifTrue: [^true]
  1792 	    (el refersToLiteral: aLiteral) ifTrue: [^true]
  1793 	]
  1793 	]
  1794     ].
  1794     ].
  1795     ^ false
  1795     ^ false
  1796 
  1796 
  1797     "
  1797     "
  1798      #(1 2 3) refersToLiteral:#foo  
  1798      #(1 2 3) refersToLiteral:#foo
  1799      #(1 2 3 foo bar baz) refersToLiteral:#foo 
  1799      #(1 2 3 foo bar baz) refersToLiteral:#foo
  1800      #(1 2 3 (((bar foo))) bar baz) refersToLiteral:#foo  
  1800      #(1 2 3 (((bar foo))) bar baz) refersToLiteral:#foo
  1801     "
  1801     "
  1802 
  1802 
  1803     "Modified: / 18.8.2000 / 21:18:14 / cg"
  1803     "Modified: / 18.8.2000 / 21:18:14 / cg"
  1804 !
  1804 !
  1805 
  1805 
  1806 refersToLiteralMatching:aMatchPattern
  1806 refersToLiteralMatching:aMatchPattern
  1807     "return true if the receiver or recursively any array element in the
  1807     "return true if the receiver or recursively any array element in the
  1808      receiver is symbolic and matches aMatchPattern (i.e. a deep search)"
  1808      receiver is symbolic and matches aMatchPattern (i.e. a deep search)"
  1809 
  1809 
  1810     self do:[ :el | 
  1810     self do:[ :el |
  1811         (el isSymbol and:[ aMatchPattern match: el]) ifTrue:[^true].
  1811 	(el isSymbol and:[ aMatchPattern match: el]) ifTrue:[^true].
  1812         el class == Array ifTrue:[
  1812 	el class == Array ifTrue:[
  1813             (el refersToLiteralMatching: aMatchPattern) ifTrue: [^true]
  1813 	    (el refersToLiteralMatching: aMatchPattern) ifTrue: [^true]
  1814         ]
  1814 	]
  1815     ].
  1815     ].
  1816     ^ false
  1816     ^ false
  1817 
  1817 
  1818     "
  1818     "
  1819      #(1 2 3) refersToLiteralMatching:#foo  
  1819      #(1 2 3) refersToLiteralMatching:#foo
  1820      #(1 2 3 foo bar baz) refersToLiteralMatching:#foo 
  1820      #(1 2 3 foo bar baz) refersToLiteralMatching:#foo
  1821      #(1 2 3 (((bar foo))) bar baz) refersToLiteralMatching:#foo  
  1821      #(1 2 3 (((bar foo))) bar baz) refersToLiteralMatching:#foo
  1822     "
  1822     "
  1823 
  1823 
  1824     "Modified: / 18-08-2000 / 21:18:14 / cg"
  1824     "Modified: / 18-08-2000 / 21:18:14 / cg"
  1825     "Created: / 26-07-2012 / 15:38:01 / cg"
  1825     "Created: / 26-07-2012 / 15:38:01 / cg"
  1826 !
  1826 !
  1839 %}
  1839 %}
  1840 ! !
  1840 ! !
  1841 
  1841 
  1842 !Array methodsFor:'searching'!
  1842 !Array methodsFor:'searching'!
  1843 
  1843 
  1844 identityIndexOf:anElement or:alternative 
  1844 identityIndexOf:anElement or:alternative
  1845     "search the array for anElement or alternative; 
  1845     "search the array for anElement or alternative;
  1846      return the index of anElement if found, or the index of anAlternative,
  1846      return the index of anElement if found, or the index of anAlternative,
  1847      if not found. If anAlternative is also not found, return 0.
  1847      if not found. If anAlternative is also not found, return 0.
  1848      This is a special interface for high-speed searching in an array
  1848      This is a special interface for high-speed searching in an array
  1849      and at the same time searching for an empty slot.
  1849      and at the same time searching for an empty slot.
  1850      Do not use this method for your application classes, since it is
  1850      Do not use this method for your application classes, since it is
  1861 
  1861 
  1862     index = 0;
  1862     index = 0;
  1863     nInsts = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
  1863     nInsts = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
  1864     index += nInsts;
  1864     index += nInsts;
  1865     nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  1865     nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  1866     el1 = anElement; el2 = alternative; 
  1866     el1 = anElement; el2 = alternative;
  1867     op = & (__InstPtr(self)->i_instvars[index]);
  1867     op = & (__InstPtr(self)->i_instvars[index]);
  1868     while (index++ < nIndex) {
  1868     while (index++ < nIndex) {
  1869 	if ((o = *op++) == el1) {
  1869 	if ((o = *op++) == el1) {
  1870 	    RETURN ( __mkSmallInteger(index - nInsts) );
  1870 	    RETURN ( __mkSmallInteger(index - nInsts) );
  1871 	}
  1871 	}
  1881 
  1881 
  1882     "
  1882     "
  1883      #(1 2 3 4 5 6 7 8 9) identityIndexOf:3 or:5
  1883      #(1 2 3 4 5 6 7 8 9) identityIndexOf:3 or:5
  1884      #(1 2 0 4 5 6 7 8 9) identityIndexOf:3 or:5
  1884      #(1 2 0 4 5 6 7 8 9) identityIndexOf:3 or:5
  1885      #(1 2 0 4 5 6 7 3 9) identityIndexOf:3 or:5
  1885      #(1 2 0 4 5 6 7 3 9) identityIndexOf:3 or:5
  1886      #(1 2 3 4 5 nil 7 3 9) identityIndexOf:3 or:nil 
  1886      #(1 2 3 4 5 nil 7 3 9) identityIndexOf:3 or:nil
  1887      #(1 2 nil 4 5 6 7 3 9) identityIndexOf:3 or:nil  
  1887      #(1 2 nil 4 5 6 7 3 9) identityIndexOf:3 or:nil
  1888      #(1 2 nil 4 5 6 7 8 9) identityIndexOf:3 or:nil 
  1888      #(1 2 nil 4 5 6 7 8 9) identityIndexOf:3 or:nil
  1889      #() identityIndexOf:3 or:nil        
  1889      #() identityIndexOf:3 or:nil
  1890      #(1 2) identityIndexOf:3 or:nil 
  1890      #(1 2) identityIndexOf:3 or:nil
  1891     "
  1891     "
  1892 !
  1892 !
  1893 
  1893 
  1894 identityIndexOf:anElement startingAt:start
  1894 identityIndexOf:anElement startingAt:start
  1895     "search the array for anElement; return index if found, 0 otherwise
  1895     "search the array for anElement; return index if found, 0 otherwise
  1917 		OBJ *p;
  1917 		OBJ *p;
  1918 
  1918 
  1919 		p = memsrch4(op, (INT)el, (nIndex - index));
  1919 		p = memsrch4(op, (INT)el, (nIndex - index));
  1920 		if (p) {
  1920 		if (p) {
  1921 		    index += (p - op + 1);
  1921 		    index += (p - op + 1);
  1922 		    RETURN ( __mkSmallInteger(index) ); 
  1922 		    RETURN ( __mkSmallInteger(index) );
  1923 		}
  1923 		}
  1924 	    }
  1924 	    }
  1925 #else
  1925 #else
  1926 
  1926 
  1927 # ifdef __UNROLL_LOOPS__
  1927 # ifdef __UNROLL_LOOPS__
  1944 		 * when found; without the goto, we branch always.
  1944 		 * when found; without the goto, we branch always.
  1945 		 * Pipelined CPUs do usually not like taken branches.
  1945 		 * Pipelined CPUs do usually not like taken branches.
  1946 		 */
  1946 		 */
  1947 
  1947 
  1948 		unsigned int i8;
  1948 		unsigned int i8;
  1949                 
  1949 
  1950 		while ((i8 = index + 8) < nIndex) {
  1950 		while ((i8 = index + 8) < nIndex) {
  1951 		    if (op[0] == el) goto found1;
  1951 		    if (op[0] == el) goto found1;
  1952 		    if (op[1] == el) goto found2;
  1952 		    if (op[1] == el) goto found2;
  1953 		    if (op[2] == el) goto found3;
  1953 		    if (op[2] == el) goto found3;
  1954 		    if (op[3] == el) goto found4;
  1954 		    if (op[3] == el) goto found4;
  1995 %}.
  1995 %}.
  1996     ^ super identityIndexOf:anElement startingAt:start
  1996     ^ super identityIndexOf:anElement startingAt:start
  1997 !
  1997 !
  1998 
  1998 
  1999 identityIndexOf:anElement startingAt:start endingAt:stop
  1999 identityIndexOf:anElement startingAt:start endingAt:stop
  2000     "search the array for anElement in the range start..stop; 
  2000     "search the array for anElement in the range start..stop;
  2001      return the index if found, 0 otherwise.
  2001      return the index if found, 0 otherwise.
  2002      - reimplemented for speed when searching in OrderedCollections"
  2002      - reimplemented for speed when searching in OrderedCollections"
  2003 
  2003 
  2004 %{  /* NOCONTEXT */
  2004 %{  /* NOCONTEXT */
  2005 
  2005 
  2028 		OBJ *p;
  2028 		OBJ *p;
  2029 
  2029 
  2030 		p = memsrch4(op, (INT)el, (lastIndex - index));
  2030 		p = memsrch4(op, (INT)el, (lastIndex - index));
  2031 		if (p) {
  2031 		if (p) {
  2032 		    index += (p - op + 1);
  2032 		    index += (p - op + 1);
  2033 		    RETURN ( __mkSmallInteger(index) ); 
  2033 		    RETURN ( __mkSmallInteger(index) );
  2034 		}
  2034 		}
  2035 	    }
  2035 	    }
  2036 #else
  2036 #else
  2037 
  2037 
  2038 # ifdef __UNROLL_LOOPS__
  2038 # ifdef __UNROLL_LOOPS__
  2102     static struct inlineCache eq = _ILC1;
  2102     static struct inlineCache eq = _ILC1;
  2103     OBJ myClass, e;
  2103     OBJ myClass, e;
  2104 
  2104 
  2105     myClass = __qClass(self);
  2105     myClass = __qClass(self);
  2106     if ( __isSmallInteger(start) ) {
  2106     if ( __isSmallInteger(start) ) {
  2107         index = __intVal(start) - 1;
  2107 	index = __intVal(start) - 1;
  2108         if (index >= 0) {
  2108 	if (index >= 0) {
  2109             nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars);
  2109 	    nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars);
  2110             index += nInsts;
  2110 	    index += nInsts;
  2111             nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2111 	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2112 
  2112 
  2113             e = anElement;
  2113 	    e = anElement;
  2114             if (e != nil) {
  2114 	    if (e != nil) {
  2115                 /*
  2115 		/*
  2116                  * special kludge to search for a string;
  2116 		 * special kludge to search for a string;
  2117                  * this is so common, that its worth a special case
  2117 		 * this is so common, that its worth a special case
  2118                  */
  2118 		 */
  2119 #define SPECIAL_STRING_OPT
  2119 #define SPECIAL_STRING_OPT
  2120 #ifdef SPECIAL_STRING_OPT
  2120 #ifdef SPECIAL_STRING_OPT
  2121                 if (__isStringLike(e)) {
  2121 		if (__isStringLike(e)) {
  2122                     while (index < nIndex) {
  2122 		    while (index < nIndex) {
  2123                         element = __InstPtr(self)->i_instvars[index++];
  2123 			element = __InstPtr(self)->i_instvars[index++];
  2124                         if (__isNonNilObject(element)) {
  2124 			if (__isNonNilObject(element)) {
  2125                             if (element == e) {
  2125 			    if (element == e) {
  2126                                 RETURN ( __mkSmallInteger(index - nInsts) );
  2126 				RETURN ( __mkSmallInteger(index - nInsts) );
  2127                             }
  2127 			    }
  2128                             if (__qClass(element) == @global(String)) {
  2128 			    if (__qClass(element) == @global(String)) {
  2129                                 if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
  2129 				if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
  2130                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2130 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2131                                 }
  2131 				}
  2132                             } else {
  2132 			    } else {
  2133                                 if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
  2133 				if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
  2134                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2134 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2135                                 }
  2135 				}
  2136                                 /*
  2136 				/*
  2137                                  * send of #= could have lead to a GC - refetch e
  2137 				 * send of #= could have lead to a GC - refetch e
  2138                                  */
  2138 				 */
  2139                                 e = anElement;
  2139 				e = anElement;
  2140                             }
  2140 			    }
  2141                         }
  2141 			}
  2142                     }
  2142 		    }
  2143                     RETURN (__mkSmallInteger(0));
  2143 		    RETURN (__mkSmallInteger(0));
  2144                 }
  2144 		}
  2145 #endif
  2145 #endif
  2146 #ifdef MAKES_IT_SLOWER_BUT_WHY
  2146 #ifdef MAKES_IT_SLOWER_BUT_WHY
  2147                 if (__isSmallInteger(e)) {
  2147 		if (__isSmallInteger(e)) {
  2148                     /* search for a small number */
  2148 		    /* search for a small number */
  2149                     while (index < nIndex) {
  2149 		    while (index < nIndex) {
  2150                         element = __InstPtr(self)->i_instvars[index++];
  2150 			element = __InstPtr(self)->i_instvars[index++];
  2151                         if (element == e) {
  2151 			if (element == e) {
  2152                             RETURN ( __mkSmallInteger(index - nInsts) );
  2152 			    RETURN ( __mkSmallInteger(index - nInsts) );
  2153                         }
  2153 			}
  2154                         if (!__isSmallInteger(element)) {
  2154 			if (!__isSmallInteger(element)) {
  2155                             if (element != nil) {
  2155 			    if (element != nil) {
  2156                                 if ((*eq.ilc_func)(e,
  2156 				if ((*eq.ilc_func)(e,
  2157                                                    @symbol(=), 
  2157 						   @symbol(=),
  2158                                                    nil,&eq,
  2158 						   nil,&eq,
  2159                                                    element) == true) {
  2159 						   element) == true) {
  2160                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2160 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2161                                 }
  2161 				}
  2162                                 /*
  2162 				/*
  2163                                  * send of #= could have lead to a GC - refetch e
  2163 				 * send of #= could have lead to a GC - refetch e
  2164                                  */
  2164 				 */
  2165                                 e = anElement;
  2165 				e = anElement;
  2166                             }
  2166 			    }
  2167                         }
  2167 			}
  2168                     }
  2168 		    }
  2169                     RETURN (__mkSmallInteger(0));
  2169 		    RETURN (__mkSmallInteger(0));
  2170                 }
  2170 		}
  2171 #endif /* MAKES_IT_SLOWER_BUT_WHY */
  2171 #endif /* MAKES_IT_SLOWER_BUT_WHY */
  2172 
  2172 
  2173                 while (index < nIndex) {
  2173 		while (index < nIndex) {
  2174                     element = __InstPtr(self)->i_instvars[index++];
  2174 		    element = __InstPtr(self)->i_instvars[index++];
  2175                     if (element != nil) {
  2175 		    if (element != nil) {
  2176                         if ((element == e) 
  2176 			if ((element == e)
  2177                          || ((*eq.ilc_func)(e,
  2177 			 || ((*eq.ilc_func)(e,
  2178                                             @symbol(=), 
  2178 					    @symbol(=),
  2179                                             nil,&eq,
  2179 					    nil,&eq,
  2180                                             element) == true)) {
  2180 					    element) == true)) {
  2181                             RETURN ( __mkSmallInteger(index - nInsts) );
  2181 			    RETURN ( __mkSmallInteger(index - nInsts) );
  2182                         }
  2182 			}
  2183                         /*
  2183 			/*
  2184                          * send of #= could have lead to a GC - refetch e
  2184 			 * send of #= could have lead to a GC - refetch e
  2185                          */
  2185 			 */
  2186                         e = anElement;
  2186 			e = anElement;
  2187                     }
  2187 		    }
  2188                 }
  2188 		}
  2189             } else {
  2189 	    } else {
  2190                 OBJ slf = self;
  2190 		OBJ slf = self;
  2191 
  2191 
  2192                 /* 
  2192 		/*
  2193                  * search for nil - do an identity-search
  2193 		 * search for nil - do an identity-search
  2194                  */
  2194 		 */
  2195 #ifdef __UNROLL_LOOPS__
  2195 #ifdef __UNROLL_LOOPS__
  2196                 {
  2196 		{
  2197                     unsigned int i8;
  2197 		    unsigned int i8;
  2198 
  2198 
  2199                     while ((i8 = index + 8) < nIndex) {
  2199 		    while ((i8 = index + 8) < nIndex) {
  2200                         if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2200 			if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2201                         if (__InstPtr(slf)->i_instvars[index+1] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 2) ); }
  2201 			if (__InstPtr(slf)->i_instvars[index+1] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 2) ); }
  2202                         if (__InstPtr(slf)->i_instvars[index+2] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 3) ); }
  2202 			if (__InstPtr(slf)->i_instvars[index+2] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 3) ); }
  2203                         if (__InstPtr(slf)->i_instvars[index+3] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 4) ); }
  2203 			if (__InstPtr(slf)->i_instvars[index+3] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 4) ); }
  2204                         if (__InstPtr(slf)->i_instvars[index+4] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 5) ); }
  2204 			if (__InstPtr(slf)->i_instvars[index+4] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 5) ); }
  2205                         if (__InstPtr(slf)->i_instvars[index+5] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 6) ); }
  2205 			if (__InstPtr(slf)->i_instvars[index+5] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 6) ); }
  2206                         if (__InstPtr(slf)->i_instvars[index+6] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 7) ); }
  2206 			if (__InstPtr(slf)->i_instvars[index+6] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 7) ); }
  2207                         if (__InstPtr(slf)->i_instvars[index+7] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 8) ); }
  2207 			if (__InstPtr(slf)->i_instvars[index+7] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 8) ); }
  2208                         index = i8;
  2208 			index = i8;
  2209                     }
  2209 		    }
  2210                 }
  2210 		}
  2211 #endif
  2211 #endif
  2212 
  2212 
  2213                 while (index < nIndex) {
  2213 		while (index < nIndex) {
  2214                     if (__InstPtr(slf)->i_instvars[index++] == nil) {
  2214 		    if (__InstPtr(slf)->i_instvars[index++] == nil) {
  2215                         RETURN ( __mkSmallInteger(index - nInsts) );
  2215 			RETURN ( __mkSmallInteger(index - nInsts) );
  2216                     }
  2216 		    }
  2217                 }
  2217 		}
  2218             }
  2218 	    }
  2219         }
  2219 	}
  2220         RETURN (__mkSmallInteger(0));
  2220 	RETURN (__mkSmallInteger(0));
  2221     }
  2221     }
  2222 %}.
  2222 %}.
  2223     ^ super indexOf:anElement startingAt:start
  2223     ^ super indexOf:anElement startingAt:start
  2224 !
  2224 !
  2225 
  2225 
  2226 indexOf:anElement startingAt:start endingAt:stop
  2226 indexOf:anElement startingAt:start endingAt:stop
  2227     "search the array for anElement in the range start..stop; 
  2227     "search the array for anElement in the range start..stop;
  2228      Return the index if found, 0 otherwise.
  2228      Return the index if found, 0 otherwise.
  2229      - reimplemented for speed when searching in OrderedCollections"
  2229      - reimplemented for speed when searching in OrderedCollections"
  2230 
  2230 
  2231     |element|
  2231     |element|
  2232 %{
  2232 %{
  2236     static struct inlineCache eq = _ILC1;
  2236     static struct inlineCache eq = _ILC1;
  2237     OBJ myClass, e;
  2237     OBJ myClass, e;
  2238 
  2238 
  2239     myClass = __qClass(self);
  2239     myClass = __qClass(self);
  2240     if ( __bothSmallInteger(start, stop) ) {
  2240     if ( __bothSmallInteger(start, stop) ) {
  2241         index = __intVal(start) - 1;
  2241 	index = __intVal(start) - 1;
  2242         if (index >= 0) {
  2242 	if (index >= 0) {
  2243             nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars);
  2243 	    nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars);
  2244             index += nInsts;
  2244 	    index += nInsts;
  2245             lastIndex = nInsts + __intVal(stop);
  2245 	    lastIndex = nInsts + __intVal(stop);
  2246             nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2246 	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2247             if (nIndex < lastIndex) {
  2247 	    if (nIndex < lastIndex) {
  2248                 lastIndex = nIndex;
  2248 		lastIndex = nIndex;
  2249             }
  2249 	    }
  2250 
  2250 
  2251             e = anElement;
  2251 	    e = anElement;
  2252 
  2252 
  2253             if (e != nil) {
  2253 	    if (e != nil) {
  2254                 /*
  2254 		/*
  2255                  * special kludge to search for a string;
  2255 		 * special kludge to search for a string;
  2256                  * this is so common, that its worth a special case
  2256 		 * this is so common, that its worth a special case
  2257                  */
  2257 		 */
  2258 #define SPECIAL_STRING_OPT
  2258 #define SPECIAL_STRING_OPT
  2259 #ifdef SPECIAL_STRING_OPT
  2259 #ifdef SPECIAL_STRING_OPT
  2260                 if (__isStringLike(e)) {
  2260 		if (__isStringLike(e)) {
  2261                     while (index < lastIndex) {
  2261 		    while (index < lastIndex) {
  2262                         element = __InstPtr(self)->i_instvars[index++];
  2262 			element = __InstPtr(self)->i_instvars[index++];
  2263                         if (__isNonNilObject(element)) {
  2263 			if (__isNonNilObject(element)) {
  2264                             if (element == e) {
  2264 			    if (element == e) {
  2265                                 RETURN ( __mkSmallInteger(index - nInsts) );
  2265 				RETURN ( __mkSmallInteger(index - nInsts) );
  2266                             }
  2266 			    }
  2267                             if (__qClass(element) == @global(String)) {
  2267 			    if (__qClass(element) == @global(String)) {
  2268                                 if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
  2268 				if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
  2269                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2269 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2270                                 }
  2270 				}
  2271                             } else {
  2271 			    } else {
  2272                                 if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
  2272 				if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
  2273                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2273 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2274                                 }
  2274 				}
  2275                                 /*
  2275 				/*
  2276                                  * send of #= could have lead to a GC - refetch e
  2276 				 * send of #= could have lead to a GC - refetch e
  2277                                  */
  2277 				 */
  2278                                 e = anElement;
  2278 				e = anElement;
  2279                             }
  2279 			    }
  2280                         }
  2280 			}
  2281                     }
  2281 		    }
  2282                     RETURN (__mkSmallInteger(0));
  2282 		    RETURN (__mkSmallInteger(0));
  2283                 }
  2283 		}
  2284 #endif
  2284 #endif
  2285                 if (__isSmallInteger(e)) {
  2285 		if (__isSmallInteger(e)) {
  2286                     /* search for a small number */
  2286 		    /* search for a small number */
  2287                     while (index < lastIndex) {
  2287 		    while (index < lastIndex) {
  2288                         element = __InstPtr(self)->i_instvars[index++];
  2288 			element = __InstPtr(self)->i_instvars[index++];
  2289                         if (element == e) {
  2289 			if (element == e) {
  2290                             RETURN ( __mkSmallInteger(index - nInsts) );
  2290 			    RETURN ( __mkSmallInteger(index - nInsts) );
  2291                         }
  2291 			}
  2292                         if (!__isSmallInteger(element)) {
  2292 			if (!__isSmallInteger(element)) {
  2293                             if ((*eq.ilc_func)(e,
  2293 			    if ((*eq.ilc_func)(e,
  2294                                                 @symbol(=), 
  2294 						@symbol(=),
  2295                                                 nil,&eq,
  2295 						nil,&eq,
  2296                                                 element) == true) {
  2296 						element) == true) {
  2297                                 RETURN ( __mkSmallInteger(index - nInsts) );
  2297 				RETURN ( __mkSmallInteger(index - nInsts) );
  2298                             }
  2298 			    }
  2299                             /*
  2299 			    /*
  2300                              * send of #= could have lead to a GC - refetch e
  2300 			     * send of #= could have lead to a GC - refetch e
  2301                              */
  2301 			     */
  2302                             e = anElement;
  2302 			    e = anElement;
  2303                         }
  2303 			}
  2304                     }
  2304 		    }
  2305                     RETURN (__mkSmallInteger(0));
  2305 		    RETURN (__mkSmallInteger(0));
  2306                 }
  2306 		}
  2307 
  2307 
  2308                 while (index < lastIndex) {
  2308 		while (index < lastIndex) {
  2309                     element = __InstPtr(self)->i_instvars[index++];
  2309 		    element = __InstPtr(self)->i_instvars[index++];
  2310                     if (element != nil) {
  2310 		    if (element != nil) {
  2311                         e = anElement;
  2311 			e = anElement;
  2312                         if ((element == e) 
  2312 			if ((element == e)
  2313                          || ((*eq.ilc_func)(e,
  2313 			 || ((*eq.ilc_func)(e,
  2314                                             @symbol(=), 
  2314 					    @symbol(=),
  2315                                             nil,&eq,
  2315 					    nil,&eq,
  2316                                             element) == true)) {
  2316 					    element) == true)) {
  2317                             RETURN ( __mkSmallInteger(index - nInsts) );
  2317 			    RETURN ( __mkSmallInteger(index - nInsts) );
  2318                         }
  2318 			}
  2319                     }
  2319 		    }
  2320                 }
  2320 		}
  2321             } else {
  2321 	    } else {
  2322                 OBJ slf = self;
  2322 		OBJ slf = self;
  2323 
  2323 
  2324                 /* 
  2324 		/*
  2325                  * search for nil - do an identity-search
  2325 		 * search for nil - do an identity-search
  2326                  */
  2326 		 */
  2327 #ifdef __UNROLL_LOOPS__
  2327 #ifdef __UNROLL_LOOPS__
  2328                 {
  2328 		{
  2329                     unsigned int i8;
  2329 		    unsigned int i8;
  2330 
  2330 
  2331                     while ((i8 = index + 8) < lastIndex) {
  2331 		    while ((i8 = index + 8) < lastIndex) {
  2332                         if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2332 			if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2333                         if (__InstPtr(slf)->i_instvars[index+1] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 2) ); }
  2333 			if (__InstPtr(slf)->i_instvars[index+1] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 2) ); }
  2334                         if (__InstPtr(slf)->i_instvars[index+2] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 3) ); }
  2334 			if (__InstPtr(slf)->i_instvars[index+2] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 3) ); }
  2335                         if (__InstPtr(slf)->i_instvars[index+3] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 4) ); }
  2335 			if (__InstPtr(slf)->i_instvars[index+3] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 4) ); }
  2336                         if (__InstPtr(slf)->i_instvars[index+4] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 5) ); }
  2336 			if (__InstPtr(slf)->i_instvars[index+4] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 5) ); }
  2337                         if (__InstPtr(slf)->i_instvars[index+5] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 6) ); }
  2337 			if (__InstPtr(slf)->i_instvars[index+5] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 6) ); }
  2338                         if (__InstPtr(slf)->i_instvars[index+6] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 7) ); }
  2338 			if (__InstPtr(slf)->i_instvars[index+6] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 7) ); }
  2339                         if (__InstPtr(slf)->i_instvars[index+7] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 8) ); }
  2339 			if (__InstPtr(slf)->i_instvars[index+7] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 8) ); }
  2340                         index = i8;
  2340 			index = i8;
  2341                     }
  2341 		    }
  2342                 }
  2342 		}
  2343 #endif
  2343 #endif
  2344                 while (index < lastIndex) {
  2344 		while (index < lastIndex) {
  2345                     if (__InstPtr(slf)->i_instvars[index++] == nil) {
  2345 		    if (__InstPtr(slf)->i_instvars[index++] == nil) {
  2346                         RETURN ( __mkSmallInteger(index - nInsts) );
  2346 			RETURN ( __mkSmallInteger(index - nInsts) );
  2347                     }
  2347 		    }
  2348                 }
  2348 		}
  2349             }
  2349 	    }
  2350         }
  2350 	}
  2351         RETURN (__mkSmallInteger(0));
  2351 	RETURN (__mkSmallInteger(0));
  2352     }
  2352     }
  2353 %}.
  2353 %}.
  2354     ^ super indexOf:anElement startingAt:start endingAt:stop
  2354     ^ super indexOf:anElement startingAt:start endingAt:stop
  2355 ! !
  2355 ! !
  2356 
  2356 
  2361      - reimplemented for speed"
  2361      - reimplemented for speed"
  2362 
  2362 
  2363     |element|
  2363     |element|
  2364 
  2364 
  2365 %{  /* NOCONTEXT */
  2365 %{  /* NOCONTEXT */
  2366     /* 
  2366     /*
  2367      * first, do a quick check using ==
  2367      * first, do a quick check using ==
  2368      * this does not need a context or message send.
  2368      * this does not need a context or message send.
  2369      * In many cases this will already find a match.
  2369      * In many cases this will already find a match.
  2370      */
  2370      */
  2371     REGISTER int index;
  2371     REGISTER int index;
  2457     REGISTER int index;
  2457     REGISTER int index;
  2458     REGISTER OBJ o;
  2458     REGISTER OBJ o;
  2459     unsigned int nIndex;
  2459     unsigned int nIndex;
  2460     static struct inlineCache eq = _ILC1;
  2460     static struct inlineCache eq = _ILC1;
  2461 
  2461 
  2462     /* 
  2462     /*
  2463      * then do a slow(er) check using =
  2463      * then do a slow(er) check using =
  2464      */
  2464      */
  2465 
  2465 
  2466     /* 
  2466     /*
  2467      * sorry: cannot access the stuff from above ...
  2467      * sorry: cannot access the stuff from above ...
  2468      */
  2468      */
  2469     nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2469     nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2470     index = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
  2470     index = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
  2471 
  2471 
  2523 isLiteral
  2523 isLiteral
  2524     "return true, if the receiver can be used as a literal constant in ST syntax
  2524     "return true, if the receiver can be used as a literal constant in ST syntax
  2525      (i.e. can be used in constant arrays)"
  2525      (i.e. can be used in constant arrays)"
  2526 
  2526 
  2527     "/ no, simply returning true here is a mistake:
  2527     "/ no, simply returning true here is a mistake:
  2528     "/ it could be a subclass of Array 
  2528     "/ it could be a subclass of Array
  2529     "/ (of which the compiler does not know at all ...)
  2529     "/ (of which the compiler does not know at all ...)
  2530 
  2530 
  2531     self class == Array ifFalse:[^ false].
  2531     self class == Array ifFalse:[^ false].
  2532 
  2532 
  2533     "/
  2533     "/
  2564 ! !
  2564 ! !
  2565 
  2565 
  2566 !Array class methodsFor:'documentation'!
  2566 !Array class methodsFor:'documentation'!
  2567 
  2567 
  2568 version
  2568 version
  2569     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.153 2013-01-02 12:32:00 cg Exp $'
  2569     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.154 2013-01-08 17:55:11 cg Exp $'
  2570 !
  2570 !
  2571 
  2571 
  2572 version_CVS
  2572 version_CVS
  2573     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.153 2013-01-02 12:32:00 cg Exp $'
  2573     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.154 2013-01-08 17:55:11 cg Exp $'
  2574 ! !
  2574 ! !