Replace SIZEOF_REGISTER with sizeof(mgreg_t) for consistency with sizeof(gpointer)
[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 MOONLIGHT || NET_4_0 || BOOTSTRAP_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                         bool ok = true;
52                         if (!typeof (TRest).IsGenericType)
53                                 ok = false;
54                         if (ok) {
55                                 Type t = typeof (TRest).GetGenericTypeDefinition ();
56                                 if (!(t == typeof (Tuple<>) || t == typeof (Tuple<,>) || t == typeof (Tuple<,,>) || t == typeof (Tuple<,,,>) || t == typeof (Tuple<,,,,>) || t == typeof (Tuple <,,,,,>) || t == typeof (Tuple<,,,,,,>) || t == typeof (Tuple<,,,,,,,>)))
57                                         ok = false;
58                         }
59                         if (!ok)
60                                 throw new ArgumentException ("The last element of an eight element tuple must be a Tuple.");
61                 }
62         }
63
64         /* The rest is generated by the script at the bottom */
65
66         [Serializable]
67         public class Tuple<T1> : IStructuralEquatable, IStructuralComparable, IComparable
68         {
69                 T1 item1;
70
71                 public Tuple (T1 item1)
72                 {
73                          this.item1 = item1;
74                 }
75
76                 public T1 Item1 {
77                         get { return item1; }
78                 }
79
80                 int IComparable.CompareTo (object obj)
81                 {
82                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
83                 }
84
85                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
86                 {
87                         var t = other as Tuple<T1>;
88                         if (t == null) {
89                                 if (other == null) return 1;
90                                 throw new ArgumentException ();
91                         }
92
93                         return comparer.Compare (item1, t.item1);
94                 }
95
96                 public override bool Equals (object obj)
97                 {
98                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
99                 }
100
101                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
102                 {
103                         var t = other as Tuple<T1>;
104                         if (t == null) {
105                                 if (other == null) return false;
106                                 throw new ArgumentException ();
107                         }
108
109                         return comparer.Equals (item1, t.item1);
110                 }
111
112                 public override int GetHashCode ()
113                 {
114                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
115                 }
116
117                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
118                 {
119                         return comparer.GetHashCode (item1);
120                 }
121
122                 public override string ToString ()
123                 {
124                         return String.Format ("({0})", item1);
125                 }
126         }
127
128         [Serializable]
129         public class Tuple<T1, T2> : IStructuralEquatable, IStructuralComparable, IComparable
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 ();
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                                 if (other == null) return false;
176                                 throw new ArgumentException ();
177                         }
178
179                         return comparer.Equals (item1, t.item1) &&
180                                 comparer.Equals (item2, t.item2);
181                 }
182
183                 public override int GetHashCode ()
184                 {
185                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
186                 }
187
188                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
189                 {
190                         int h = comparer.GetHashCode (item1);
191                         h = (h << 5) - h + comparer.GetHashCode (item2);
192                         return h;
193                 }
194
195                 public override string ToString ()
196                 {
197                         return String.Format ("({0}, {1})", item1, item2);
198                 }
199         }
200
201         [Serializable]
202         public class Tuple<T1, T2, T3> : IStructuralEquatable, IStructuralComparable, IComparable
203         {
204                 T1 item1;
205                 T2 item2;
206                 T3 item3;
207
208                 public Tuple (T1 item1, T2 item2, T3 item3)
209                 {
210                          this.item1 = item1;
211                          this.item2 = item2;
212                          this.item3 = item3;
213                 }
214
215                 public T1 Item1 {
216                         get { return item1; }
217                 }
218
219                 public T2 Item2 {
220                         get { return item2; }
221                 }
222
223                 public T3 Item3 {
224                         get { return item3; }
225                 }
226
227                 int IComparable.CompareTo (object obj)
228                 {
229                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
230                 }
231
232                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
233                 {
234                         var t = other as Tuple<T1, T2, T3>;
235                         if (t == null) {
236                                 if (other == null) return 1;
237                                 throw new ArgumentException ();
238                         }
239
240                         int res = comparer.Compare (item1, t.item1);
241                         if (res != 0) return res;
242                         res = comparer.Compare (item2, t.item2);
243                         if (res != 0) return res;
244                         return comparer.Compare (item3, t.item3);
245                 }
246
247                 public override bool Equals (object obj)
248                 {
249                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
250                 }
251
252                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
253                 {
254                         var t = other as Tuple<T1, T2, T3>;
255                         if (t == null) {
256                                 if (other == null) return false;
257                                 throw new ArgumentException ();
258                         }
259
260                         return comparer.Equals (item1, t.item1) &&
261                                 comparer.Equals (item2, t.item2) &&
262                                 comparer.Equals (item3, t.item3);
263                 }
264
265                 public override int GetHashCode ()
266                 {
267                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
268                 }
269
270                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
271                 {
272                         int h = comparer.GetHashCode (item1);
273                         h = (h << 5) - h + comparer.GetHashCode (item2);
274                         h = (h << 5) - h + comparer.GetHashCode (item3);
275                         return h;
276                 }
277
278                 public override string ToString ()
279                 {
280                         return String.Format ("({0}, {1}, {2})", item1, item2, item3);
281                 }
282         }
283
284         [Serializable]
285         public class Tuple<T1, T2, T3, T4> : IStructuralEquatable, IStructuralComparable, IComparable
286         {
287                 T1 item1;
288                 T2 item2;
289                 T3 item3;
290                 T4 item4;
291
292                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4)
293                 {
294                          this.item1 = item1;
295                          this.item2 = item2;
296                          this.item3 = item3;
297                          this.item4 = item4;
298                 }
299
300                 public T1 Item1 {
301                         get { return item1; }
302                 }
303
304                 public T2 Item2 {
305                         get { return item2; }
306                 }
307
308                 public T3 Item3 {
309                         get { return item3; }
310                 }
311
312                 public T4 Item4 {
313                         get { return item4; }
314                 }
315
316                 int IComparable.CompareTo (object obj)
317                 {
318                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
319                 }
320
321                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
322                 {
323                         var t = other as Tuple<T1, T2, T3, T4>;
324                         if (t == null) {
325                                 if (other == null) return 1;
326                                 throw new ArgumentException ();
327                         }
328
329                         int res = comparer.Compare (item1, t.item1);
330                         if (res != 0) return res;
331                         res = comparer.Compare (item2, t.item2);
332                         if (res != 0) return res;
333                         res = comparer.Compare (item3, t.item3);
334                         if (res != 0) return res;
335                         return comparer.Compare (item4, t.item4);
336                 }
337
338                 public override bool Equals (object obj)
339                 {
340                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
341                 }
342
343                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
344                 {
345                         var t = other as Tuple<T1, T2, T3, T4>;
346                         if (t == null) {
347                                 if (other == null) return false;
348                                 throw new ArgumentException ();
349                         }
350
351                         return comparer.Equals (item1, t.item1) &&
352                                 comparer.Equals (item2, t.item2) &&
353                                 comparer.Equals (item3, t.item3) &&
354                                 comparer.Equals (item4, t.item4);
355                 }
356
357                 public override int GetHashCode ()
358                 {
359                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
360                 }
361
362                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
363                 {
364                         int h = comparer.GetHashCode (item1);
365                         h = (h << 5) - h + comparer.GetHashCode (item2);
366                         h = (h << 5) - h + comparer.GetHashCode (item3);
367                         h = (h << 5) - h + comparer.GetHashCode (item4);
368                         return h;
369                 }
370
371                 public override string ToString ()
372                 {
373                         return String.Format ("({0}, {1}, {2}, {3})", item1, item2, item3, item4);
374                 }
375         }
376
377         [Serializable]
378         public class Tuple<T1, T2, T3, T4, T5> : IStructuralEquatable, IStructuralComparable, IComparable
379         {
380                 T1 item1;
381                 T2 item2;
382                 T3 item3;
383                 T4 item4;
384                 T5 item5;
385
386                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
387                 {
388                          this.item1 = item1;
389                          this.item2 = item2;
390                          this.item3 = item3;
391                          this.item4 = item4;
392                          this.item5 = item5;
393                 }
394
395                 public T1 Item1 {
396                         get { return item1; }
397                 }
398
399                 public T2 Item2 {
400                         get { return item2; }
401                 }
402
403                 public T3 Item3 {
404                         get { return item3; }
405                 }
406
407                 public T4 Item4 {
408                         get { return item4; }
409                 }
410
411                 public T5 Item5 {
412                         get { return item5; }
413                 }
414
415                 int IComparable.CompareTo (object obj)
416                 {
417                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
418                 }
419
420                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
421                 {
422                         var t = other as Tuple<T1, T2, T3, T4, T5>;
423                         if (t == null) {
424                                 if (other == null) return 1;
425                                 throw new ArgumentException ();
426                         }
427
428                         int res = comparer.Compare (item1, t.item1);
429                         if (res != 0) return res;
430                         res = comparer.Compare (item2, t.item2);
431                         if (res != 0) return res;
432                         res = comparer.Compare (item3, t.item3);
433                         if (res != 0) return res;
434                         res = comparer.Compare (item4, t.item4);
435                         if (res != 0) return res;
436                         return comparer.Compare (item5, t.item5);
437                 }
438
439                 public override bool Equals (object obj)
440                 {
441                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
442                 }
443
444                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
445                 {
446                         var t = other as Tuple<T1, T2, T3, T4, T5>;
447                         if (t == null) {
448                                 if (other == null) return false;
449                                 throw new ArgumentException ();
450                         }
451
452                         return comparer.Equals (item1, t.item1) &&
453                                 comparer.Equals (item2, t.item2) &&
454                                 comparer.Equals (item3, t.item3) &&
455                                 comparer.Equals (item4, t.item4) &&
456                                 comparer.Equals (item5, t.item5);
457                 }
458
459                 public override int GetHashCode ()
460                 {
461                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
462                 }
463
464                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
465                 {
466                         int h = comparer.GetHashCode (item1);
467                         h = (h << 5) - h + comparer.GetHashCode (item2);
468                         h = (h << 5) - h + comparer.GetHashCode (item3);
469                         h = (h << 5) - h + comparer.GetHashCode (item4);
470                         h = (h << 5) - h + comparer.GetHashCode (item5);
471                         return h;
472                 }
473
474                 public override string ToString ()
475                 {
476                         return String.Format ("({0}, {1}, {2}, {3}, {4})", item1, item2, item3, item4, item5);
477                 }
478         }
479
480         [Serializable]
481         public class Tuple<T1, T2, T3, T4, T5, T6> : IStructuralEquatable, IStructuralComparable, IComparable
482         {
483                 T1 item1;
484                 T2 item2;
485                 T3 item3;
486                 T4 item4;
487                 T5 item5;
488                 T6 item6;
489
490                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
491                 {
492                          this.item1 = item1;
493                          this.item2 = item2;
494                          this.item3 = item3;
495                          this.item4 = item4;
496                          this.item5 = item5;
497                          this.item6 = item6;
498                 }
499
500                 public T1 Item1 {
501                         get { return item1; }
502                 }
503
504                 public T2 Item2 {
505                         get { return item2; }
506                 }
507
508                 public T3 Item3 {
509                         get { return item3; }
510                 }
511
512                 public T4 Item4 {
513                         get { return item4; }
514                 }
515
516                 public T5 Item5 {
517                         get { return item5; }
518                 }
519
520                 public T6 Item6 {
521                         get { return item6; }
522                 }
523
524                 int IComparable.CompareTo (object obj)
525                 {
526                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
527                 }
528
529                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
530                 {
531                         var t = other as Tuple<T1, T2, T3, T4, T5, T6>;
532                         if (t == null) {
533                                 if (other == null) return 1;
534                                 throw new ArgumentException ();
535                         }
536
537                         int res = comparer.Compare (item1, t.item1);
538                         if (res != 0) return res;
539                         res = comparer.Compare (item2, t.item2);
540                         if (res != 0) return res;
541                         res = comparer.Compare (item3, t.item3);
542                         if (res != 0) return res;
543                         res = comparer.Compare (item4, t.item4);
544                         if (res != 0) return res;
545                         res = comparer.Compare (item5, t.item5);
546                         if (res != 0) return res;
547                         return comparer.Compare (item6, t.item6);
548                 }
549
550                 public override bool Equals (object obj)
551                 {
552                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
553                 }
554
555                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
556                 {
557                         var t = other as Tuple<T1, T2, T3, T4, T5, T6>;
558                         if (t == null) {
559                                 if (other == null) return false;
560                                 throw new ArgumentException ();
561                         }
562
563                         return comparer.Equals (item1, t.item1) &&
564                                 comparer.Equals (item2, t.item2) &&
565                                 comparer.Equals (item3, t.item3) &&
566                                 comparer.Equals (item4, t.item4) &&
567                                 comparer.Equals (item5, t.item5) &&
568                                 comparer.Equals (item6, t.item6);
569                 }
570
571                 public override int GetHashCode ()
572                 {
573                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
574                 }
575
576                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
577                 {
578                         int h = comparer.GetHashCode (item1);
579                         h = (h << 5) - h + comparer.GetHashCode (item2);
580                         h = (h << 5) - h + comparer.GetHashCode (item3);
581                         h = (h << 5) - h + comparer.GetHashCode (item4);
582                         h = (h << 5) - h + comparer.GetHashCode (item5);
583                         h = (h << 5) - h + comparer.GetHashCode (item6);
584                         return h;
585                 }
586
587                 public override string ToString ()
588                 {
589                         return String.Format ("({0}, {1}, {2}, {3}, {4}, {5})", item1, item2, item3, item4, item5, item6);
590                 }
591         }
592
593         [Serializable]
594         public class Tuple<T1, T2, T3, T4, T5, T6, T7> : IStructuralEquatable, IStructuralComparable, IComparable
595         {
596                 T1 item1;
597                 T2 item2;
598                 T3 item3;
599                 T4 item4;
600                 T5 item5;
601                 T6 item6;
602                 T7 item7;
603
604                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
605                 {
606                          this.item1 = item1;
607                          this.item2 = item2;
608                          this.item3 = item3;
609                          this.item4 = item4;
610                          this.item5 = item5;
611                          this.item6 = item6;
612                          this.item7 = item7;
613                 }
614
615                 public T1 Item1 {
616                         get { return item1; }
617                 }
618
619                 public T2 Item2 {
620                         get { return item2; }
621                 }
622
623                 public T3 Item3 {
624                         get { return item3; }
625                 }
626
627                 public T4 Item4 {
628                         get { return item4; }
629                 }
630
631                 public T5 Item5 {
632                         get { return item5; }
633                 }
634
635                 public T6 Item6 {
636                         get { return item6; }
637                 }
638
639                 public T7 Item7 {
640                         get { return item7; }
641                 }
642
643                 int IComparable.CompareTo (object obj)
644                 {
645                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
646                 }
647
648                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
649                 {
650                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
651                         if (t == null) {
652                                 if (other == null) return 1;
653                                 throw new ArgumentException ();
654                         }
655
656                         int res = comparer.Compare (item1, t.item1);
657                         if (res != 0) return res;
658                         res = comparer.Compare (item2, t.item2);
659                         if (res != 0) return res;
660                         res = comparer.Compare (item3, t.item3);
661                         if (res != 0) return res;
662                         res = comparer.Compare (item4, t.item4);
663                         if (res != 0) return res;
664                         res = comparer.Compare (item5, t.item5);
665                         if (res != 0) return res;
666                         res = comparer.Compare (item6, t.item6);
667                         if (res != 0) return res;
668                         return comparer.Compare (item7, t.item7);
669                 }
670
671                 public override bool Equals (object obj)
672                 {
673                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
674                 }
675
676                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
677                 {
678                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
679                         if (t == null) {
680                                 if (other == null) return false;
681                                 throw new ArgumentException ();
682                         }
683
684                         return comparer.Equals (item1, t.item1) &&
685                                 comparer.Equals (item2, t.item2) &&
686                                 comparer.Equals (item3, t.item3) &&
687                                 comparer.Equals (item4, t.item4) &&
688                                 comparer.Equals (item5, t.item5) &&
689                                 comparer.Equals (item6, t.item6) &&
690                                 comparer.Equals (item7, t.item7);
691                 }
692
693                 public override int GetHashCode ()
694                 {
695                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
696                 }
697
698                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
699                 {
700                         int h = comparer.GetHashCode (item1);
701                         h = (h << 5) - h + comparer.GetHashCode (item2);
702                         h = (h << 5) - h + comparer.GetHashCode (item3);
703                         h = (h << 5) - h + comparer.GetHashCode (item4);
704                         h = (h << 5) - h + comparer.GetHashCode (item5);
705                         h = (h << 5) - h + comparer.GetHashCode (item6);
706                         h = (h << 5) - h + comparer.GetHashCode (item7);
707                         return h;
708                 }
709
710                 public override string ToString ()
711                 {
712                         return String.Format ("({0}, {1}, {2}, {3}, {4}, {5}, {6})", item1, item2, item3, item4, item5, item6, item7);
713                 }
714         }
715
716         [Serializable]
717         public partial class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> : IStructuralEquatable, IStructuralComparable, IComparable
718         {
719                 T1 item1;
720                 T2 item2;
721                 T3 item3;
722                 T4 item4;
723                 T5 item5;
724                 T6 item6;
725                 T7 item7;
726                 TRest rest;
727
728                 public T1 Item1 {
729                         get { return item1; }
730                 }
731
732                 public T2 Item2 {
733                         get { return item2; }
734                 }
735
736                 public T3 Item3 {
737                         get { return item3; }
738                 }
739
740                 public T4 Item4 {
741                         get { return item4; }
742                 }
743
744                 public T5 Item5 {
745                         get { return item5; }
746                 }
747
748                 public T6 Item6 {
749                         get { return item6; }
750                 }
751
752                 public T7 Item7 {
753                         get { return item7; }
754                 }
755
756                 public TRest Rest {
757                         get { return rest; }
758                 }
759
760                 int IComparable.CompareTo (object obj)
761                 {
762                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
763                 }
764
765                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
766                 {
767                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>;
768                         if (t == null) {
769                                 if (other == null) return 1;
770                                 throw new ArgumentException ();
771                         }
772
773                         int res = comparer.Compare (item1, t.item1);
774                         if (res != 0) return res;
775                         res = comparer.Compare (item2, t.item2);
776                         if (res != 0) return res;
777                         res = comparer.Compare (item3, t.item3);
778                         if (res != 0) return res;
779                         res = comparer.Compare (item4, t.item4);
780                         if (res != 0) return res;
781                         res = comparer.Compare (item5, t.item5);
782                         if (res != 0) return res;
783                         res = comparer.Compare (item6, t.item6);
784                         if (res != 0) return res;
785                         res = comparer.Compare (item7, t.item7);
786                         if (res != 0) return res;
787                         return comparer.Compare (rest, t.rest);
788                 }
789
790                 public override bool Equals (object obj)
791                 {
792                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
793                 }
794
795                 bool IStructuralEquatable.Equals (object other, IEqualityComparer 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 false;
800                                 throw new ArgumentException ();
801                         }
802
803                         return comparer.Equals (item1, t.item1) &&
804                                 comparer.Equals (item2, t.item2) &&
805                                 comparer.Equals (item3, t.item3) &&
806                                 comparer.Equals (item4, t.item4) &&
807                                 comparer.Equals (item5, t.item5) &&
808                                 comparer.Equals (item6, t.item6) &&
809                                 comparer.Equals (item7, t.item7) &&
810                                 comparer.Equals (rest, t.rest);
811                 }
812
813                 public override int GetHashCode ()
814                 {
815                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
816                 }
817
818                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
819                 {
820                         int h = comparer.GetHashCode (item1);
821                         h = (h << 5) - h + comparer.GetHashCode (item2);
822                         h = (h << 5) - h + comparer.GetHashCode (item3);
823                         h = (h << 5) - h + comparer.GetHashCode (item4);
824                         h = (h << 5) - h + comparer.GetHashCode (item5);
825                         h = (h << 5) - h + comparer.GetHashCode (item6);
826                         h = (h << 5) - h + comparer.GetHashCode (item7);
827                         h = (h << 5) - h + comparer.GetHashCode (rest);
828                         return h;
829                 }
830
831                 public override string ToString ()
832                 {
833                         return String.Format ("({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7})", item1, item2, item3, item4, item5, item6, item7, rest);
834                 }
835         }
836
837 }
838         
839 #endif
840
841 #if FALSE
842
843 //
844 // generator script
845 //
846
847 using System;
848 using System.Text;
849
850 public class TupleGen
851 {
852         public static void Main () {
853                 for (int arity = 1; arity < 9; ++arity) {
854                         string type_name = GetTypeName (arity);
855
856                         Console.WriteLine ("\t[Serializable]");
857                         Console.Write ("\tpublic {0}class ", arity < 8 ? null : "partial ");
858                         Console.Write (type_name);
859                         Console.WriteLine (" : IStructuralEquatable, IStructuralComparable, IComparable");
860                         Console.WriteLine ("\t{");
861                         for (int i = 1; i <= arity; ++i)
862                                 Console.WriteLine ("\t\t{0} {1};", GetItemTypeName (i), GetItemName (i));
863                                 
864                         if (arity < 8) {
865                                 Console.WriteLine ();
866                                 Console.Write ("\t\tpublic Tuple (");
867                                 for (int i = 1; i <= arity; ++i) {
868                                         Console.Write ("{0} {1}", GetItemTypeName (i), GetItemName (i));
869                                         if (i < arity)
870                                                 Console.Write (", ");
871                                 }
872                                 Console.WriteLine (")");
873                                 Console.WriteLine ("\t\t{");
874                                 for (int i = 1; i <= arity; ++i)
875                                         Console.WriteLine ("\t\t\t this.{0} = {0};", GetItemName (i));
876                                 Console.WriteLine ("\t\t}");
877                         }
878
879                         for (int i = 1; i <= arity; ++i) {
880                                 Console.WriteLine ();
881                                 Console.WriteLine ("\t\tpublic {0} {1} {{", GetItemTypeName (i),
882                                         System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase (GetItemName (i)));
883                                 Console.Write ("\t\t\tget { ");
884                                 Console.WriteLine ("return {0}; }}", GetItemName (i));
885                                 Console.WriteLine ("\t\t}");
886                         }
887
888                         Console.WriteLine ();
889                         Console.WriteLine ("\t\tint IComparable.CompareTo (object obj)");
890                         Console.WriteLine ("\t\t{");
891                         Console.WriteLine ("\t\t\treturn ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);");
892                         Console.WriteLine ("\t\t}");
893                         
894                         Console.WriteLine ();
895                         Console.WriteLine ("\t\tint IStructuralComparable.CompareTo (object other, IComparer comparer)");
896                         Console.WriteLine ("\t\t{");
897                         Console.WriteLine ("\t\t\tvar t = other as {0};", type_name);
898                         Console.WriteLine ("\t\t\tif (t == null) {");
899                         Console.WriteLine ("\t\t\t\tif (other == null) return 1;");
900                         Console.WriteLine ("\t\t\t\tthrow new ArgumentException ();");
901                         Console.WriteLine ("\t\t\t}");
902                         Console.WriteLine ();
903                         
904                         for (int i = 1; i < arity; ++i) {
905                                 Console.Write ("\t\t\t");
906                                 if (i == 1)
907                                         Console.Write ("int ");
908
909                                 Console.WriteLine ("res = comparer.Compare ({0}, t.{0});", GetItemName (i));
910                                 Console.WriteLine ("\t\t\tif (res != 0) return res;");
911                         }
912                         Console.WriteLine ("\t\t\treturn comparer.Compare ({0}, t.{0});", GetItemName (arity));
913                         Console.WriteLine ("\t\t}");                    
914                         
915                         Console.WriteLine ();
916                         Console.WriteLine ("\t\tpublic override bool Equals (object obj)");
917                         Console.WriteLine ("\t\t{");
918                         Console.WriteLine ("\t\t\treturn ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);");
919                         Console.WriteLine ("\t\t}");
920                         
921                         Console.WriteLine ();
922                         Console.WriteLine ("\t\tbool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)");
923                         Console.WriteLine ("\t\t{");
924                         Console.WriteLine ("\t\t\tvar t = other as {0};", type_name);
925                         Console.WriteLine ("\t\t\tif (t == null) {");
926                         Console.WriteLine ("\t\t\t\tif (other == null) return false;");
927                         Console.WriteLine ("\t\t\t\tthrow new ArgumentException ();");
928                         Console.WriteLine ("\t\t\t}");
929                         Console.WriteLine ();
930                         Console.Write ("\t\t\treturn");
931                         
932                         for (int i = 1; i <= arity; ++i) {
933                                 if (i == 1)
934                                         Console.Write (" ");
935                                 else
936                                         Console.Write ("\t\t\t\t");
937
938                                 Console.Write ("comparer.Equals ({0}, t.{0})", GetItemName (i));
939                                 if (i != arity)
940                                         Console.WriteLine (" &&");
941                                 else
942                                         Console.WriteLine (";");
943                         }
944                         Console.WriteLine ("\t\t}");
945                         
946                         Console.WriteLine ();
947                         Console.WriteLine ("\t\tpublic override int GetHashCode ()");
948                         Console.WriteLine ("\t\t{");
949                         Console.WriteLine ("\t\t\treturn ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);");
950                         Console.WriteLine ("\t\t}");
951                         
952                         Console.WriteLine ();
953                         Console.WriteLine ("\t\tint IStructuralEquatable.GetHashCode (IEqualityComparer comparer)");
954                         Console.WriteLine ("\t\t{");
955                         if (arity == 1) {
956                                 Console.WriteLine ("\t\t\treturn comparer.GetHashCode ({0});", GetItemName (arity));
957                         } else {
958                                 Console.WriteLine ("\t\t\tint h = comparer.GetHashCode ({0});", GetItemName (1));
959                                 for (int i = 2; i <= arity; ++i)
960                                         Console.WriteLine ("\t\t\th = (h << 5) - h + comparer.GetHashCode ({0});", GetItemName (i));
961                                 Console.WriteLine ("\t\t\treturn h;");
962                         }
963
964                         Console.WriteLine ("\t\t}");
965
966                         Console.WriteLine ();
967                         Console.WriteLine ("\t\tpublic override string ToString ()");
968                         Console.WriteLine ("\t\t{");
969                         Console.Write ("\t\t\treturn String.Format (\"(");
970                         for (int i = 1; i <= arity; ++i) {
971                                 Console.Write ("{" + (i - 1) + "}");
972                                 if (i < arity)
973                                         Console.Write (", ");
974                         }
975                         Console.Write (")\", ");
976                         for (int i = 1; i <= arity; ++i) {
977                                 Console.Write (GetItemName (i));
978                                 if (i < arity)
979                                         Console.Write (", ");
980                         }
981                         Console.WriteLine (");");
982                         Console.WriteLine ("\t\t}");
983
984                         Console.WriteLine ("\t}\n");
985                 }
986         }
987
988         static string GetTypeName (int arity)
989         {
990                 StringBuilder sb = new StringBuilder ();
991                 sb.Append ("Tuple<");
992                 for (int i = 1; i <= arity; ++i) {
993                         sb.Append (GetItemTypeName (i));
994                         if (i < arity)
995                                 sb.Append (", ");
996                 }
997                 sb.Append (">");
998                 
999                 return sb.ToString ();
1000         }
1001         
1002         static string GetItemName (int arity)
1003         {
1004                 return arity < 8 ? "item" + arity.ToString () : "rest";
1005         }
1006         
1007         static string GetItemTypeName (int arity)
1008         {
1009                 return arity < 8 ? "T" + arity.ToString () : "TRest";
1010         }
1011 }
1012
1013 #endif