1 /*  Part of XPCE --- The SWI-Prolog GUI toolkit
2 
3     Author:        Jan Wielemaker and Anjo Anjewierden
4     E-mail:        jan@swi.psy.uva.nl
5     WWW:           http://www.swi.psy.uva.nl/projects/xpce/
6     Copyright (c)  1985-2002, University of Amsterdam
7     All rights reserved.
8 
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions
11     are met:
12 
13     1. Redistributions of source code must retain the above copyright
14        notice, this list of conditions and the following disclaimer.
15 
16     2. Redistributions in binary form must reproduce the above copyright
17        notice, this list of conditions and the following disclaimer in
18        the documentation and/or other materials provided with the
19        distribution.
20 
21     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25     COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32     POSSIBILITY OF SUCH DAMAGE.
33 */
34 
35 #include <h/kernel.h>
36 
37 #define assignVector(v, n, o)	{ assignField((Instance)(v), \
38 					      &(v)->elements[n], \
39 					      (o)); \
40 				}
41 #define indexVector(v, e)	( valInt(e) - valInt(v->offset) - 1 )
42 #define validIndex(v, i)	{ if ( i < 0 || i >= valInt(v->size) ) fail; }
43 
44 status
initialiseVectorv(Vector v,int argc,Any * argv)45 initialiseVectorv(Vector v, int argc, Any *argv)
46 { int n;
47 
48   v->offset = ZERO;
49   v->size = toInt(argc);
50   v->allocated = v->size;
51   if ( argc > 0 )
52   { v->elements = alloc(argc * sizeof(Any));
53 
54     for(n=0; n < argc; n++)
55     { v->elements[n] = NIL;
56       assignVector(v, n, argv[n]);
57     }
58   } else
59     v->elements = NULL;
60 
61   succeed;
62 }
63 
64 
65 static status
cloneVector(Vector v,Vector clone)66 cloneVector(Vector v, Vector clone)
67 { int n, size = valInt(v->size);
68 
69   clonePceSlots(v, clone);
70   clone->allocated = v->size;
71   clone->elements  = alloc(size * sizeof(Any));
72 
73   for( n=0; n<size; n++ )
74   { clone->elements[n] = NIL;
75     assignField((Instance) clone,
76 		&clone->elements[n],
77 		getClone2Object(v->elements[n]));
78   }
79 
80   succeed;
81 }
82 
83 
84 Vector
createVectorv(int argc,Any * argv)85 createVectorv(int argc, Any *argv)
86 { Vector v = alloc(sizeof(struct vector));
87 
88   initHeaderObj(v, ClassVector);
89   v->offset      = (Int) NIL;
90   v->size        = (Int) NIL;
91   v->elements    = NULL;
92 
93   initialiseVectorv(v, argc, argv);
94   createdObject(v, NAME_new);
95 
96   return v;
97 }
98 
99 
100 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
101 Load/store a vector on a file. Format:
102 
103 <vector>		::= {<element>}
104 
105 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
106 
107 static status
storeVector(Vector v,FileObj file)108 storeVector(Vector v, FileObj file)
109 { int n;
110 
111   TRY(storeSlotsObject(v, file));
112   for(n = 0; n < valInt(v->size); n++)
113     TRY(storeObject(v->elements[n], file));
114 
115   succeed;
116 }
117 
118 
119 static status
loadVector(Vector v,IOSTREAM * fd,ClassDef def)120 loadVector(Vector v, IOSTREAM *fd, ClassDef def)
121 { int n;
122   Any obj;
123   int size;
124 
125   loadSlotsObject(v, fd, def);
126   size = valInt(v->size);
127   v->allocated = v->size;
128   v->elements = alloc(size * sizeof(Any));
129   for(n = 0; n < size; n++)
130   { TRY( obj = loadObject(fd) );
131     v->elements[n] = NIL;
132     assignVector(v, n, obj);
133   }
134 
135   succeed;
136 }
137 
138 
139 status
unlinkVector(Vector v)140 unlinkVector(Vector v)
141 { if ( v->elements != NULL )
142     return clearVector(v);
143 
144   succeed;
145 }
146 
147 
148 static status
equalVector(Vector v1,Vector v2)149 equalVector(Vector v1, Vector v2)
150 { if ( classOfObject(v1) == classOfObject(v2) &&
151        v1->size == v2->size &&
152        v1->offset == v2->offset )
153   { Any *e1 = v1->elements;
154     Any *e2 = v2->elements;
155     int n = valInt(v1->size);
156 
157     for(; --n >= 0; e1++, e2++)
158     { if ( *e1 != *e2 )
159 	fail;
160     }
161 
162     succeed;
163   }
164 
165   fail;
166 }
167 
168 
169 Int
getLowIndexVector(Vector v)170 getLowIndexVector(Vector v)
171 { answer(add(v->offset, ONE));
172 }
173 
174 
175 Int
getHighIndexVector(Vector v)176 getHighIndexVector(Vector v)
177 { answer(add(v->size, v->offset));
178 }
179 
180 
181 static status
highIndexVector(Vector v,Int high)182 highIndexVector(Vector v, Int high)
183 { int h  = valInt(high);
184   int oh = valInt(v->offset) + valInt(v->size);
185 
186   if ( oh > h )				/* too long */
187   { int size = h - valInt(v->offset);
188     if ( size > 0 )
189     { Any *elms = alloc(size * sizeof(Any));
190 
191       fillVector(v, NIL, inc(high), DEFAULT); /* dereference */
192       cpdata(elms, v->elements, Any, size);
193       unalloc(valInt(v->allocated)*sizeof(Any), v->elements);
194       v->elements = elms;
195       assign(v,	size,	   toInt(size));
196       assign(v,	allocated, v->size);
197 
198       succeed;
199     } else
200     { return clearVector(v);
201     }
202   } else if ( oh < h )			/* too, short */
203   { return fillVector(v, NIL, toInt(oh+1), inc(high));
204   }
205 
206   succeed;
207 }
208 
209 
210 static status
lowIndexVector(Vector v,Int low)211 lowIndexVector(Vector v, Int low)
212 { int l  = valInt(low);
213   int ol = valInt(v->offset) + 1;
214 
215   if ( l > ol )				/* too long */
216   { int size = valInt(v->size) + valInt(v->offset) - l;
217     if ( size > 0 )
218     { Any *elms = alloc(size * sizeof(Any));
219 
220       fillVector(v, NIL, toInt(l), toInt(ol-1)); /* dereference */
221       cpdata(elms, &v->elements[l-ol], Any, size);
222       unalloc(valInt(v->allocated)*sizeof(Any), v->elements);
223       v->elements = elms;
224       assign(v, size, toInt(size));
225       assign(v, allocated, v->size);
226 
227       succeed;
228     } else
229     { return clearVector(v);
230     }
231   } else if ( l < ol )			/* too, short */
232   { return fillVector(v, NIL, toInt(l), toInt(ol-1));
233   }
234 
235   succeed;
236 }
237 
238 
239 status
rangeVector(Vector v,Int low,Int high)240 rangeVector(Vector v, Int low, Int high)
241 { if ( notDefault(low) )
242     lowIndexVector(v, low);
243   if ( notDefault(high) )
244     highIndexVector(v, high);
245 
246   succeed;
247 }
248 
249 
250 status
clearVector(Vector v)251 clearVector(Vector v)
252 { if ( v->elements )
253   { fillVector(v, NIL, DEFAULT, DEFAULT);
254 
255     unalloc(valInt(v->allocated)*sizeof(Any), v->elements);
256     v->elements = NULL;
257   }
258   assign(v, allocated, ZERO);
259   assign(v, size,      ZERO);
260   assign(v, offset,    ZERO);
261 
262   succeed;
263 }
264 
265 
266 Any
getTailVector(Vector v)267 getTailVector(Vector v)
268 { if ( v->size != ZERO )
269     answer(v->elements[valInt(v->size)-1]);
270 
271   fail;
272 }
273 
274 
275 static Any
getHeadVector(Vector v)276 getHeadVector(Vector v)
277 { if ( v->size != ZERO )
278     answer(v->elements[0]);
279 
280   fail;
281 }
282 
283 
284 Vector
getCopyVector(Vector v)285 getCopyVector(Vector v)
286 { Vector v2 = answerObjectv(classOfObject(v), valInt(v->size), v->elements);
287 
288   assign(v2, offset, v->offset);
289 
290   answer(v2);
291 }
292 
293 
294 status
fillVector(Vector v,Any obj,Int from,Int to)295 fillVector(Vector v, Any obj, Int from, Int to)
296 { int f, t;
297 
298   f = (isDefault(from) ? valInt(getLowIndexVector(v)) : valInt(from));
299   t = (isDefault(to)   ? valInt(getHighIndexVector(v)) : valInt(to));
300 
301   if ( t < f )
302     fail;
303 
304   if ( v->size == ZERO )
305   { int size = t-f+1;
306     int n;
307 
308     assign(v, offset,	 toInt(f - 1));
309     assign(v, size,	 toInt(size));
310     assign(v, allocated, v->size);
311     if ( v->elements )
312       unalloc(0, v->elements);
313     v->elements = alloc(sizeof(Any) * size);
314     for(n=0; n<size; n++)
315     { v->elements[n] = NIL;
316       if ( notNil(obj) )
317 	assignVector(v, n, obj);
318     }
319   } else
320   { elementVector(v, toInt(f), obj);
321     elementVector(v, toInt(t), obj);
322     while( ++f < t )
323       elementVector(v, toInt(f), obj);
324   }
325 
326   succeed;
327 }
328 
329 
330 status
shiftVector(Vector v,Int places)331 shiftVector(Vector v, Int places)
332 { int n = valInt(v->size);
333   int s = valInt(places);
334   int i;
335 
336   if ( s > 0 )
337   { for(i=n-s; i < n; i++)
338       assignVector(v, i, NIL);
339     for(i = n - 1; i >= s; i--)
340       v->elements[i] = v->elements[i-s];
341     for( ; i >= 0; i-- )
342       v->elements[i] = NIL;
343   } else
344   { for(i = 0; i < -s; i++)
345       assignVector(v, i, NIL);
346     for(i = 0; i < n+s; i++)
347       v->elements[i] = v->elements[i-s];
348     for( ; i < n; i++ )
349       v->elements[i] = NIL;
350   }
351 
352   succeed;
353 }
354 
355 
356 Any
getElementVector(Vector v,Int e)357 getElementVector(Vector v, Int e)
358 { int n = indexVector(v, e);
359 
360   validIndex(v, n);
361 
362   answer(v->elements[n]);
363 }
364 
365 
366 status
elementVector(Vector v,Int e,Any obj)367 elementVector(Vector v, Int e, Any obj)
368 { int n = indexVector(v, e);
369 
370   if ( n < 0 )
371   { int nsize = valInt(v->size)-n;
372     Any *newElements = alloc(nsize*sizeof(Any));
373     int m;
374 
375     if ( v->elements )
376     { cpdata(&newElements[-n], v->elements, Any, valInt(v->size));
377       unalloc(valInt(v->allocated)*sizeof(Any), v->elements);
378     }
379     v->elements = newElements;
380     for( m = 0; m < -n; m++ )
381       v->elements[m] = NIL;
382     assignVector(v, 0, obj);
383 
384     assign(v, size,	 toInt(nsize));
385     assign(v, allocated, toInt(nsize));
386     assign(v, offset,	 toInt(valInt(e)-1));
387 
388     succeed;
389   }
390 
391   if ( n >= valInt(v->size) )
392   { int m;
393 
394     if ( n >= valInt(v->allocated) )
395     { int nalloc = max(valInt(v->allocated)*2, n+1);
396       Any *newElements = alloc(nalloc * sizeof(Any));
397 
398       if ( v->elements )
399       { cpdata(newElements, v->elements, Any, valInt(v->size));
400 	unalloc(valInt(v->allocated)*sizeof(Any), v->elements);
401       }
402       v->elements = newElements;
403       assign(v, allocated, toInt(nalloc));
404     }
405     for( m = valInt(v->size); m <= n ; m++ )
406       v->elements[m] = NIL;
407     assignVector(v, n, obj);
408 
409     assign(v, size, toInt(n+1));
410 
411     succeed;
412   }
413 
414   assignVector(v, n, obj);
415 
416   succeed;
417 }
418 
419 
420 status
appendVector(Vector v,int argc,Any obj[])421 appendVector(Vector v, int argc, Any obj[])
422 { if ( argc )
423   { int start = valInt(v->size) + valInt(v->offset) + 1;
424 
425     fillVector(v, NIL, toInt(start), toInt(start + argc - 1));
426     for( ; argc-- > 0; start++, obj++ )
427       elementVector(v, toInt(start), *obj);
428   }
429 
430   succeed;
431 }
432 
433 
434 static status
insertVector(Vector v,Int where,Any obj)435 insertVector(Vector v, Int where, Any obj)
436 { int size   = valInt(v->size);
437   int offset = valInt(v->offset);
438   int i;
439   Any *s, *p;
440 
441   if ( valInt(where) <= offset+1 )
442   { assign(v, offset, toInt(offset+1));
443 
444     return elementVector(v, where, obj);
445   }
446   if ( valInt(where) > size+offset )
447     return elementVector(v, where, obj);
448 
449   elementVector(v, toInt(size+offset+1), NIL);
450   i = indexVector(v, where);
451   s = &v->elements[i];
452   p = &v->elements[valInt(v->size)-1];	/* point to last element */
453   for( ; p>s; p-- )
454   { p[0] = p[-1];
455   }
456   v->elements[i] = NIL;
457   assignVector(v, i, obj);
458 
459   succeed;
460 }
461 
462 
463 static status
sortVector(Vector v,Code code,Int from,Int to)464 sortVector(Vector v, Code code, Int from, Int to)
465 { int f, t, n;
466 
467   f = valInt(v->offset) + 1;
468   t = f + valInt(v->size) - 1;
469 
470   if ( notDefault(from) && valInt(from) > f )
471     f = valInt(from);
472   if ( notDefault(to) && valInt(to) > t )
473     t = valInt(to);
474   if ( t <= f )
475     succeed;
476 
477   n = t-f+1;
478   f -= valInt(v->offset) + 1;
479 
480   { Code old = qsortCompareCode;		/* make reentrant */
481     qsortCompareCode = code;
482 
483     qsort(&v->elements[f], n, sizeof(Any), qsortCompareObjects);
484 
485     qsortCompareCode = old;
486   }
487 
488   succeed;
489 }
490 
491 
492 static status
swapVector(Vector v,Int e1,Int e2)493 swapVector(Vector v, Int e1, Int e2)
494 { int n1 = indexVector(v, e1);
495   int n2 = indexVector(v, e2);
496   Any tmp;
497 
498   validIndex(v, n1);
499   validIndex(v, n2);
500 
501   tmp = v->elements[n1];		/* do not use assign() here: tmp */
502   v->elements[n1] = v->elements[n2];	/* might drop out in that case (JW) */
503   v->elements[n2] = tmp;
504 
505   succeed;
506 }
507 
508 #define BOUNDS(v, l, m) \
509 	{ if ( (v) < (l) ) (v) = (l); else if ( (v) > (m) ) (v) = (m); }
510 
511 static int
get_range(Vector v,Int from,Int to,int * f,int * t)512 get_range(Vector v, Int from, Int to, int *f, int *t)
513 { int low  = valInt(getLowIndexVector(v));
514   int high = valInt(getHighIndexVector(v));
515 
516   if ( low > high )
517     fail;				/* empty vector */
518 
519   if ( isDefault(to) )
520   { if ( isDefault(from) )
521     { *f = low;
522       *t = high;
523     } else				/* from, @default */
524     { int i = valInt(from);
525 
526       if ( i > high )
527 	fail;
528       if ( i < low )
529 	i = low;
530       *f = i;
531       *t = high;
532     }
533   } else
534   { if ( isDefault(from) )		/* @default, to */
535     { int i = valInt(to);
536 
537       if ( low > i )
538 	fail;
539       if ( i > high )
540 	i = high;
541       *t = i;
542       *f = low;
543     } else				/* from, to */
544     { int i = valInt(from);
545 
546       BOUNDS(i, low, high);
547       *f = i;
548       i = valInt(to);
549       BOUNDS(i, low, high);
550       *t = i;
551     }
552   }
553 
554   succeed;
555 }
556 
557 
558 static status
forVector(Vector v,Code code,Int from,Int to,int some)559 forVector(Vector v, Code code, Int from, Int to, int some)
560 { int f, t;
561 
562   if ( get_range(v, from, to, &f, &t) )
563   { int step = (t >= f ? 1 : -1);
564     int offset = valInt(v->offset);
565 
566     for(; f != t+step ; f += step)
567     { Any av[2];
568 
569       av[0] = v->elements[f-offset-1];
570       av[1] = toInt(f);
571       if ( !(forwardCodev(code, 2, av) || some) )
572 	fail;
573     }
574   }
575 
576   succeed;
577 }
578 
579 
580 static status
forAllVector(Vector v,Code code,Int from,Int to)581 forAllVector(Vector v, Code code, Int from, Int to)
582 { return forVector(v, code, from, to, FALSE);
583 }
584 
585 
586 static status
forSomeVector(Vector v,Code code,Int from,Int to)587 forSomeVector(Vector v, Code code, Int from, Int to)
588 { return forVector(v, code, from, to, TRUE);
589 }
590 
591 
592 static Any
getFindVector(Vector v,Code code,Int from,Int to)593 getFindVector(Vector v, Code code, Int from, Int to)
594 { int f, t;
595 
596   if ( get_range(v, from, to, &f, &t) )
597   { int step = (t >= f ? 1 : -1);
598     int offset = valInt(v->offset);
599 
600     for(; f != t+step ; f += step)
601     { Any av[2];
602 
603       av[0] = v->elements[f-offset-1];
604       av[1] = toInt(f);
605       if ( forwardCodev(code, 2, av) )
606 	answer(av[0]);
607     }
608   }
609 
610   fail;
611 }
612 
613 
614 static Chain
getFindAllVector(Vector v,Code code,Int from,Int to)615 getFindAllVector(Vector v, Code code, Int from, Int to)
616 { Chain result = answerObject(ClassChain, EAV);
617   int f, t;
618 
619   if ( get_range(v, from, to, &f, &t) )
620   { int step = (t >= f ? 1 : -1);
621     int offset = valInt(v->offset);
622 
623     for(; f != t+step ; f += step)
624     { Any av[2];
625 
626       av[0] = v->elements[f-offset-1];
627       av[1] = toInt(f);
628       if ( forwardCodev(code, 2, av) )
629 	appendChain(result, av[0]);
630     }
631   }
632 
633   answer(result);
634 }
635 
636 
637 Int
getIndexVector(Vector v,Any obj)638 getIndexVector(Vector v, Any obj)
639 { int n;
640   int size = valInt(v->size);
641 
642   for( n=0; n<size; n++)
643     if ( v->elements[n] == obj )
644       answer(toInt(n + valInt(v->offset) + 1));
645 
646   fail;
647 }
648 
649 
650 static Int
getRindexVector(Vector v,Any obj)651 getRindexVector(Vector v, Any obj)
652 { int n;
653   int size = valInt(v->size);
654 
655   for( n=size-1; n>=0; n--)
656     if ( v->elements[n] == obj )
657       answer(toInt(n + valInt(v->offset) + 1));
658 
659   fail;
660 }
661 
662 		/********************************
663 		*      TERM REPRESENTATION      *
664 		*********************************/
665 
666 Any
getArgVector(Vector v,Int arg)667 getArgVector(Vector v, Int arg)
668 { int n = valInt(arg) - 1;
669 
670   validIndex(v, n);
671 
672   answer(v->elements[n]);
673 }
674 
675 
676 Int
getArityVector(Vector v)677 getArityVector(Vector v)
678 { answer(v->size);
679 }
680 
681 
682 static status
changedVector(Vector v,Any * field)683 changedVector(Vector v, Any *field)
684 { if ( onFlag(v, F_INSPECT) )
685   { Class class = classOfObject(v);
686 
687     if ( notNil(class->changed_messages) )
688     { int index = field - v->elements;
689 
690       if ( index >= 0 && index < valInt(v->size) )
691 	return changedObject(v, toName((Any) toInt(index)), EAV);
692 
693       return changedFieldObject(v, field);
694     }
695   }
696 
697   succeed;
698 }
699 
700 		 /*******************************
701 		 *	 CLASS DECLARATION	*
702 		 *******************************/
703 
704 /* Type declaractions */
705 
706 static char *T_element[] =
707         { "index=int", "value=any" };
708 static char *T_swap[] =
709         { "index_1=int", "index_2=int" };
710 static char *T_fill[] =
711         { "value=any", "from=[int]", "to=[int]" };
712 static char *T_range[] =
713         { "from=[int]", "to=[int]" };
714 static char *T_sort[] =
715         { "compare=code", "from=[int]", "to=[int]" };
716 static char *T_enum[] =
717 	{ "code=code", "from=[int]", "to=[int]" };
718 
719 /* Instance Variables */
720 
721 static vardecl var_vector[] =
722 { IV(NAME_offset, "int", IV_GET,
723      NAME_range, "Offset relative to 1-based"),
724   IV(NAME_size, "0..", IV_GET,
725      NAME_range, "Number of elements"),
726   IV(NAME_allocated, "0..", IV_GET,
727      NAME_internal, "Allocated size of array"),
728   IV(NAME_elements, "alien:Any *", IV_NONE,
729      NAME_storage, "The elements themselves")
730 };
731 
732 /* Send Methods */
733 
734 static senddecl send_vector[] =
735 { SM(NAME_initialise, 1, "element=any ...", initialiseVectorv,
736      DEFAULT, "Create vector with elements at 1, ..."),
737   SM(NAME_unlink, 0, NULL, unlinkVector,
738      DEFAULT, "Deallocates -elements"),
739   SM(NAME_equal, 1, "vector", equalVector,
740      NAME_compare, "Test if both vectors contain the same objects"),
741   SM(NAME_element, 2, T_element, elementVector,
742      NAME_element, "Set specified element"),
743   SM(NAME_insert, 2, T_element, insertVector,
744      NAME_element, "Insert at location, shifting higher elements"),
745   SM(NAME_fill, 3, T_fill, fillVector,
746      NAME_element, "Fill index range with one value"),
747   SM(NAME_forAll, 3, T_enum, forAllVector,
748      NAME_iterate, "Run code on all elements; demand acceptance"),
749   SM(NAME_forSome, 3, T_enum, forSomeVector,
750      NAME_iterate, "Run code on all elements"),
751   SM(NAME_append, 1, "value=any ...", appendVector,
752      NAME_list, "Append element at <-high_index+1"),
753   SM(NAME_sort, 3, T_sort, sortVector,
754      NAME_order, "Sort according to code exit status"),
755   SM(NAME_swap, 2, T_swap, swapVector,
756      NAME_order, "Swap two elements"),
757   SM(NAME_shift, 1, "places=int", shiftVector,
758      NAME_range, "Shift contents by n places"),
759   SM(NAME_clear, 0, NULL, clearVector,
760      NAME_range, "Delete all elements"),
761   SM(NAME_range, 2, T_range, rangeVector,
762      NAME_range, "Determine range")
763 };
764 
765 /* Get Methods */
766 
767 static getdecl get_vector[] =
768 { GM(NAME_Arg, 1, "any", "int", getArgVector,
769      DEFAULT, "Get argument for term"),
770   GM(NAME_Arity, 0, "int", NULL, getArityVector,
771      DEFAULT, "Get arity for term"),
772   GM(NAME_copy, 0, "vector", NULL, getCopyVector,
773      NAME_copy, "Create a copy of a vector"),
774   GM(NAME_element, 1, "any", "index=int", getElementVector,
775      NAME_element, "Get element at index"),
776   GM(NAME_head, 0, "any", NULL, getHeadVector,
777      NAME_element, "First element (as class chain)"),
778   GM(NAME_tail, 0, "any", NULL, getTailVector,
779      NAME_element, "Last element (as class chain)"),
780   GM(NAME_highIndex, 0, "int", NULL, getHighIndexVector,
781      NAME_range, "Get highest valid index"),
782   GM(NAME_lowIndex, 0, "int", NULL, getLowIndexVector,
783      NAME_range, "Get lowest valid index"),
784   GM(NAME_find, 3, "unchecked", T_enum, getFindVector,
785      NAME_search, "First element accepted by code"),
786   GM(NAME_findAll, 3, "unchecked", T_enum, getFindAllVector,
787      NAME_search, "Chain of elements accepted by code"),
788   GM(NAME_index, 1, "int", "any", getIndexVector,
789      NAME_search, "Get first index holding argument"),
790   GM(NAME_rindex, 1, "int", "any", getRindexVector,
791      NAME_search, "Get last index holding argument")
792 };
793 
794 /* Resources */
795 
796 #define rc_vector NULL
797 /*
798 static classvardecl rc_vector[] =
799 {
800 };
801 */
802 
803 /* Class Declaration */
804 
805 ClassDecl(vector_decls,
806           var_vector, send_vector, get_vector, rc_vector,
807           ARGC_UNKNOWN, NULL,
808           "$Rev$");
809 
810 
811 
812 status
makeClassVector(Class class)813 makeClassVector(Class class)
814 { declareClass(class, &vector_decls);
815 
816   setLoadStoreFunctionClass(class, loadVector, storeVector);
817   setCloneFunctionClass(class, cloneVector);
818   setChangedFunctionClass(class, changedVector);
819 
820   succeed;
821 }
822 
823