Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCClassLibrary / Common / Collections / Pair.sc
blobb26351d5aa83aaf1f5003022ec11a0ab07c8c62d
1 // LISP-like two element cells
3 Pair : Collection {
5         var <>linkDown, <>linkAcross;
7         *new { arg linkDown, linkAcross;
8                 ^super.newCopyArgs(linkDown, linkAcross)
9         }
11         // create from nested array
12         *newFrom { arg collection;
13                 var linkDown = collection.at(0);
14                 var linkAcross = collection.at(1);
15                 if(linkDown.isKindOf(Collection)) { linkDown = this.newFrom(linkDown) };
16                 if(linkAcross.isKindOf(Collection)) { linkAcross = this.newFrom(linkAcross) };
17                 ^this.new(linkDown, linkAcross)
18         }
21         size { var i = 0, link;
22                 link = linkAcross;
23                 while ({ link.respondsTo('linkAcross') },{
24                         i = i + 1;
25                         link = link.linkAcross;
26                 });
27                 ^i
28         }
29         depth { var i = 0, link;
30                 link = linkDown;
31                 while ({ link.respondsTo('linkDown') },{
32                         i = i + 1;
33                         link = link.linkDown;
34                 });
35                 ^i
36         }
37         do { arg function;
38                 var i = 0, link, res;
39                 link = linkAcross;
40                 while ({ link.respondsTo('linkAcross') },{
41                         i = i + 1;
42                         res = function.value(link, i);
43                         link = link.linkAcross;
44                 });
45                 ^res
46         }
48         traverse { arg function;
49                 // the default traversal order
50                 ^this.depthFirstPreOrderTraversal(function)
51         }
52         depthFirstPreOrderTraversal { arg function;
53                 var link;
54                 function.value(this);
55                 if ( linkDown.respondsTo('depthFirstPreOrderTraversal'), {
56                         linkDown.depthFirstPreOrderTraversal(function);
57                 });
58                 // iterate linkAcross to conserve stack depth
59                 link = linkAcross;
60                 while ({ link.notNil },{
61                         function.value(link);
62                         if (link.respondsTo(\linkDown) and:
63                                 { link.linkDown.respondsTo('depthFirstPreOrderTraversal') }, {
64                                         link.linkDown.depthFirstPreOrderTraversal(function);
65                         });
66                         if(link.respondsTo('linkAcross')) {
67                                 link = link.linkAcross;
68                         } { link = nil };
69                 });
70         }
71         depthFirstPostOrderTraversal { arg function;
72                 var link;
73                 if ( linkDown.respondsTo('depthFirstPostOrderTraversal'), {
74                         linkDown.depthFirstPostOrderTraversal(function);
75                 });
76                 function.value(this);
77                 // iterate linkAcross to conserve stack depth
78                 link = linkAcross;
79                 while ({ link.notNil },{
80                         if (link.respondsTo(\linkDown) and:
81                                 { link.linkDown.respondsTo('depthFirstPostOrderTraversal') }, {
82                                 link.linkDown.depthFirstPostOrderTraversal(function);
83                         });
84                         function.value(link);
85                         if(link.respondsTo('linkAcross')) {
86                                 link = link.linkAcross;
87                         } { link = nil };
88                 });
89         }
91         storeArgs { arg stream;
92                 ^[linkDown, linkAcross]
93         }
95         printOn { arg stream;
96                 stream << this.class.name << "(" <<* this.storeArgs << ")"
97         }
98         storeOn { arg stream;
99                 stream << this.class.name << "(" <<<* this.storeArgs << ")"
100         }