1 
2 //metadoc Sequence copyright Steve Dekorte 2002
3 //metadoc Sequence license BSD revised
4 /*metadoc Sequence description
5 A Sequence is a container for a list of data elements. Typically these elements are each 1 byte in size. A Sequence can be either mutable or immutable. When immutable, only the read-only methods can be used.
6 <p>
7 Terminology
8 <ul>
9 <li> Buffer: A mutable Sequence of single byte elements, typically in a binary encoding
10 <li> Symbol or String: A unique immutable Sequence, typically in a character encoding
11 </ul>
12 */
13 //metadoc Sequence category Core
14 
15 #pragma GCC diagnostic push
16 
17 //Suppresses incorrect warning from GCC about CTYPE never having value of -1
18 #ifndef __MINGW64__
19 #pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
20 #endif
21 
22 #include "IoSeq.h"
23 #include "IoState.h"
24 #include "IoCFunction.h"
25 #include "IoObject.h"
26 #include "IoNumber.h"
27 #include "IoMessage.h"
28 #include "IoList.h"
29 #include "IoMap.h"
30 #include <ctype.h>
31 #include <errno.h>
32 
33 #define DATA(self) ((UArray *)IoObject_dataPointer(self))
34 
35 #define IO_ASSERT_NOT_SYMBOL(self) IoAssertNotSymbol(self, m)
36 #define IO_ASSERT_NUMBER_ENCODING(self) IOASSERT(DATA(self)->encoding == CENCODING_NUMBER, "operation not valid on non-number encodings")
37 
IoAssertNotSymbol(IoSeq * self,IoMessage * m)38 static void IoAssertNotSymbol(IoSeq *self, IoMessage *m)
39 {
40 	if (ISSYMBOL(self))
41 	{
42 		IoState_error_(IOSTATE, m,
43 					"'%s' cannot be called on an immutable Sequence",
44 					CSTRING(IoMessage_name(m)));
45 	}
46 }
47 
IO_METHOD(IoSeq,setItemType)48 IO_METHOD(IoSeq, setItemType)
49 {
50 	/*doc Sequence setItemType(aTypeName)
51 	Sets the underlying machine type for the elements.
52 	Valid names are uint8, uint16, uint32, uint64, int8, int16, int32,
53 	int64, float32, and float64. Note that 64 bit types are only available
54 	on platforms that support such types. Returns self.
55 	*/
56 
57 	CTYPE itemType;
58 	IoSeq *typeName;
59 
60 	IO_ASSERT_NOT_SYMBOL(self);
61 
62 	typeName = IoMessage_locals_symbolArgAt_(m, locals, 0);
63 	itemType = CTYPE_forName(CSTRING(typeName));
64 
65 	IOASSERT(itemType != -1, "invalid item type name");
66 
67 	UArray_setItemType_(DATA(self), itemType);
68 	IoObject_isDirty_(self, 1);
69 	return self;
70 }
71 
IO_METHOD(IoSeq,convertToItemType)72 IO_METHOD(IoSeq, convertToItemType)
73 {
74 	/*doc Sequence convertToItemType(aTypeName)
75 	Converts the underlying machine type for the elements, expanding or contracting
76 	the size of the Sequence as needed.
77 	Valid names are uint8, uint16, uint32, uint64, int8, int16, int32,
78 	int64, float32, and float64. Note that 64 bit types are only available
79 	on platforms that support such types. Returns self.
80 	*/
81 	IoSymbol *typeName = IoMessage_locals_symbolArgAt_(m, locals, 0);
82 	CTYPE itemType = CTYPE_forName(CSTRING(typeName));
83 
84 	IO_ASSERT_NOT_SYMBOL(self);
85 
86 	IOASSERT(itemType != -1, "invalid item type name");
87 
88 	UArray_convertToItemType_(DATA(self), itemType);
89 	IoObject_isDirty_(self, 1);
90 	return self;
91 }
92 
IO_METHOD(IoSeq,convertToFixedSizeType)93 IO_METHOD(IoSeq, convertToFixedSizeType)
94 {
95 	IO_ASSERT_NOT_SYMBOL(self);
96 	UArray_convertToFixedSizeType(DATA(self));
97 	IoObject_isDirty_(self, 1);
98 	return self;
99 }
100 
IO_METHOD(IoSeq,setEncoding)101 IO_METHOD(IoSeq, setEncoding)
102 {
103 	/*doc Sequence setEncoding(encodingName)
104 	Sets the encoding flag of the receiver (only the encoding flag,
105 	itemSize and itemType will change, no conversion is done between UTF
106 	encodings - you can use convertToUTF8, etc methods for conversions).
107 	Valid encodings are number, utf8, utf16, and utf32. Returns self.
108 	*/
109 
110 	CENCODING encoding;
111 	IoSeq *encodingName;
112 
113 	IO_ASSERT_NOT_SYMBOL(self);
114 
115 	encodingName = IoMessage_locals_symbolArgAt_(m, locals, 0);
116 	encoding = CENCODING_forName(CSTRING(encodingName));
117 
118 	IOASSERT(encoding != -1, "invalid encoding name");
119 
120 	UArray_setEncoding_(DATA(self), encoding);
121 
122 	IoObject_isDirty_(self, 1);
123 	return self;
124 }
125 
IoSeq_rawCopy_(IoSeq * self,IoSeq * other)126 void IoSeq_rawCopy_(IoSeq *self, IoSeq *other)
127 {
128 	UArray_copy_(DATA(self), DATA(other));
129 }
130 
IO_METHOD(IoSeq,copy)131 IO_METHOD(IoSeq, copy)
132 {
133 	/*doc Sequence copy(aSequence)
134 	Replaces the bytes of the receiver with a copy of those in aSequence. Returns self.
135 	*/
136 
137 	IO_ASSERT_NOT_SYMBOL(self);
138 
139 	IoSeq_rawCopy_(self, IoMessage_locals_seqArgAt_(m, locals, 0));
140 	return self;
141 }
142 
IO_METHOD(IoSeq,appendSeq)143 IO_METHOD(IoSeq, appendSeq)
144 {
145 	/*doc Sequence appendSeq(object1, object2, ...)
146 	Calls asString on the arguments and appends the string to the receiver. Returns self.
147 	*/
148 
149 	int i;
150 
151 	IO_ASSERT_NOT_SYMBOL(self);
152 	IOASSERT(IoMessage_argCount(m), "requires at least one argument");
153 
154 	for (i = 0; i < IoMessage_argCount(m); i ++)
155 	{
156 		UArray_append_(DATA(self), DATA(IoMessage_locals_valueAsStringArgAt_(m, locals, i)));
157 	}
158 	return self;
159 }
160 
IO_METHOD(IoSeq,append)161 IO_METHOD(IoSeq, append)
162 {
163 	/*doc Sequence append(aNumber)
164 	Appends aNumber (cast to a byte) to the receiver. Returns self.
165 	*/
166 
167 	int i;
168 
169 	IO_ASSERT_NOT_SYMBOL(self);
170 	IOASSERT(IoMessage_argCount(m), "requires at least one argument");
171 
172 	for (i = 0; i < IoMessage_argCount(m); i ++)
173 	{
174 		UArray_appendDouble_(DATA(self), IoMessage_locals_doubleArgAt_(m, locals, i));
175 	}
176 
177 	return self;
178 }
179 
IO_METHOD(IoSeq,atInsertSeq)180 IO_METHOD(IoSeq, atInsertSeq)
181 {
182 	/*doc Sequence atInsertSeq(indexNumber, object)
183 	Calls asString on object and inserts the string at position indexNumber. Returns self.
184 	*/
185 
186 	size_t n = IoMessage_locals_sizetArgAt_(m, locals, 0);
187 	IoSeq *otherSeq = IoMessage_locals_valueAsStringArgAt_(m, locals, 1);
188 
189 	IO_ASSERT_NOT_SYMBOL(self);
190 
191 	IOASSERT(n <= UArray_size(DATA(self)), "insert index out of sequence bounds");
192 
193 	UArray_at_putAll_(DATA(self), n, DATA(otherSeq));
194 
195 	return self;
196 }
197 
IO_METHOD(IoSeq,insertSeqEvery)198 IO_METHOD(IoSeq, insertSeqEvery)
199 {
200 	/*doc MutableSequence IoSeq_insertSeqEvery(aSequence, aNumberOfItems)
201 	Inserts aSequence every aNumberOfItems.  Returns self.
202 	*/
203 
204 	IoSeq *otherSeq = IoMessage_locals_valueAsStringArgAt_(m, locals, 0);
205 	size_t itemCount = IoMessage_locals_sizetArgAt_(m, locals, 1);
206 
207 	IO_ASSERT_NOT_SYMBOL(self);
208 
209 	IOASSERT(itemCount > 0, "aNumberOfItems must be > 0");
210 	IOASSERT(itemCount <= UArray_size(DATA(self)), "aNumberOfItems out of sequence bounds");
211 
212 	UArray_insert_every_(DATA(self), DATA(otherSeq), itemCount);
213 
214 	return self;
215 }
216 
217 /*
218 IO_METHOD(IoSeq, atInsert)
219 {
220 	doc Sequence atInsert(indexNumber, valueNumber)
221 	Inserts valueNumber at position indexNumber. Returns self.
222 
223 	size_t n = IoMessage_locals_sizetArgAt_(m, locals, 0);
224 	IoNumber *value = IoMessage_locals_numberArgAt_(m, locals, 1);
225 
226 	IO_ASSERT_NOT_SYMBOL(self);
227 
228 
229 	UArray_at_putAll_(DATA(self), n, DATA(otherSeq));
230 	return self;
231 }
232 */
233 
234 // removing ---------------------------------------
235 
IO_METHOD(IoSeq,removeAt)236 IO_METHOD(IoSeq, removeAt)
237 {
238 	/*doc Sequence removeAt(index)
239 	Removes the item at index. Returns self.
240 	*/
241 
242 	long i = IoMessage_locals_longArgAt_(m, locals, 0);
243 
244 	IO_ASSERT_NOT_SYMBOL(self);
245 
246 	i = UArray_wrapPos_(DATA(self), i);
247 
248 	UArray_removeRange(DATA(self), i, 1);
249 	return self;
250 }
251 
IO_METHOD(IoSeq,removeSlice)252 IO_METHOD(IoSeq, removeSlice)
253 {
254 	/*doc Sequence removeSlice(startIndex, endIndex)
255 	Removes the items from startIndex to endIndex.
256 	Returns self.
257 	*/
258 
259 	long start = IoMessage_locals_longArgAt_(m, locals, 0);
260 	long end   = IoMessage_locals_longArgAt_(m, locals, 1);
261 
262 	IO_ASSERT_NOT_SYMBOL(self);
263 
264 	start = UArray_wrapPos_(DATA(self), start);
265 	end   = UArray_wrapPos_(DATA(self), end);
266 
267 	UArray_removeRange(DATA(self), start, end - start + 1);
268 	return self;
269 }
270 
IO_METHOD(IoSeq,removeLast)271 IO_METHOD(IoSeq, removeLast)
272 {
273 	/*doc Sequence removeLast
274 	Removes the last element from the receiver. Returns self.
275 	*/
276 
277 	IO_ASSERT_NOT_SYMBOL(self);
278 	UArray_removeLast(DATA(self));
279 	return self;
280 }
281 
IO_METHOD(IoSeq,leaveThenRemove)282 IO_METHOD(IoSeq, leaveThenRemove)
283 {
284 	/*doc MutableSequence IoSeq_leaveThenRemove(aNumberToLeave, aNumberToRemove)
285 	Leaves aNumberToLeave items then removes aNumberToRemove items.  Returns self.
286 	*/
287 
288 	size_t itemsToLeave = IoMessage_locals_sizetArgAt_(m, locals, 0);
289 	size_t itemsToRemove = IoMessage_locals_sizetArgAt_(m, locals, 1);
290 
291 	IO_ASSERT_NOT_SYMBOL(self);
292 
293 	IOASSERT(itemsToLeave > 0 || itemsToRemove > 0, "either aNumberToLeave or aNumberToRemove must be > 0");
294 
295 	UArray_leave_thenRemove_(DATA(self), itemsToLeave, itemsToRemove);
296 
297 	return self;
298 }
299 
IO_METHOD(IoSeq,setSize)300 IO_METHOD(IoSeq, setSize)
301 {
302 	/*doc Sequence setSize(aNumber)
303 	Sets the length in bytes of the receiver to aNumber. Return self.
304 	*/
305 
306 	size_t len = IoMessage_locals_sizetArgAt_(m, locals, 0);
307 	IO_ASSERT_NOT_SYMBOL(self);
308 	UArray_setSize_(DATA(self), len);
309 	return self;
310 }
311 
IoSeq_rawPio_reallocateToSize_(IoSeq * self,size_t size)312 void IoSeq_rawPio_reallocateToSize_(IoSeq *self, size_t size)
313 {
314 	if (ISSYMBOL(self))
315 	{
316 		IoState_error_(IOSTATE, NULL, "attempt to resize an immutable Sequence");
317 	}
318 
319 	UArray_sizeTo_(DATA(self), size);
320 }
321 
IO_METHOD(IoSeq,preallocateToSize)322 IO_METHOD(IoSeq, preallocateToSize)
323 {
324 	/*doc Sequence preallocateToSize(aNumber)
325 	If needed, resize the memory alloced for the receivers
326 	byte array to be large enough to fit the number of bytes specified by
327 	aNumber. This is useful for pio_reallocating the memory so it doesn't
328 	keep getting allocated as the Sequence is appended to. This operation
329 	will not change the Sequence's length or contents. Returns self.
330 	*/
331 
332 	size_t newSize = IoMessage_locals_sizetArgAt_(m, locals, 0);
333 	IO_ASSERT_NOT_SYMBOL(self);
334 	UArray_sizeTo_(DATA(self), newSize);
335 	return self;
336 }
337 
IO_METHOD(IoSeq,replaceSeq)338 IO_METHOD(IoSeq, replaceSeq)
339 {
340 	/*doc Sequence replaceSeq(aSequence, anotherSequence)
341 	Returns a new Sequence with all occurrences of aSequence
342 	replaced with anotherSequence in the receiver. Returns self.
343 	*/
344 
345 	IoSeq *subSeq   = IoMessage_locals_seqArgAt_(m, locals, 0);
346 	IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 1);
347 	IO_ASSERT_NOT_SYMBOL(self);
348 	UArray_replace_with_(DATA(self), DATA(subSeq), DATA(otherSeq));
349 	return self;
350 }
351 
IO_METHOD(IoSeq,removeSeq)352 IO_METHOD(IoSeq, removeSeq)
353 {
354 	/*doc Sequence removeSeq(aSequence)
355 	Removes occurrences of aSequence from the receiver.
356 	*/
357 
358 	IoSeq *subSeq   = IoMessage_locals_seqArgAt_(m, locals, 0);
359 	IO_ASSERT_NOT_SYMBOL(self);
360 	UArray_remove_(DATA(self), DATA(subSeq));
361 	return self;
362 }
363 
364 
IO_METHOD(IoSeq,replaceFirstSeq)365 IO_METHOD(IoSeq, replaceFirstSeq)
366 {
367 	/*doc Sequence replaceFirstSeq(aSequence, anotherSequence, optionalStartIndex)
368 	Returns a new Sequence with the first occurrence of aSequence
369 	replaced with anotherSequence in the receiver. If optionalStartIndex is
370 	provided, the search for aSequence begins at that index. Returns self.
371 	*/
372 
373 	IoSeq *subSeq   = IoMessage_locals_seqArgAt_(m, locals, 0);
374 	IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 1);
375 	size_t startIndex = 0;
376 
377 	if (IoMessage_argCount(m) > 2)
378 	{
379 		startIndex = IoMessage_locals_longArgAt_(m, locals, 2);
380 	}
381 
382 	IO_ASSERT_NOT_SYMBOL(self);
383 
384 	{
385 		UArray *a = DATA(self);
386 		UArray *b = DATA(subSeq);
387 		UArray *c = DATA(otherSeq);
388 		long i = UArray_find_from_(a, b, startIndex);
389 		if(i != -1)
390 		{
391 			UArray_removeRange(a, i, UArray_size(b));
392 			UArray_at_putAll_(a, i, c);
393 		}
394 	}
395 	return self;
396 }
397 
IO_METHOD(IoSeq,atPut)398 IO_METHOD(IoSeq, atPut)
399 {
400 	/*doc Sequence atPut(aNumberIndex, aNumber)
401 	Sets the value at the index specified by aNumberIndex to aNumber. Returns self.
402 	*/
403 
404 	size_t i = IoMessage_locals_longArgAt_(m, locals, 0);
405 	UArray *a = DATA(self);
406 
407 	IO_ASSERT_NOT_SYMBOL(self);
408 
409 	if (UArray_isFloatType(a))
410 	{
411 		double v = IoMessage_locals_doubleArgAt_(m, locals, 1);
412 		UArray_at_putDouble_(a, i, v);
413 	}
414 	else
415 	{
416 		long v = IoMessage_locals_longArgAt_(m, locals, 1);
417 		UArray_at_putLong_(a, i, v);
418 	}
419 
420 	return self;
421 }
422 
IO_METHOD(IoSeq,lowercase)423 IO_METHOD(IoSeq, lowercase)
424 {
425 	/*doc Sequence lowercase
426 	Makes all the uppercase characters in the receiver lowercase. Returns self.
427 	*/
428 
429 	IO_ASSERT_NOT_SYMBOL(self);
430 	UArray_tolower(DATA(self));
431 	return self;
432 }
433 
IO_METHOD(IoSeq,uppercase)434 IO_METHOD(IoSeq, uppercase)
435 {
436 	/*doc Sequence uppercase
437 	Makes all characters of the receiver uppercase.
438 	*/
439 
440 	IO_ASSERT_NOT_SYMBOL(self);
441 	UArray_toupper(DATA(self));
442 	return self;
443 }
444 
445 // clip --------------------------------------
446 
IO_METHOD(IoSeq,clipBeforeSeq)447 IO_METHOD(IoSeq, clipBeforeSeq)
448 {
449 	/*doc Sequence clipBeforeSeq(aSequence)
450 	Clips receiver before aSequence.
451 	*/
452 
453 	IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
454 	IO_ASSERT_NOT_SYMBOL(self);
455 	UArray_clipBefore_(DATA(self), DATA(otherSeq));
456 	return self;
457 }
458 
IO_METHOD(IoSeq,clipAfterSeq)459 IO_METHOD(IoSeq, clipAfterSeq)
460 {
461 	/*doc Sequence clipAfterSeq(aSequence)
462 	Removes the contents of the receiver after the end of
463 	the first occurrence of aSequence. Returns true if anything was
464 	removed, or false otherwise.
465 	*/
466 
467 	IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
468 
469 	IO_ASSERT_NOT_SYMBOL(self);
470 	UArray_clipAfter_(DATA(self), DATA(otherSeq));
471 	return self;
472 }
473 
IO_METHOD(IoSeq,clipBeforeEndOfSeq)474 IO_METHOD(IoSeq, clipBeforeEndOfSeq)
475 {
476 	/*doc Sequence clipBeforeEndOfSeq(aSequence)
477 	Removes the contents of the receiver before the end of
478 	the first occurrence of aSequence. Returns true if anything was
479 	removed, or false otherwise.
480 	*/
481 
482 	IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
483 	IO_ASSERT_NOT_SYMBOL(self);
484 	UArray_clipBeforeEndOf_(DATA(self), DATA(otherSeq));
485 	return self;
486 }
487 
IO_METHOD(IoSeq,clipAfterStartOfSeq)488 IO_METHOD(IoSeq, clipAfterStartOfSeq)
489 {
490 	/*doc Sequence clipAfterStartOfSeq(aSequence)
491 	Removes the contents of the receiver after the beginning of
492 	the first occurrence of aSequence. Returns true if anything was
493 	removed, or false otherwise.
494 	*/
495 
496 	IoSeq *otherSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
497 	IO_ASSERT_NOT_SYMBOL(self);
498 	UArray_clipAfterStartOf_(DATA(self), DATA(otherSeq));
499 	return self;
500 }
501 
502 // -----------------------------------------
503 
IO_METHOD(IoSeq,empty)504 IO_METHOD(IoSeq, empty)
505 {
506 	/*doc Sequence empty
507 	Sets all bytes in the receiver to 0x0 and sets
508 	its length to 0. Returns self.
509 	*/
510 
511 	IO_ASSERT_NOT_SYMBOL(self);
512 	UArray_clear(DATA(self));
513 	UArray_setSize_(DATA(self), 0);
514 	return self;
515 }
516 
IoSeq_byteCompare(const void * a,const void * b)517 int IoSeq_byteCompare(const void *a, const void *b)
518 {
519 	char aa = *(char *)a;
520 	char bb = *(char *)b;
521 
522 	if (aa < bb)
523 	{
524 		return -1;
525 	}
526 
527 	if (aa == bb)
528 	{
529 		return 0;
530 	}
531 
532 	return 1;
533 }
534 
IO_METHOD(IoSeq,sort)535 IO_METHOD(IoSeq, sort)
536 {
537 	//doc Sequence sort Sorts the characters/numbers in the array. Returns self.
538 
539 	UArray *a = DATA(self);
540 	IO_ASSERT_NOT_SYMBOL(self);
541 
542 	if(UArray_itemType(a) == CTYPE_uintptr_t)
543 	{
544 		UArray_sortBy_(a, (UArraySortCallback *)IoObject_compare);
545 	}
546 	else
547 	{
548 		UArray_sort(a);
549 	}
550 
551 	return self;
552 }
553 
IO_METHOD(IoSeq,replaceMap)554 IO_METHOD(IoSeq, replaceMap)
555 {
556 	/*doc Sequence replaceMap(aMap)
557 	In the receiver, the keys of aMap replaced with its values. Returns self.
558 	*/
559 
560 	IoMap *map = IoMessage_locals_mapArgAt_(m, locals, 0);
561 	UArray *ba = DATA(self);
562 
563 	IO_ASSERT_NOT_SYMBOL(self);
564 
565 	PHASH_FOREACH(IoMap_rawHash(map), k, v,
566 		{
567 		IoSymbol *subSeq = k;
568 		IoSymbol *otherSeq = v;
569 
570 		if (ISSEQ(otherSeq))
571 		{
572 			UArray_replace_with_(ba, DATA(subSeq), DATA(otherSeq));
573 		}
574 		else
575 		{
576 			IoState_error_(IOSTATE, m,
577 							"argument 0 to method '%s' must be a Map with Sequence values, not '%s'",
578 							CSTRING(IoMessage_name(m)), IoObject_name(otherSeq));
579 		}
580 		}
581 	);
582 
583 	return self;
584 }
585 
586 // translate ------------------------------------------------------
587 
IO_METHOD(IoSeq,translate)588 IO_METHOD(IoSeq, translate)
589 {
590 	/*doc Sequence translate(fromChars, toChars)
591 	In the receiver, the characters in fromChars are replaced with those in the same positions in toChars. Returns self.
592 	*/
593 
594 	UArray *ba = DATA(self);
595 	UArray *fc = DATA(IoMessage_locals_seqArgAt_(m, locals, 0));
596 	UArray *tc = DATA(IoMessage_locals_seqArgAt_(m, locals, 1));
597 
598 	IO_ASSERT_NOT_SYMBOL(self);
599 
600 	if (UArray_size(tc) != UArray_size(fc))
601 	{
602 		IoState_error_(IOSTATE, m, "translation strings must be of the same length");
603 	}
604 
605 	UArray_translate(ba, fc, tc);
606 
607 	return self;
608 }
609 
610 // reverse --------------------------------------------------------
611 
IO_METHOD(IoSeq,reverseInPlace)612 IO_METHOD(IoSeq, reverseInPlace)
613 {
614 	/*doc Sequence reverseInPlace
615 	Reverses the bytes in the receiver, in-place.
616 	*/
617 
618 	IO_ASSERT_NOT_SYMBOL(self);
619 
620 	UArray_reverse(DATA(self));
621 	return self;
622 }
623 
624 
625 // strip ----------------------------------------------------------
626 
IO_METHOD(IoSeq,strip)627 IO_METHOD(IoSeq, strip)
628 {
629 /*doc Sequence strip(optionalSequence)
630 Trims the whitespace (or optionalSequence) off both ends:
631 <p>
632 <pre>
633 "   Trim this string   \r\n" strip
634 ==> "Trim this string"
635 </pre>
636 */
637 
638 	IO_ASSERT_NOT_SYMBOL(self);
639 
640 	if (IoMessage_argCount(m) > 0)
641 	{
642 		IoSeq *other  = IoMessage_locals_seqArgAt_(m, locals, 0);
643 		UArray_strip_(DATA(self), DATA(other));
644 	}
645 	else
646 	{
647 		UArray space = UArray_stackAllocedWithCString_(WHITESPACE);
648 		UArray_strip_(DATA(self), &space);
649 	}
650 
651 	return self;
652 }
653 
IO_METHOD(IoSeq,lstrip)654 IO_METHOD(IoSeq, lstrip)
655 {
656 /*doc Sequence lstrip(aSequence)
657 Strips the characters in aSequence
658 stripped from the beginning of the receiver. Example:
659 <p>
660 <pre>
661 "Keep the tail" lstrip(" eKp")
662 ==> "the tail"
663 </pre>
664 */
665 
666 	IO_ASSERT_NOT_SYMBOL(self);
667 
668 	if (IoMessage_argCount(m) > 0)
669 	{
670 		IoSeq *other  = IoMessage_locals_seqArgAt_(m, locals, 0);
671 		UArray_lstrip_(DATA(self), DATA(other));
672 	}
673 	else
674 	{
675 		UArray space = UArray_stackAllocedWithCString_(WHITESPACE);
676 		UArray_lstrip_(DATA(self), &space);
677 	}
678 
679 	return self;
680 }
681 
IO_METHOD(IoSeq,rstrip)682 IO_METHOD(IoSeq, rstrip)
683 {
684 /*doc Sequence rstrip(aSequence)
685 Strips the characters in
686 aSequence stripped from the end of the receiver. Example:
687 <pre>
688 "Cut the tail off" rstrip(" afilot")
689 ==> "Cut the"
690 </pre>
691 */
692 
693 	IO_ASSERT_NOT_SYMBOL(self);
694 
695 	if (IoMessage_argCount(m) > 0)
696 	{
697 		IoSeq *other  = IoMessage_locals_seqArgAt_(m, locals, 0);
698 		UArray_rstrip_(DATA(self), DATA(other));
699 	}
700 	else
701 	{
702 		UArray space = UArray_stackAllocedWithCString_(WHITESPACE);
703 		UArray_rstrip_(DATA(self), &space);
704 	}
705 
706 	return self;
707 }
708 
709 // -----------------------------------------------------------
710 
IO_METHOD(IoSeq,escape)711 IO_METHOD(IoSeq, escape)
712 {
713 	/*doc Sequence escape
714 	Escape characters in the receiver are replaced with escape codes.
715 	For example a string containing a single return character would contain the
716 	following 2 characters after being escaped: "\n". Returns self.
717 	*/
718 
719 	IO_ASSERT_NOT_SYMBOL(self);
720 	UArray_escape(DATA(self));
721 	return self;
722 }
723 
IO_METHOD(IoSeq,unescape)724 IO_METHOD(IoSeq, unescape)
725 {
726 	/*doc Sequence unescape
727 	Escape codes replaced with escape characters. Returns self.
728 	*/
729 
730 	IO_ASSERT_NOT_SYMBOL(self);
731 	UArray_unescape(DATA(self));
732 	return self;
733 }
734 
IO_METHOD(IoSeq,removePrefix)735 IO_METHOD(IoSeq, removePrefix)
736 {
737 	/*doc Sequence removePrefix(aSequence)
738 	If the receiver begins with aSequence, it is removed. Returns self.
739 	*/
740 
741 	IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
742 
743 	IO_ASSERT_NOT_SYMBOL(self);
744 
745 	if (UArray_beginsWith_(DATA(self), DATA(other)))
746 	{
747 		UArray_removeRange(DATA(self), 0, UArray_size(DATA(other)));
748 	}
749 
750 	return self;
751 }
752 
IO_METHOD(IoSeq,removeSuffix)753 IO_METHOD(IoSeq, removeSuffix)
754 {
755 	/*doc Sequence removeSuffix(aSequence)
756 	If the receiver end with aSequence, it is removed. Returns self.
757 	*/
758 
759 	IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
760 
761 	IO_ASSERT_NOT_SYMBOL(self);
762 
763 	if (UArray_endsWith_(DATA(self), DATA(other)))
764 	{
765 		UArray *ba = DATA(self);
766 		UArray_removeRange(ba,
767 							UArray_size(ba) - UArray_size(DATA(other)),
768 							UArray_size(ba));
769 	}
770 
771 	return self;
772 }
773 
IO_METHOD(IoSeq,capitalize)774 IO_METHOD(IoSeq, capitalize)
775 {
776 	/*doc Sequence capitalize
777 	First charater of the receiver is made uppercase.
778 	*/
779 
780 	long firstChar = UArray_firstLong(DATA(self));
781 
782 	IO_ASSERT_NOT_SYMBOL(self);
783 	UArray_at_putLong_(DATA(self), 0, toupper((int)firstChar));
784 	return self;
785 }
786 
IO_METHOD(IoSeq,appendPathSeq)787 IO_METHOD(IoSeq, appendPathSeq)
788 {
789 	/*doc Sequence appendPathSeq(aSeq)
790 	Appends argument to the receiver such that there is one
791 	and only one path separator between the two. Returns self.
792 	*/
793 
794 	IoSeq *component = IoMessage_locals_seqArgAt_(m, locals, 0);
795 
796 	IO_ASSERT_NOT_SYMBOL(self);
797 	UArray_appendPath_(DATA(self), DATA(component));
798 	return self;
799 }
800 
IO_METHOD(IoSeq,interpolateInPlace)801 IO_METHOD(IoSeq, interpolateInPlace)
802 {
803 	/*doc Sequence interpolateInPlace(optionalContext)
804 	Replaces all #{expression} with expression evaluated in the optionalContext.
805 	If optionalContext not given, the current context is used.  Returns self.
806 	*/
807 
808 	IoObject *context;
809 	UArray *string;
810 	UArray *code;
811 	IoObject *evaluatedCode;
812 	IoSeq *codeString;
813 	UArray *evaluatedCodeAsString = NULL;
814 	//const char *label;
815 	long from, to;
816 	UArray begin = UArray_stackAllocedWithCString_("#{");
817 	UArray end = UArray_stackAllocedWithCString_("}");
818 
819 	IO_ASSERT_NOT_SYMBOL(self);
820 
821 	context = IoMessage_locals_valueArgAt_(m, locals, 0);
822 	string = DATA(self);
823 	//label = "IoSeq_interpolateInPlace()";
824 	from = 0;
825 
826 	context = (context == IONIL(self)) ? locals : context;
827 
828 	IoState_pushRetainPool(IOSTATE);
829 
830 	for(;;)
831 	{
832 		IoState_clearTopPool(IOSTATE);
833 
834 		from = UArray_find_from_(string, &begin, from);
835 		if (from == -1) break;
836 
837 		to = UArray_find_from_(string, &end, from);
838 		if (to == -1) break;
839 
840 		code = UArray_slice(string, from + 2, to);
841 		codeString = IoSeq_newWithUArray_copy_(IOSTATE, code, 0);
842 
843 		if (UArray_size(code) == 0)
844 		{
845 			// we do not want "#{}" to interpolate into "nil"
846 			evaluatedCodeAsString = DATA(IoState_doCString_(IOSTATE, "Sequence clone"));
847 		}
848 		else
849 		{
850 			IoMessage *em = IoMessage_newWithName_andCachedArg_(IOSTATE, IOSYMBOL("doString"), codeString);
851 			evaluatedCode = IoObject_perform(context, context, em);
852 			evaluatedCode = IoObject_perform(evaluatedCode, context, IOSTATE->asStringMessage);
853 
854 			if (ISSEQ(evaluatedCode))
855 			{
856 				evaluatedCodeAsString = DATA(evaluatedCode);
857 			}
858 		}
859 
860 		//UArray_free(code);
861 
862 		if (evaluatedCodeAsString == NULL)
863 		{
864 			break;
865 		}
866 
867 		UArray_removeRange(string, from, to-from+1);
868 		UArray_at_putAll_(string, from, evaluatedCodeAsString);
869 		from = from + UArray_size(evaluatedCodeAsString);
870 	}
871 
872 	IoState_popRetainPool(IOSTATE);
873 
874 	if (from >= 0 && to >= 0)
875 	{
876 		IOASSERT(evaluatedCodeAsString != NULL, "bad asString results");
877 	}
878 
879 	return self;
880 }
881 
882 // math ---------------------------------------------------------------------
883 
IO_METHOD(IoSeq,addEquals)884 IO_METHOD(IoSeq, addEquals)
885 {
886 	/*doc Sequence +=(aSeq)
887 	Vector addition - adds the values of aSeq to those of the receiver.
888 	Only works on Sequences whose item type is numeric. Returns self.
889 	*/
890 
891 	IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
892 
893 	IO_ASSERT_NOT_SYMBOL(self);
894 	IO_ASSERT_NUMBER_ENCODING(self);
895 
896 	if (ISSEQ(other))
897 	{
898 		//printf("IoMessage_argCount(m) = %i\n", IoMessage_argCount(m));
899 		if (IoMessage_argCount(m) > 1)
900 		{
901 			float offset = IoMessage_locals_floatArgAt_(m, locals, 1);
902 			float xscale = IoMessage_locals_floatArgAt_(m, locals, 2);
903 			float yscale = IoMessage_locals_floatArgAt_(m, locals, 3);
904 			UArray_addEqualsOffsetXScaleYScale(DATA(self), DATA(other), offset, xscale, yscale);
905 		}
906 		else
907 		{
908 			UArray_add_(DATA(self), DATA(other));
909 		}
910 	}
911 	else if (ISNUMBER(other))
912 	{
913 		double value = IoNumber_asDouble(other);
914 		UArray_addScalarDouble_(DATA(self), value);
915 	}
916 	else
917 	{
918 		IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
919 	}
920 
921 	return self;
922 }
923 
924 
IO_METHOD(IoSeq,subtractEquals)925 IO_METHOD(IoSeq, subtractEquals)
926 {
927 	/*doc Sequence -=(aSeq)
928 	Vector subtraction - subtracts the values of aSeq to those of the receiver.
929 	Only works on Sequences whose item type is numeric. Returns self.
930 	*/
931 
932 	IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
933 
934 	IO_ASSERT_NOT_SYMBOL(self);
935 	IO_ASSERT_NUMBER_ENCODING(self);
936 
937 	if (ISSEQ(other))
938 	{
939 		UArray_subtract_(DATA(self), DATA(other));
940 	}
941 	else if (ISNUMBER(other))
942 	{
943 		double value = IoNumber_asDouble(other);
944 		UArray_subtractScalarDouble_(DATA(self), value);
945 	}
946 	else
947 	{
948 		IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
949 	}
950 
951 	return self;
952 }
953 
IO_METHOD(IoSeq,multiplyEquals)954 IO_METHOD(IoSeq, multiplyEquals)
955 {
956 	/*doc Sequence *=(aSeq)
957 	Multiplies the values of aSeq to the corresponding values of the receiver.
958 	Only works on Sequences whose item type is numeric. Returns self.
959 	*/
960 
961 	IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
962 
963 	IO_ASSERT_NOT_SYMBOL(self);
964 	IO_ASSERT_NUMBER_ENCODING(self);
965 
966 	if (ISSEQ(other))
967 	{
968 		UArray_multiply_(DATA(self), DATA(other));
969 	}
970 	else if (ISNUMBER(other))
971 	{
972 		double value = IoNumber_asDouble(other);
973 		UArray_multiplyScalarDouble_(DATA(self), value);
974 	}
975 	else
976 	{
977 		IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
978 	}
979 
980 	return self;
981 }
982 
IO_METHOD(IoSeq,divideEquals)983 IO_METHOD(IoSeq, divideEquals)
984 {
985 	/*doc Sequence /=(aSeq)
986 	Divides the values of aSeq to the corresponding values of the receiver.
987 	Only works on Sequences whose item type is numeric. Returns self.
988 	*/
989 
990 	IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
991 
992 	IO_ASSERT_NOT_SYMBOL(self);
993 	IO_ASSERT_NUMBER_ENCODING(self);
994 
995 	if (ISSEQ(other))
996 	{
997 		UArray_divide_(DATA(self), DATA(other));
998 	}
999 	else if (ISNUMBER(other))
1000 	{
1001 		double value = IoNumber_asDouble(other);
1002 		UArray_divideScalarDouble_(DATA(self), value);
1003 	}
1004 	else
1005 	{
1006 		IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
1007 	}
1008 
1009 	return self;
1010 }
1011 
IO_METHOD(IoSeq,powerEquals)1012 IO_METHOD(IoSeq, powerEquals)
1013 {
1014 	/*doc Sequence **=(aSeq)
1015 	Raises the values of the receiver in the corresponding values of aSeq.
1016 	Only works on Sequences whose item type is numeric. Returns self.
1017 	*/
1018 
1019 	IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0);
1020 
1021 	IO_ASSERT_NOT_SYMBOL(self);
1022 	IO_ASSERT_NUMBER_ENCODING(self);
1023 
1024 	if (ISSEQ(other))
1025 	{
1026 		UArray_power_(DATA(self), DATA(other));
1027 	}
1028 	else if (ISNUMBER(other))
1029 	{
1030 		double value = IoNumber_asDouble(other);
1031 		UArray_powerScalarDouble_(DATA(self), value);
1032 	}
1033 	else
1034 	{
1035 		IoMessage_locals_numberArgAt_errorForType_(self, locals, 0, "Sequence or Number");
1036 	}
1037 
1038 	return self;
1039 }
1040 
IoSeq_clone(IoSeq * self)1041 IoObject *IoSeq_clone(IoSeq *self)
1042 {
1043 	return IoSeq_newWithUArray_copy_(IOSTATE, DATA(self), 1);
1044 }
1045 
IO_METHOD(IoSeq,add)1046 IO_METHOD(IoSeq, add)
1047 {
1048 	/*doc Sequence +(aSeq)
1049 	Vector addition - adds the values of aSeq to the corresponding values of the receiver
1050 	returning a new vector with the result.
1051 	Only works on Sequences whose item type is numeric.
1052 	*/
1053 
1054 	return IoSeq_addEquals(IoSeq_clone(self), locals, m);
1055 }
1056 
IO_METHOD(IoSeq,subtract)1057 IO_METHOD(IoSeq, subtract)
1058 {
1059 	/*doc Sequence -(aSeq)
1060 	Vector subtraction - Subtracts the values of aSeq from the corresponding values of the receiver
1061 	returning a new vector with the result.
1062 	Only works on Sequences whose item type is numeric.
1063 	*/
1064 
1065 	return IoSeq_subtractEquals(IoSeq_clone(self), locals, m);
1066 }
1067 
IO_METHOD(IoSeq,multiply)1068 IO_METHOD(IoSeq, multiply)
1069 {
1070 	/*doc Sequence *(aSeq)
1071 	Multiplies the values of aSeq to the corresponding values of the receiver
1072 	returning a new vector with the result.
1073 	Only works on Sequences whose item type is numeric.
1074 	*/
1075 
1076 	return IoSeq_multiplyEquals(IoSeq_clone(self), locals, m);
1077 }
1078 
IO_METHOD(IoSeq,divide)1079 IO_METHOD(IoSeq, divide)
1080 {
1081 	/*doc Sequence /(aSeq)
1082 	Divides the values of the receiver by the corresponding values of aSeq
1083 	returning a new vector with the result.
1084 	Only works on Sequences whose item type is numeric.
1085 	*/
1086 
1087 	return IoSeq_divideEquals(IoSeq_clone(self), locals, m);
1088 }
1089 
IO_METHOD(IoSeq,power)1090 IO_METHOD(IoSeq, power)
1091 {
1092 	/*doc Sequence **(aSeq)
1093 	Raises the values of the receiver in the corresponding values of aSeq
1094 	returning a new vector with the result.
1095 	Only works on Sequences whose item type is numeric.
1096 	*/
1097 
1098 	return IoSeq_powerEquals(IoSeq_clone(self), locals, m);
1099 }
1100 
IO_METHOD(IoSeq,dotProduct)1101 IO_METHOD(IoSeq, dotProduct)
1102 {
1103 	/*doc Sequence dotProduct(aSeq)
1104 	Returns a new Sequence containing the dot product of the receiver with aSeq.
1105 	*/
1106 
1107 	IoSeq *other = IoMessage_locals_seqArgAt_(m, locals, 0);
1108 	IO_ASSERT_NOT_SYMBOL(self);
1109 	return IONUMBER(UArray_dotProduct_(DATA(self), DATA(other)));
1110 }
1111 
IO_METHOD(IoSeq,setItemsToLong_)1112 IO_METHOD(IoSeq, setItemsToLong_)
1113 {
1114 	/*doc Sequence setItemsToLong(aNumber)
1115 	Sets all items in the Sequence to the long integer value of aNumber.
1116 	*/
1117 
1118 	long v = IoMessage_locals_longArgAt_(m, locals, 0);
1119 	IO_ASSERT_NOT_SYMBOL(self);
1120 	UArray_setItemsToLong_(DATA(self), v);
1121 	return self;
1122 }
1123 
IO_METHOD(IoSeq,setItemsToDouble_)1124 IO_METHOD(IoSeq, setItemsToDouble_)
1125 {
1126 	/*doc Sequence setItemsToDouble(aNumber)
1127 	Sets all items in the Sequence to the double floating point value of aNumber.
1128 	*/
1129 
1130 	double v = IoMessage_locals_doubleArgAt_(m, locals, 0);
1131 	IO_ASSERT_NOT_SYMBOL(self);
1132 	UArray_setItemsToLong_(DATA(self), v);
1133 	return self;
1134 }
1135 
IO_METHOD(IoSeq,set_)1136 IO_METHOD(IoSeq, set_)
1137 {
1138 	/*doc Sequence set(aNumber1, aNumber2, ...)
1139 	Sets the values of the receiver to the sequences of numbers in the arguments.
1140 	Unset values will remain unchanged.
1141 	Returns self.
1142 	*/
1143 
1144 	double i, max = IoMessage_argCount(m);
1145 	IO_ASSERT_NOT_SYMBOL(self);
1146 
1147 	for (i = 0; i < max; i ++)
1148 	{
1149 		double v = IoMessage_locals_doubleArgAt_(m, locals, i);
1150 		UArray_at_putDouble_(DATA(self), i, v);
1151 	}
1152 
1153 	return self;
1154 }
1155 
1156 #define IoSeqMutateNoArgNoResultOp(name) \
1157 IoObject *IoSeq_ ## name (IoSeq *self, IoObject *locals, IoMessage *m) \
1158 { IO_ASSERT_NOT_SYMBOL(self); UArray_ ## name (DATA(self)); return self; }
1159 
1160 /*doc Sequence negate
1161 Negates the values of the receiver.
1162 Returns self.
1163 */
1164 IoSeqMutateNoArgNoResultOp(negate)
1165 
1166 /*doc Sequence rangeFill
1167 Sets the values of the Sequence to their index values.
1168 Returns self.
1169 */
1170 IoSeqMutateNoArgNoResultOp(rangeFill)
1171 
1172 /*doc Sequence sin
1173 Sets each value of the Sequence to the trigonometric sine of its value.
1174 Returns self.
1175 */
1176 IoSeqMutateNoArgNoResultOp(sin)
1177 
1178 /*doc Sequence cos
1179 Sets each value of the Sequence to the trigonometric cosine of its value.
1180 Returns self.
1181 */
1182 IoSeqMutateNoArgNoResultOp(cos)
1183 
1184 /*doc Sequence tan
1185 Sets each value of the Sequence to the trigonometric tangent of its value.
1186 Returns self.
1187 */
1188 IoSeqMutateNoArgNoResultOp(tan)
1189 
1190 /*doc Sequence asin
1191 Sets each value of the Sequence to the trigonometric arcsine of its value.
1192 Returns self.
1193 */
1194 IoSeqMutateNoArgNoResultOp(asin)
1195 
1196 /*doc Sequence acos
1197 Sets each value of the Sequence to the trigonometric arcsine of its value.
1198 Returns self.
1199 */
1200 IoSeqMutateNoArgNoResultOp(acos)
1201 
1202 /*doc Sequence atan
1203 Sets each value of the Sequence to the trigonometric arctangent of its value.
1204 Returns self.
1205 */
1206 IoSeqMutateNoArgNoResultOp(atan)
1207 
1208 /*doc Sequence sinh
1209 Sets each value of the Sequence to the hyperbolic sine of its value.
1210 Returns self.
1211 */
1212 IoSeqMutateNoArgNoResultOp(sinh)
1213 
1214 /*doc Sequence cosh
1215 Sets each value of the Sequence to the hyperbolic cosine of its value.
1216 Returns self.
1217 */
1218 IoSeqMutateNoArgNoResultOp(cosh)
1219 
1220 /*doc Sequence tanh
1221 Sets each value of the Sequence to the hyperbolic tangent of its value.
1222 Returns self.
1223 */
1224 IoSeqMutateNoArgNoResultOp(tanh)
1225 
1226 /*doc Sequence exp
1227 Sets each value of the Sequence to e**value.
1228 Returns self.
1229 */
1230 IoSeqMutateNoArgNoResultOp(exp)
1231 
1232 /*doc Sequence log
1233 Sets each value of the Sequence to the natural log of its value.
1234 Returns self.
1235 */
1236 IoSeqMutateNoArgNoResultOp(log)
1237 
1238 /*doc Sequence log10
1239 Sets each value of the Sequence to the base 10 log of its value.
1240 Returns self.
1241 */
1242 IoSeqMutateNoArgNoResultOp(log10);
1243 
1244 /*doc Sequence ceil
1245 Round each value to smallest integral value not less than x.
1246 Returns self.
1247 */
1248 IoSeqMutateNoArgNoResultOp(ceil)
1249 
1250 /*doc Sequence floor
1251 Round each value to largest integral value not greater than x.
1252 Returns self.
1253 */
IoSeqMutateNoArgNoResultOp(floor)1254 IoSeqMutateNoArgNoResultOp(floor)
1255 
1256 /*doc Sequence abs
1257 Sets each value of the Sequence to its absolute value.
1258 Returns self.
1259 */
1260 IoSeqMutateNoArgNoResultOp(abs)
1261 
1262 /*doc Sequence square
1263 Sets each value of the Sequence to the square of its value.
1264 Returns self.
1265 */
1266 IoSeqMutateNoArgNoResultOp(square)
1267 
1268 /*doc Sequence sqrt
1269 Sets each value of the Sequence to the square root of its value.
1270 Returns self.
1271 */
1272 IoSeqMutateNoArgNoResultOp(sqrt)
1273 
1274 /*doc Sequence normalize
1275 Divides each value of the Sequence by the max value of the sequence.
1276 Returns self.
1277 */
1278 IoSeqMutateNoArgNoResultOp(normalize)
1279 
1280 #define IoSeqNoArgNumberResultOp(name) \
1281 IoObject *IoSeq_ ## name (IoSeq *self, IoObject *locals, IoMessage *m) \
1282 { return IONUMBER(UArray_ ## name (DATA(self))); }
1283 
1284 /*doc Sequence sum
1285 Returns the sum of the Sequence.
1286 */
1287 IoSeqNoArgNumberResultOp(sumAsDouble)
1288 
1289 /*doc Sequence product
1290 Returns the product of all the sequence's values multipled together.
1291 */
1292 IoSeqNoArgNumberResultOp(productAsDouble)
1293 
1294 /*doc Sequence min
1295 Returns the minimum value of the Sequence.
1296 */
1297 IoSeqNoArgNumberResultOp(minAsDouble)
1298 
1299 /*doc Sequence max
1300 Returns the maximum value of the Sequence.
1301 */
1302 IoSeqNoArgNumberResultOp(maxAsDouble)
1303 
1304 /*doc Sequence mean
1305 Returns the arithmetic mean of the sequence.
1306 */
1307 IoSeqNoArgNumberResultOp(arithmeticMeanAsDouble)
1308 
1309 /*doc Sequence meanSquare
1310 Returns the arithmetic mean of the sequence's values after they have been squared.
1311 */
1312 IoSeqNoArgNumberResultOp(arithmeticMeanSquareAsDouble)
1313 
1314 /*doc Sequence hash
1315 Returns a Number containing a hash of the Sequence.
1316 */
1317 IoSeqNoArgNumberResultOp(hash)
1318 
1319 #define IoSeqLongArgNumberResultOp(name) \
1320 IoObject *IoSeq_ ## name (IoSeq *self, IoObject *locals, IoMessage *m) \
1321 { return IONUMBER(UArray_ ## name (DATA(self), IoMessage_locals_longArgAt_(m, locals, 0))); }
1322 
1323 //IoSeqLongArgNumberResultOp(setAllBitsTo_)
1324 
1325 /*doc Sequence byteAt(byteIndex)
1326 Returns a Number containing the byte at the byte index value.
1327 */
1328 IoSeqLongArgNumberResultOp(byteAt_)
1329 
1330 /*doc Sequence bitAt(bitIndex)
1331 Returns a Number containing the bit at the bit index value.
1332 */
1333 IoSeqLongArgNumberResultOp(bitAt_)
1334 
1335 /*doc Sequence bitCount
1336 Returns the number of bits in the sequence.
1337 */
1338 IoSeqNoArgNumberResultOp(bitCount)
1339 
1340 #define IoSeqSeqArgNoResultOp(name) \
1341 IoObject *IoSeq_ ## name (IoSeq *self, IoObject *locals, IoMessage *m) \
1342 { IO_ASSERT_NOT_SYMBOL(self); UArray_ ## name (DATA(self), DATA(IoMessage_locals_seqArgAt_(m, locals, 0))); return self; }
1343 
1344 /*doc Sequence bitwiseOr(aSequence)
1345 Updates the receiver to be the result of a bitwiseOr with aSequence. Returns self.
1346 */
1347 IoSeqSeqArgNoResultOp(bitwiseOr_)
1348 
1349 /*doc Sequence bitwiseAnd(aSequence)
1350 Updates the receiver to be the result of a bitwiseAnd with aSequence. Returns self.
1351 */
1352 IoSeqSeqArgNoResultOp(bitwiseAnd_)
1353 
1354 /*doc Sequence bitwiseXor(aSequence)
1355 Updates the receiver to be the result of a bitwiseXor with aSequence. Returns self.
1356 */
1357 IoSeqSeqArgNoResultOp(bitwiseXor_)
1358 
1359 /*doc Sequence bitwiseNot(aSequence)
1360 Updates the receiver to be the result of a bitwiseNot with aSequence. Returns self.
1361 */
1362 IoSeqMutateNoArgNoResultOp(bitwiseNot)
1363 
1364 /*doc Sequence logicalOr(aSequence)
1365 Updates the receiver's values to be the result of a logical OR operations with the values of aSequence. Returns self.
1366 */
1367 IoSeqSeqArgNoResultOp(logicalOr_)
1368 
1369 /*doc Sequence logicalAnd(aSequence)
1370 Updates the receiver's values to be the result of a logical OR operations with the values of aSequence. Returns self.
1371 */
1372 IoSeqSeqArgNoResultOp(logicalAnd_)
1373 
1374 /*doc Sequence Max
1375 Returns the maximum value in the sequence.
1376 */
1377 IoSeqSeqArgNoResultOp(Max)
1378 
1379 /*doc Sequence Min
1380 Returns the minimum value in the sequence.
1381 */
1382 IoSeqSeqArgNoResultOp(Min)
1383 
1384 /*doc Sequence duplicateIndexes
1385 Duplicates all indexes in the receiver.
1386 For example, list(1,2,3) duplicateIndexes == list(1,1,2,2,3,3). Returns self.
1387 */
1388 IoSeqMutateNoArgNoResultOp(duplicateIndexes)
1389 
1390 /*doc Sequence removeOddIndexes
1391 Removes odd indexes in the receiver.
1392 For example, list(1,2,3) removeOddIndexes == list(2). Returns self.
1393 */
1394 IoSeqMutateNoArgNoResultOp(removeOddIndexes)
1395 
1396 /*doc Sequence removeEvenIndexes
1397 Removes even indexes in the receiver.
1398 For example, list(1,2,3) removeEvenIndexes == list(1, 3). Returns self.
1399 */
1400 IoSeqMutateNoArgNoResultOp(removeEvenIndexes)
1401 
1402 /*doc Sequence clear
1403 Set all values in the sequence to 0. Returns self.
1404 */
1405 IoSeqMutateNoArgNoResultOp(clear)
1406 
1407 
1408 void IoSeq_addMutableMethods(IoSeq *self)
1409 {
1410 	IoMethodTable methodTable[] = {
1411 	{"setItemType", IoSeq_setItemType},
1412 	{"setEncoding", IoSeq_setEncoding},
1413 	{"convertToItemType", IoSeq_convertToItemType},
1414 	{"convertToFixedSizeType", IoSeq_convertToFixedSizeType},
1415 	{"copy", IoSeq_copy},
1416 	{"appendSeq", IoSeq_appendSeq},
1417 	{"append", IoSeq_append},
1418 	{"atInsertSeq", IoSeq_atInsertSeq},
1419 	{"insertSeqEvery", IoSeq_insertSeqEvery},
1420 	{"removeAt", IoSeq_removeAt},
1421 	{"removeSlice", IoSeq_removeSlice},
1422 	{"removeLast", IoSeq_removeLast},
1423 	{"leaveThenRemove", IoSeq_leaveThenRemove},
1424 	{"setSize", IoSeq_setSize},
1425 	{"preallocateToSize", IoSeq_preallocateToSize},
1426 	{"replaceSeq", IoSeq_replaceSeq},
1427 	{"removeSeq", IoSeq_removeSeq},
1428 	{"replaceFirstSeq", IoSeq_replaceFirstSeq},
1429 	{"atPut", IoSeq_atPut},
1430 	{"lowercase", IoSeq_lowercase},
1431 	{"uppercase", IoSeq_uppercase},
1432 	{"translate", IoSeq_translate},
1433 
1434 	{"clipBeforeSeq", IoSeq_clipBeforeSeq},
1435 	{"clipAfterSeq",  IoSeq_clipAfterSeq},
1436 	{"clipBeforeEndOfSeq",  IoSeq_clipBeforeEndOfSeq},
1437 	{"clipAfterStartOfSeq", IoSeq_clipAfterStartOfSeq},
1438 
1439 	{"empty", IoSeq_empty},
1440 	{"sort", IoSeq_sort},
1441 	{"reverseInPlace", IoSeq_reverseInPlace},
1442 	{"replaceMap", IoSeq_replaceMap},
1443 
1444 	{"strip",  IoSeq_strip},
1445 	{"lstrip", IoSeq_lstrip},
1446 	{"rstrip", IoSeq_rstrip},
1447 
1448 	{"zero", IoSeq_clear},
1449 
1450 	{"escape",   IoSeq_escape},
1451 	{"unescape", IoSeq_unescape},
1452 	{"removePrefix", IoSeq_removePrefix},
1453 	{"removeSuffix", IoSeq_removeSuffix},
1454 	{"capitalize", IoSeq_capitalize},
1455 	{"appendPathSeq", IoSeq_appendPathSeq},
1456 
1457 	{"interpolateInPlace", IoSeq_interpolateInPlace},
1458 
1459 	{"+=", IoSeq_addEquals},
1460 	{"-=", IoSeq_subtractEquals},
1461 	{"*=", IoSeq_multiplyEquals},
1462 	{"/=", IoSeq_divideEquals},
1463 	{"**=", IoSeq_powerEquals},
1464 
1465 	{"+", IoSeq_add},
1466 	{"-", IoSeq_subtract},
1467 	{"*", IoSeq_multiply},
1468 	{"/", IoSeq_divide},
1469 	{"**", IoSeq_power},
1470 
1471 		//
1472 	{"dotProduct", IoSeq_dotProduct},
1473 	{"sum", IoSeq_sumAsDouble},
1474 	{"product", IoSeq_productAsDouble},
1475 	{"min", IoSeq_minAsDouble},
1476 	{"max", IoSeq_maxAsDouble},
1477 	{"mean", IoSeq_arithmeticMeanAsDouble},
1478 	{"meanSquare", IoSeq_arithmeticMeanSquareAsDouble},
1479 	{"square", IoSeq_square},
1480 	{"sqrt", IoSeq_sqrt},
1481 	{"normalize", IoSeq_normalize},
1482 	{"hash", IoSeq_hash},
1483 
1484 	{"abs", IoSeq_abs},
1485 	{"ceil", IoSeq_ceil},
1486 	{"floor", IoSeq_floor},
1487 	{"log", IoSeq_log},
1488 	{"log10", IoSeq_log10},
1489 	{"negate", IoSeq_negate},
1490 	{"rangeFill", IoSeq_rangeFill},
1491 	{"Min", IoSeq_Min},
1492 	{"Max", IoSeq_Max},
1493 
1494 	{"sin", IoSeq_sin},
1495 	{"cos", IoSeq_cos},
1496 	{"tan", IoSeq_tan},
1497 
1498 	{"asin", IoSeq_asin},
1499 	{"acos", IoSeq_acos},
1500 	{"atan", IoSeq_atan},
1501 
1502 	{"sinh", IoSeq_sinh},
1503 	{"cosh", IoSeq_cosh},
1504 	{"tanh", IoSeq_tanh},
1505 
1506 	{"removeOddIndexes",  IoSeq_removeOddIndexes},
1507 	{"removeEvenIndexes", IoSeq_removeEvenIndexes},
1508 	{"duplicateIndexes",  IoSeq_duplicateIndexes},
1509 
1510 
1511 	//{"setAllBitsTo",  IoSeq_setAllBitsTo_},
1512 	{"byteAt",  IoSeq_byteAt_},
1513 	{"bitAt",  IoSeq_bitAt_},
1514 	{"bitCount",  IoSeq_bitCount},
1515 
1516 	{"bitwiseOr",  IoSeq_bitwiseOr_},
1517 	{"bitwiseAnd",  IoSeq_bitwiseAnd_},
1518 	{"bitwiseXor",  IoSeq_bitwiseXor_},
1519 	{"bitwiseNot",  IoSeq_bitwiseNot},
1520 
1521 	{"logicalOr",  IoSeq_logicalOr_},
1522 	{"setItemsToLong", IoSeq_setItemsToLong_},
1523 	{"setItemsToDouble", IoSeq_setItemsToDouble_},
1524 	{"set", IoSeq_set_},
1525 
1526 	{NULL, NULL},
1527 	};
1528 
1529 	IoObject_addMethodTable_(self, methodTable);
1530 }
1531 #pragma GCC pop
1532