Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System / Tuples.cs
1 //
2 // Tuples.cs
3 //
4 // Authors:
5 //  Zoltan Varga (vargaz@gmail.com)
6 //  Marek Safar (marek.safar@gmail.com)
7 //
8 // Copyright (C) 2009 Novell
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 #if NET_4_0
31
32 using System;
33 using System.Collections;
34 using System.Collections.Generic;
35
36 namespace System
37 {
38         public partial class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>
39         {
40                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
41                 {
42                         this.item1 = item1;
43                         this.item2 = item2;
44                         this.item3 = item3;
45                         this.item4 = item4;
46                         this.item5 = item5;
47                         this.item6 = item6;
48                         this.item7 = item7;
49                         this.rest = rest;
50
51                         if (!(rest is ITuple))
52                                 throw new ArgumentException ("rest", "The last element of an eight element tuple must be a Tuple.");
53                 }
54         }
55
56         interface ITuple
57         {
58                 string ToString ();
59         }
60
61         /* The rest is generated by the script at the bottom */
62
63         [Serializable]
64         public class Tuple<T1> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
65         {
66                 T1 item1;
67
68                 public Tuple (T1 item1)
69                 {
70                          this.item1 = item1;
71                 }
72
73                 public T1 Item1 {
74                         get { return item1; }
75                 }
76
77                 int IComparable.CompareTo (object obj)
78                 {
79                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
80                 }
81
82                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
83                 {
84                         var t = other as Tuple<T1>;
85                         if (t == null) {
86                                 if (other == null) return 1;
87                                 throw new ArgumentException ("other");
88                         }
89
90                         return comparer.Compare (item1, t.item1);
91                 }
92
93                 public override bool Equals (object obj)
94                 {
95                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
96                 }
97
98                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
99                 {
100                         var t = other as Tuple<T1>;
101                         if (t == null)
102                                 return false;
103
104                         return comparer.Equals (item1, t.item1);
105                 }
106
107                 public override int GetHashCode ()
108                 {
109                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
110                 }
111
112                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
113                 {
114                         return comparer.GetHashCode (item1);
115                 }
116
117                 string ITuple.ToString ()
118                 {
119                         return String.Format ("{0}", item1);
120                 }
121
122                 public override string ToString ()
123                 {
124                         return "(" + ((ITuple) this).ToString () + ")";
125                 }
126         }
127
128         [Serializable]
129         public class Tuple<T1, T2> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
130         {
131                 T1 item1;
132                 T2 item2;
133
134                 public Tuple (T1 item1, T2 item2)
135                 {
136                          this.item1 = item1;
137                          this.item2 = item2;
138                 }
139
140                 public T1 Item1 {
141                         get { return item1; }
142                 }
143
144                 public T2 Item2 {
145                         get { return item2; }
146                 }
147
148                 int IComparable.CompareTo (object obj)
149                 {
150                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
151                 }
152
153                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
154                 {
155                         var t = other as Tuple<T1, T2>;
156                         if (t == null) {
157                                 if (other == null) return 1;
158                                 throw new ArgumentException ("other");
159                         }
160
161                         int res = comparer.Compare (item1, t.item1);
162                         if (res != 0) return res;
163                         return comparer.Compare (item2, t.item2);
164                 }
165
166                 public override bool Equals (object obj)
167                 {
168                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
169                 }
170
171                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
172                 {
173                         var t = other as Tuple<T1, T2>;
174                         if (t == null)
175                                 return false;
176
177                         return comparer.Equals (item1, t.item1) &&
178                                 comparer.Equals (item2, t.item2);
179                 }
180
181                 public override int GetHashCode ()
182                 {
183                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
184                 }
185
186                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
187                 {
188                         int h0;
189                         h0 = comparer.GetHashCode (item1);
190                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
191                         return h0;
192                 }
193
194                 string ITuple.ToString ()
195                 {
196                         return String.Format ("{0}, {1}", item1, item2);
197                 }
198
199                 public override string ToString ()
200                 {
201                         return "(" + ((ITuple) this).ToString () + ")";
202                 }
203         }
204
205         [Serializable]
206         public class Tuple<T1, T2, T3> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
207         {
208                 T1 item1;
209                 T2 item2;
210                 T3 item3;
211
212                 public Tuple (T1 item1, T2 item2, T3 item3)
213                 {
214                          this.item1 = item1;
215                          this.item2 = item2;
216                          this.item3 = item3;
217                 }
218
219                 public T1 Item1 {
220                         get { return item1; }
221                 }
222
223                 public T2 Item2 {
224                         get { return item2; }
225                 }
226
227                 public T3 Item3 {
228                         get { return item3; }
229                 }
230
231                 int IComparable.CompareTo (object obj)
232                 {
233                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
234                 }
235
236                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
237                 {
238                         var t = other as Tuple<T1, T2, T3>;
239                         if (t == null) {
240                                 if (other == null) return 1;
241                                 throw new ArgumentException ("other");
242                         }
243
244                         int res = comparer.Compare (item1, t.item1);
245                         if (res != 0) return res;
246                         res = comparer.Compare (item2, t.item2);
247                         if (res != 0) return res;
248                         return comparer.Compare (item3, t.item3);
249                 }
250
251                 public override bool Equals (object obj)
252                 {
253                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
254                 }
255
256                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
257                 {
258                         var t = other as Tuple<T1, T2, T3>;
259                         if (t == null)
260                                 return false;
261
262                         return comparer.Equals (item1, t.item1) &&
263                                 comparer.Equals (item2, t.item2) &&
264                                 comparer.Equals (item3, t.item3);
265                 }
266
267                 public override int GetHashCode ()
268                 {
269                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
270                 }
271
272                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
273                 {
274                         int h0;
275                         h0 = comparer.GetHashCode (item1);
276                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
277                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item3);
278                         return h0;
279                 }
280
281                 string ITuple.ToString ()
282                 {
283                         return String.Format ("{0}, {1}, {2}", item1, item2, item3);
284                 }
285
286                 public override string ToString ()
287                 {
288                         return "(" + ((ITuple) this).ToString () + ")";
289                 }
290         }
291
292         [Serializable]
293         public class Tuple<T1, T2, T3, T4> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
294         {
295                 T1 item1;
296                 T2 item2;
297                 T3 item3;
298                 T4 item4;
299
300                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4)
301                 {
302                          this.item1 = item1;
303                          this.item2 = item2;
304                          this.item3 = item3;
305                          this.item4 = item4;
306                 }
307
308                 public T1 Item1 {
309                         get { return item1; }
310                 }
311
312                 public T2 Item2 {
313                         get { return item2; }
314                 }
315
316                 public T3 Item3 {
317                         get { return item3; }
318                 }
319
320                 public T4 Item4 {
321                         get { return item4; }
322                 }
323
324                 int IComparable.CompareTo (object obj)
325                 {
326                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
327                 }
328
329                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
330                 {
331                         var t = other as Tuple<T1, T2, T3, T4>;
332                         if (t == null) {
333                                 if (other == null) return 1;
334                                 throw new ArgumentException ("other");
335                         }
336
337                         int res = comparer.Compare (item1, t.item1);
338                         if (res != 0) return res;
339                         res = comparer.Compare (item2, t.item2);
340                         if (res != 0) return res;
341                         res = comparer.Compare (item3, t.item3);
342                         if (res != 0) return res;
343                         return comparer.Compare (item4, t.item4);
344                 }
345
346                 public override bool Equals (object obj)
347                 {
348                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
349                 }
350
351                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
352                 {
353                         var t = other as Tuple<T1, T2, T3, T4>;
354                         if (t == null)
355                                 return false;
356
357                         return comparer.Equals (item1, t.item1) &&
358                                 comparer.Equals (item2, t.item2) &&
359                                 comparer.Equals (item3, t.item3) &&
360                                 comparer.Equals (item4, t.item4);
361                 }
362
363                 public override int GetHashCode ()
364                 {
365                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
366                 }
367
368                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
369                 {
370                         int h0, h1;
371                         h0 = comparer.GetHashCode (item1);
372                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
373                         h1 = comparer.GetHashCode (item3);
374                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
375                         h0 = (h0 << 5) + h0 ^ h1;
376                         return h0;
377                 }
378
379                 string ITuple.ToString ()
380                 {
381                         return String.Format ("{0}, {1}, {2}, {3}", item1, item2, item3, item4);
382                 }
383
384                 public override string ToString ()
385                 {
386                         return "(" + ((ITuple) this).ToString () + ")";
387                 }
388         }
389
390         [Serializable]
391         public class Tuple<T1, T2, T3, T4, T5> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
392         {
393                 T1 item1;
394                 T2 item2;
395                 T3 item3;
396                 T4 item4;
397                 T5 item5;
398
399                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
400                 {
401                          this.item1 = item1;
402                          this.item2 = item2;
403                          this.item3 = item3;
404                          this.item4 = item4;
405                          this.item5 = item5;
406                 }
407
408                 public T1 Item1 {
409                         get { return item1; }
410                 }
411
412                 public T2 Item2 {
413                         get { return item2; }
414                 }
415
416                 public T3 Item3 {
417                         get { return item3; }
418                 }
419
420                 public T4 Item4 {
421                         get { return item4; }
422                 }
423
424                 public T5 Item5 {
425                         get { return item5; }
426                 }
427
428                 int IComparable.CompareTo (object obj)
429                 {
430                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
431                 }
432
433                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
434                 {
435                         var t = other as Tuple<T1, T2, T3, T4, T5>;
436                         if (t == null) {
437                                 if (other == null) return 1;
438                                 throw new ArgumentException ("other");
439                         }
440
441                         int res = comparer.Compare (item1, t.item1);
442                         if (res != 0) return res;
443                         res = comparer.Compare (item2, t.item2);
444                         if (res != 0) return res;
445                         res = comparer.Compare (item3, t.item3);
446                         if (res != 0) return res;
447                         res = comparer.Compare (item4, t.item4);
448                         if (res != 0) return res;
449                         return comparer.Compare (item5, t.item5);
450                 }
451
452                 public override bool Equals (object obj)
453                 {
454                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
455                 }
456
457                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
458                 {
459                         var t = other as Tuple<T1, T2, T3, T4, T5>;
460                         if (t == null)
461                                 return false;
462
463                         return comparer.Equals (item1, t.item1) &&
464                                 comparer.Equals (item2, t.item2) &&
465                                 comparer.Equals (item3, t.item3) &&
466                                 comparer.Equals (item4, t.item4) &&
467                                 comparer.Equals (item5, t.item5);
468                 }
469
470                 public override int GetHashCode ()
471                 {
472                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
473                 }
474
475                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
476                 {
477                         int h0, h1;
478                         h0 = comparer.GetHashCode (item1);
479                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
480                         h1 = comparer.GetHashCode (item3);
481                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
482                         h0 = (h0 << 5) + h0 ^ h1;
483                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item5);
484                         return h0;
485                 }
486
487                 string ITuple.ToString ()
488                 {
489                         return String.Format ("{0}, {1}, {2}, {3}, {4}", item1, item2, item3, item4, item5);
490                 }
491
492                 public override string ToString ()
493                 {
494                         return "(" + ((ITuple) this).ToString () + ")";
495                 }
496         }
497
498         [Serializable]
499         public class Tuple<T1, T2, T3, T4, T5, T6> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
500         {
501                 T1 item1;
502                 T2 item2;
503                 T3 item3;
504                 T4 item4;
505                 T5 item5;
506                 T6 item6;
507
508                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
509                 {
510                          this.item1 = item1;
511                          this.item2 = item2;
512                          this.item3 = item3;
513                          this.item4 = item4;
514                          this.item5 = item5;
515                          this.item6 = item6;
516                 }
517
518                 public T1 Item1 {
519                         get { return item1; }
520                 }
521
522                 public T2 Item2 {
523                         get { return item2; }
524                 }
525
526                 public T3 Item3 {
527                         get { return item3; }
528                 }
529
530                 public T4 Item4 {
531                         get { return item4; }
532                 }
533
534                 public T5 Item5 {
535                         get { return item5; }
536                 }
537
538                 public T6 Item6 {
539                         get { return item6; }
540                 }
541
542                 int IComparable.CompareTo (object obj)
543                 {
544                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
545                 }
546
547                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
548                 {
549                         var t = other as Tuple<T1, T2, T3, T4, T5, T6>;
550                         if (t == null) {
551                                 if (other == null) return 1;
552                                 throw new ArgumentException ("other");
553                         }
554
555                         int res = comparer.Compare (item1, t.item1);
556                         if (res != 0) return res;
557                         res = comparer.Compare (item2, t.item2);
558                         if (res != 0) return res;
559                         res = comparer.Compare (item3, t.item3);
560                         if (res != 0) return res;
561                         res = comparer.Compare (item4, t.item4);
562                         if (res != 0) return res;
563                         res = comparer.Compare (item5, t.item5);
564                         if (res != 0) return res;
565                         return comparer.Compare (item6, t.item6);
566                 }
567
568                 public override bool Equals (object obj)
569                 {
570                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
571                 }
572
573                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
574                 {
575                         var t = other as Tuple<T1, T2, T3, T4, T5, T6>;
576                         if (t == null)
577                                 return false;
578
579                         return comparer.Equals (item1, t.item1) &&
580                                 comparer.Equals (item2, t.item2) &&
581                                 comparer.Equals (item3, t.item3) &&
582                                 comparer.Equals (item4, t.item4) &&
583                                 comparer.Equals (item5, t.item5) &&
584                                 comparer.Equals (item6, t.item6);
585                 }
586
587                 public override int GetHashCode ()
588                 {
589                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
590                 }
591
592                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
593                 {
594                         int h0, h1;
595                         h0 = comparer.GetHashCode (item1);
596                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
597                         h1 = comparer.GetHashCode (item3);
598                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
599                         h0 = (h0 << 5) + h0 ^ h1;
600                         h1 = comparer.GetHashCode (item5);
601                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
602                         h0 = (h0 << 5) + h0 ^ h1;
603                         return h0;
604                 }
605
606                 string ITuple.ToString ()
607                 {
608                         return String.Format ("{0}, {1}, {2}, {3}, {4}, {5}", item1, item2, item3, item4, item5, item6);
609                 }
610
611                 public override string ToString ()
612                 {
613                         return "(" + ((ITuple) this).ToString () + ")";
614                 }
615         }
616
617         [Serializable]
618         public class Tuple<T1, T2, T3, T4, T5, T6, T7> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
619         {
620                 T1 item1;
621                 T2 item2;
622                 T3 item3;
623                 T4 item4;
624                 T5 item5;
625                 T6 item6;
626                 T7 item7;
627
628                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
629                 {
630                          this.item1 = item1;
631                          this.item2 = item2;
632                          this.item3 = item3;
633                          this.item4 = item4;
634                          this.item5 = item5;
635                          this.item6 = item6;
636                          this.item7 = item7;
637                 }
638
639                 public T1 Item1 {
640                         get { return item1; }
641                 }
642
643                 public T2 Item2 {
644                         get { return item2; }
645                 }
646
647                 public T3 Item3 {
648                         get { return item3; }
649                 }
650
651                 public T4 Item4 {
652                         get { return item4; }
653                 }
654
655                 public T5 Item5 {
656                         get { return item5; }
657                 }
658
659                 public T6 Item6 {
660                         get { return item6; }
661                 }
662
663                 public T7 Item7 {
664                         get { return item7; }
665                 }
666
667                 int IComparable.CompareTo (object obj)
668                 {
669                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
670                 }
671
672                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
673                 {
674                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
675                         if (t == null) {
676                                 if (other == null) return 1;
677                                 throw new ArgumentException ("other");
678                         }
679
680                         int res = comparer.Compare (item1, t.item1);
681                         if (res != 0) return res;
682                         res = comparer.Compare (item2, t.item2);
683                         if (res != 0) return res;
684                         res = comparer.Compare (item3, t.item3);
685                         if (res != 0) return res;
686                         res = comparer.Compare (item4, t.item4);
687                         if (res != 0) return res;
688                         res = comparer.Compare (item5, t.item5);
689                         if (res != 0) return res;
690                         res = comparer.Compare (item6, t.item6);
691                         if (res != 0) return res;
692                         return comparer.Compare (item7, t.item7);
693                 }
694
695                 public override bool Equals (object obj)
696                 {
697                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
698                 }
699
700                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
701                 {
702                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
703                         if (t == null)
704                                 return false;
705
706                         return comparer.Equals (item1, t.item1) &&
707                                 comparer.Equals (item2, t.item2) &&
708                                 comparer.Equals (item3, t.item3) &&
709                                 comparer.Equals (item4, t.item4) &&
710                                 comparer.Equals (item5, t.item5) &&
711                                 comparer.Equals (item6, t.item6) &&
712                                 comparer.Equals (item7, t.item7);
713                 }
714
715                 public override int GetHashCode ()
716                 {
717                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
718                 }
719
720                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
721                 {
722                         int h0, h1;
723                         h0 = comparer.GetHashCode (item1);
724                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
725                         h1 = comparer.GetHashCode (item3);
726                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
727                         h0 = (h0 << 5) + h0 ^ h1;
728                         h1 = comparer.GetHashCode (item5);
729                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
730                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item7);
731                         h0 = (h0 << 5) + h0 ^ h1;
732                         return h0;
733                 }
734
735                 string ITuple.ToString ()
736                 {
737                         return String.Format ("{0}, {1}, {2}, {3}, {4}, {5}, {6}", item1, item2, item3, item4, item5, item6, item7);
738                 }
739
740                 public override string ToString ()
741                 {
742                         return "(" + ((ITuple) this).ToString () + ")";
743                 }
744         }
745
746         [Serializable]
747         public partial class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
748         {
749                 T1 item1;
750                 T2 item2;
751                 T3 item3;
752                 T4 item4;
753                 T5 item5;
754                 T6 item6;
755                 T7 item7;
756                 TRest rest;
757
758                 public T1 Item1 {
759                         get { return item1; }
760                 }
761
762                 public T2 Item2 {
763                         get { return item2; }
764                 }
765
766                 public T3 Item3 {
767                         get { return item3; }
768                 }
769
770                 public T4 Item4 {
771                         get { return item4; }
772                 }
773
774                 public T5 Item5 {
775                         get { return item5; }
776                 }
777
778                 public T6 Item6 {
779                         get { return item6; }
780                 }
781
782                 public T7 Item7 {
783                         get { return item7; }
784                 }
785
786                 public TRest Rest {
787                         get { return rest; }
788                 }
789
790                 int IComparable.CompareTo (object obj)
791                 {
792                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
793                 }
794
795                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
796                 {
797                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>;
798                         if (t == null) {
799                                 if (other == null) return 1;
800                                 throw new ArgumentException ("other");
801                         }
802
803                         int res = comparer.Compare (item1, t.item1);
804                         if (res != 0) return res;
805                         res = comparer.Compare (item2, t.item2);
806                         if (res != 0) return res;
807                         res = comparer.Compare (item3, t.item3);
808                         if (res != 0) return res;
809                         res = comparer.Compare (item4, t.item4);
810                         if (res != 0) return res;
811                         res = comparer.Compare (item5, t.item5);
812                         if (res != 0) return res;
813                         res = comparer.Compare (item6, t.item6);
814                         if (res != 0) return res;
815                         res = comparer.Compare (item7, t.item7);
816                         if (res != 0) return res;
817                         return comparer.Compare (rest, t.rest);
818                 }
819
820                 public override bool Equals (object obj)
821                 {
822                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
823                 }
824
825                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
826                 {
827                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>;
828                         if (t == null)
829                                 return false;
830
831                         return comparer.Equals (item1, t.item1) &&
832                                 comparer.Equals (item2, t.item2) &&
833                                 comparer.Equals (item3, t.item3) &&
834                                 comparer.Equals (item4, t.item4) &&
835                                 comparer.Equals (item5, t.item5) &&
836                                 comparer.Equals (item6, t.item6) &&
837                                 comparer.Equals (item7, t.item7) &&
838                                 comparer.Equals (rest, t.rest);
839                 }
840
841                 public override int GetHashCode ()
842                 {
843                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
844                 }
845
846                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
847                 {
848                         int h0, h1, h2;
849                         h0 = comparer.GetHashCode (item1);
850                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
851                         h1 = comparer.GetHashCode (item3);
852                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
853                         h0 = (h0 << 5) + h0 ^ h1;
854                         h1 = comparer.GetHashCode (item5);
855                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
856                         h2 = comparer.GetHashCode (item7);
857                         h2 = (h2 << 5) + h2 ^ comparer.GetHashCode (rest);
858                         h1 = (h1 << 5) + h1 ^ h2;
859                         h0 = (h0 << 5) + h0 ^ h1;
860                         return h0;
861                 }
862
863                 string ITuple.ToString ()
864                 {
865                         return String.Format ("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", item1, item2, item3, item4, item5, item6, item7, ((ITuple)rest).ToString ());
866                 }
867
868                 public override string ToString ()
869                 {
870                         return "(" + ((ITuple) this).ToString () + ")";
871                 }
872         }
873
874 }
875         
876 #endif
877
878 #if FALSE
879
880 //
881 // generator script
882 //
883
884 using System;
885 using System.Text;
886
887 public class TupleGen
888 {
889         public static void Main () {
890                 for (int arity = 1; arity < 9; ++arity) {
891                         string type_name = GetTypeName (arity);
892
893                         Console.WriteLine ("\t[Serializable]");
894                         Console.Write ("\tpublic {0}class ", arity < 8 ? null : "partial ");
895                         Console.Write (type_name);
896                         Console.WriteLine (" : IStructuralEquatable, IStructuralComparable, IComparable, ITuple");
897                         Console.WriteLine ("\t{");
898                         for (int i = 1; i <= arity; ++i)
899                                 Console.WriteLine ("\t\t{0} {1};", GetItemTypeName (i), GetItemName (i));
900
901                         if (arity < 8) {
902                                 Console.WriteLine ();
903                                 Console.Write ("\t\tpublic Tuple (");
904                                 for (int i = 1; i <= arity; ++i) {
905                                         Console.Write ("{0} {1}", GetItemTypeName (i), GetItemName (i));
906                                         if (i < arity)
907                                                 Console.Write (", ");
908                                 }
909                                 Console.WriteLine (")");
910                                 Console.WriteLine ("\t\t{");
911                                 for (int i = 1; i <= arity; ++i)
912                                         Console.WriteLine ("\t\t\t this.{0} = {0};", GetItemName (i));
913                                 Console.WriteLine ("\t\t}");
914                         }
915
916                         for (int i = 1; i <= arity; ++i) {
917                                 Console.WriteLine ();
918                                 Console.WriteLine ("\t\tpublic {0} {1} {{", GetItemTypeName (i),
919                                         System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase (GetItemName (i)));
920                                 Console.Write ("\t\t\tget { ");
921                                 Console.WriteLine ("return {0}; }}", GetItemName (i));
922                                 Console.WriteLine ("\t\t}");
923                         }
924
925                         Console.WriteLine ();
926                         Console.WriteLine ("\t\tint IComparable.CompareTo (object obj)");
927                         Console.WriteLine ("\t\t{");
928                         Console.WriteLine ("\t\t\treturn ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);");
929                         Console.WriteLine ("\t\t}");
930
931                         Console.WriteLine ();
932                         Console.WriteLine ("\t\tint IStructuralComparable.CompareTo (object other, IComparer comparer)");
933                         Console.WriteLine ("\t\t{");
934                         Console.WriteLine ("\t\t\tvar t = other as {0};", type_name);
935                         Console.WriteLine ("\t\t\tif (t == null) {");
936                         Console.WriteLine ("\t\t\t\tif (other == null) return 1;");
937                         Console.WriteLine ("\t\t\t\tthrow new ArgumentException (\"other\");");
938                         Console.WriteLine ("\t\t\t}");
939                         Console.WriteLine ();
940
941                         for (int i = 1; i < arity; ++i) {
942                                 Console.Write ("\t\t\t");
943                                 if (i == 1)
944                                         Console.Write ("int ");
945
946                                 Console.WriteLine ("res = comparer.Compare ({0}, t.{0});", GetItemName (i));
947                                 Console.WriteLine ("\t\t\tif (res != 0) return res;");
948                         }
949                         Console.WriteLine ("\t\t\treturn comparer.Compare ({0}, t.{0});", GetItemName (arity));
950                         Console.WriteLine ("\t\t}");
951
952                         Console.WriteLine ();
953                         Console.WriteLine ("\t\tpublic override bool Equals (object obj)");
954                         Console.WriteLine ("\t\t{");
955                         Console.WriteLine ("\t\t\treturn ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);");
956                         Console.WriteLine ("\t\t}");
957
958                         Console.WriteLine ();
959                         Console.WriteLine ("\t\tbool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)");
960                         Console.WriteLine ("\t\t{");
961                         Console.WriteLine ("\t\t\tvar t = other as {0};", type_name);
962                         Console.WriteLine ("\t\t\tif (t == null)");
963                         Console.WriteLine ("\t\t\t\treturn false;");
964                         Console.WriteLine ();
965                         Console.Write ("\t\t\treturn");
966
967                         for (int i = 1; i <= arity; ++i) {
968                                 if (i == 1)
969                                         Console.Write (" ");
970                                 else
971                                         Console.Write ("\t\t\t\t");
972
973                                 Console.Write ("comparer.Equals ({0}, t.{0})", GetItemName (i));
974                                 if (i != arity)
975                                         Console.WriteLine (" &&");
976                                 else
977                                         Console.WriteLine (";");
978                         }
979                         Console.WriteLine ("\t\t}");
980
981                         Console.WriteLine ();
982                         Console.WriteLine ("\t\tpublic override int GetHashCode ()");
983                         Console.WriteLine ("\t\t{");
984                         Console.WriteLine ("\t\t\treturn ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);");
985                         Console.WriteLine ("\t\t}");
986
987                         Console.WriteLine ();
988                         Console.WriteLine ("\t\tint IStructuralEquatable.GetHashCode (IEqualityComparer comparer)");
989                         Console.WriteLine ("\t\t{");
990                         if (arity == 1) {
991                                 Console.WriteLine ("\t\t\treturn comparer.GetHashCode ({0});", GetItemName (arity));
992                         } else {
993                                 int varnum = IntLog2 (arity);
994                                 Console.Write ("\t\t\tint h0");
995                                 for (int i = 1; i < varnum; ++i)
996                                         Console.Write (", h{0}", i);
997                                 Console.WriteLine (";");
998
999                                 WriteHash (0, 1, arity);
1000
1001                                 Console.WriteLine ("\t\t\treturn h0;");
1002                         }
1003
1004                         Console.WriteLine ("\t\t}");
1005
1006                         Console.WriteLine ();
1007                         Console.WriteLine ("\t\tstring ITuple.ToString ()");
1008                         Console.WriteLine ("\t\t{");
1009                         Console.Write ("\t\t\treturn String.Format (\"");
1010                         for (int i = 1; i <= arity; ++i) {
1011                                 Console.Write ("{" + (i - 1) + "}");
1012                                 if (i < arity)
1013                                         Console.Write (", ");
1014                         }
1015                         Console.Write ("\", ");
1016                         for (int i = 1; i <= arity; ++i) {
1017                                 var item_name = GetItemName (i);
1018                                 Console.Write (i == 8 ? "((ITuple){0}).ToString ()" : "{0}", item_name);
1019                                 if (i < arity)
1020                                         Console.Write (", ");
1021                         }
1022                         Console.WriteLine (");");
1023                         Console.WriteLine ("\t\t}");
1024
1025                         Console.WriteLine ();
1026                         Console.WriteLine ("\t\tpublic override string ToString ()");
1027                         Console.WriteLine ("\t\t{");
1028                         Console.WriteLine ("\t\t\treturn \"(\" + ((ITuple) this).ToString () + \")\";");
1029                         Console.WriteLine ("\t\t}");
1030
1031                         Console.WriteLine ("\t}\n");
1032                 }
1033         }
1034
1035         static int IntLog2 (int n)
1036         {
1037                 int r = -1;
1038
1039                 while (n != 0) {
1040                         n >>= 1;
1041                         r++;
1042                 }
1043
1044                 return r;
1045         }
1046
1047         static void WriteHash (int destVar, int start, int count)
1048         {
1049                 if (count == 1) {
1050                         Console.WriteLine ("\t\t\th{0} = comparer.GetHashCode ({1});", destVar, GetItemName (start));
1051                 } else {
1052                         int subCount = 1 << IntLog2 (count - 1);
1053                         WriteHash (destVar, start, subCount);
1054                         start += subCount;
1055                         count -= subCount;
1056                         if (count == 1) {
1057                                 Console.WriteLine ("\t\t\th{0} = (h{0} << 5) + h{0} ^ comparer.GetHashCode ({1});", destVar, GetItemName (start));
1058                         } else {
1059                                 WriteHash (destVar + 1, start, count);
1060                                 Console.WriteLine ("\t\t\th{0} = (h{0} << 5) + h{0} ^ h{1};", destVar, destVar + 1);
1061                         }
1062                 }
1063         }
1064
1065         static string GetTypeName (int arity)
1066         {
1067                 StringBuilder sb = new StringBuilder ();
1068                 sb.Append ("Tuple<");
1069                 for (int i = 1; i <= arity; ++i) {
1070                         sb.Append (GetItemTypeName (i));
1071                         if (i < arity)
1072                                 sb.Append (", ");
1073                 }
1074                 sb.Append (">");
1075
1076                 return sb.ToString ();
1077         }
1078
1079         static string GetItemName (int arity)
1080         {
1081                 return arity < 8 ? "item" + arity.ToString () : "rest";
1082         }
1083
1084         static string GetItemTypeName (int arity)
1085         {
1086                 return arity < 8 ? "T" + arity.ToString () : "TRest";
1087         }
1088 }
1089
1090
1091 #endif