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