Merge pull request #847 from ranma42/fsharp-tuple-hashing
[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                         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 h0;
187                         h0 = comparer.GetHashCode (item1);
188                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
189                         return h0;
190                 }
191
192                 public override string ToString ()
193                 {
194                         return String.Format ("({0}, {1})", item1, item2);
195                 }
196         }
197
198         [Serializable]
199         public class Tuple<T1, T2, T3> : IStructuralEquatable, IStructuralComparable, IComparable
200         {
201                 T1 item1;
202                 T2 item2;
203                 T3 item3;
204
205                 public Tuple (T1 item1, T2 item2, T3 item3)
206                 {
207                          this.item1 = item1;
208                          this.item2 = item2;
209                          this.item3 = item3;
210                 }
211
212                 public T1 Item1 {
213                         get { return item1; }
214                 }
215
216                 public T2 Item2 {
217                         get { return item2; }
218                 }
219
220                 public T3 Item3 {
221                         get { return item3; }
222                 }
223
224                 int IComparable.CompareTo (object obj)
225                 {
226                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
227                 }
228
229                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
230                 {
231                         var t = other as Tuple<T1, T2, T3>;
232                         if (t == null) {
233                                 if (other == null) return 1;
234                                 throw new ArgumentException ("other");
235                         }
236
237                         int res = comparer.Compare (item1, t.item1);
238                         if (res != 0) return res;
239                         res = comparer.Compare (item2, t.item2);
240                         if (res != 0) return res;
241                         return comparer.Compare (item3, t.item3);
242                 }
243
244                 public override bool Equals (object obj)
245                 {
246                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
247                 }
248
249                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
250                 {
251                         var t = other as Tuple<T1, T2, T3>;
252                         if (t == null)
253                                 return false;
254
255                         return comparer.Equals (item1, t.item1) &&
256                                 comparer.Equals (item2, t.item2) &&
257                                 comparer.Equals (item3, t.item3);
258                 }
259
260                 public override int GetHashCode ()
261                 {
262                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
263                 }
264
265                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
266                 {
267                         int h0;
268                         h0 = comparer.GetHashCode (item1);
269                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
270                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item3);
271                         return h0;
272                 }
273
274                 public override string ToString ()
275                 {
276                         return String.Format ("({0}, {1}, {2})", item1, item2, item3);
277                 }
278         }
279
280         [Serializable]
281         public class Tuple<T1, T2, T3, T4> : IStructuralEquatable, IStructuralComparable, IComparable
282         {
283                 T1 item1;
284                 T2 item2;
285                 T3 item3;
286                 T4 item4;
287
288                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4)
289                 {
290                          this.item1 = item1;
291                          this.item2 = item2;
292                          this.item3 = item3;
293                          this.item4 = item4;
294                 }
295
296                 public T1 Item1 {
297                         get { return item1; }
298                 }
299
300                 public T2 Item2 {
301                         get { return item2; }
302                 }
303
304                 public T3 Item3 {
305                         get { return item3; }
306                 }
307
308                 public T4 Item4 {
309                         get { return item4; }
310                 }
311
312                 int IComparable.CompareTo (object obj)
313                 {
314                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
315                 }
316
317                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
318                 {
319                         var t = other as Tuple<T1, T2, T3, T4>;
320                         if (t == null) {
321                                 if (other == null) return 1;
322                                 throw new ArgumentException ("other");
323                         }
324
325                         int res = comparer.Compare (item1, t.item1);
326                         if (res != 0) return res;
327                         res = comparer.Compare (item2, t.item2);
328                         if (res != 0) return res;
329                         res = comparer.Compare (item3, t.item3);
330                         if (res != 0) return res;
331                         return comparer.Compare (item4, t.item4);
332                 }
333
334                 public override bool Equals (object obj)
335                 {
336                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
337                 }
338
339                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
340                 {
341                         var t = other as Tuple<T1, T2, T3, T4>;
342                         if (t == null)
343                                 return false;
344
345                         return comparer.Equals (item1, t.item1) &&
346                                 comparer.Equals (item2, t.item2) &&
347                                 comparer.Equals (item3, t.item3) &&
348                                 comparer.Equals (item4, t.item4);
349                 }
350
351                 public override int GetHashCode ()
352                 {
353                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
354                 }
355
356                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
357                 {
358                         int h0, h1;
359                         h0 = comparer.GetHashCode (item1);
360                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
361                         h1 = comparer.GetHashCode (item3);
362                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
363                         h0 = (h0 << 5) + h0 ^ h1;
364                         return h0;
365                 }
366
367                 public override string ToString ()
368                 {
369                         return String.Format ("({0}, {1}, {2}, {3})", item1, item2, item3, item4);
370                 }
371         }
372
373         [Serializable]
374         public class Tuple<T1, T2, T3, T4, T5> : IStructuralEquatable, IStructuralComparable, IComparable
375         {
376                 T1 item1;
377                 T2 item2;
378                 T3 item3;
379                 T4 item4;
380                 T5 item5;
381
382                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
383                 {
384                          this.item1 = item1;
385                          this.item2 = item2;
386                          this.item3 = item3;
387                          this.item4 = item4;
388                          this.item5 = item5;
389                 }
390
391                 public T1 Item1 {
392                         get { return item1; }
393                 }
394
395                 public T2 Item2 {
396                         get { return item2; }
397                 }
398
399                 public T3 Item3 {
400                         get { return item3; }
401                 }
402
403                 public T4 Item4 {
404                         get { return item4; }
405                 }
406
407                 public T5 Item5 {
408                         get { return item5; }
409                 }
410
411                 int IComparable.CompareTo (object obj)
412                 {
413                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
414                 }
415
416                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
417                 {
418                         var t = other as Tuple<T1, T2, T3, T4, T5>;
419                         if (t == null) {
420                                 if (other == null) return 1;
421                                 throw new ArgumentException ("other");
422                         }
423
424                         int res = comparer.Compare (item1, t.item1);
425                         if (res != 0) return res;
426                         res = comparer.Compare (item2, t.item2);
427                         if (res != 0) return res;
428                         res = comparer.Compare (item3, t.item3);
429                         if (res != 0) return res;
430                         res = comparer.Compare (item4, t.item4);
431                         if (res != 0) return res;
432                         return comparer.Compare (item5, t.item5);
433                 }
434
435                 public override bool Equals (object obj)
436                 {
437                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
438                 }
439
440                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
441                 {
442                         var t = other as Tuple<T1, T2, T3, T4, T5>;
443                         if (t == null)
444                                 return false;
445
446                         return comparer.Equals (item1, t.item1) &&
447                                 comparer.Equals (item2, t.item2) &&
448                                 comparer.Equals (item3, t.item3) &&
449                                 comparer.Equals (item4, t.item4) &&
450                                 comparer.Equals (item5, t.item5);
451                 }
452
453                 public override int GetHashCode ()
454                 {
455                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
456                 }
457
458                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
459                 {
460                         int h0, h1;
461                         h0 = comparer.GetHashCode (item1);
462                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
463                         h1 = comparer.GetHashCode (item3);
464                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
465                         h0 = (h0 << 5) + h0 ^ h1;
466                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item5);
467                         return h0;
468                 }
469
470                 public override string ToString ()
471                 {
472                         return String.Format ("({0}, {1}, {2}, {3}, {4})", item1, item2, item3, item4, item5);
473                 }
474         }
475
476         [Serializable]
477         public class Tuple<T1, T2, T3, T4, T5, T6> : IStructuralEquatable, IStructuralComparable, IComparable
478         {
479                 T1 item1;
480                 T2 item2;
481                 T3 item3;
482                 T4 item4;
483                 T5 item5;
484                 T6 item6;
485
486                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
487                 {
488                          this.item1 = item1;
489                          this.item2 = item2;
490                          this.item3 = item3;
491                          this.item4 = item4;
492                          this.item5 = item5;
493                          this.item6 = item6;
494                 }
495
496                 public T1 Item1 {
497                         get { return item1; }
498                 }
499
500                 public T2 Item2 {
501                         get { return item2; }
502                 }
503
504                 public T3 Item3 {
505                         get { return item3; }
506                 }
507
508                 public T4 Item4 {
509                         get { return item4; }
510                 }
511
512                 public T5 Item5 {
513                         get { return item5; }
514                 }
515
516                 public T6 Item6 {
517                         get { return item6; }
518                 }
519
520                 int IComparable.CompareTo (object obj)
521                 {
522                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
523                 }
524
525                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
526                 {
527                         var t = other as Tuple<T1, T2, T3, T4, T5, T6>;
528                         if (t == null) {
529                                 if (other == null) return 1;
530                                 throw new ArgumentException ("other");
531                         }
532
533                         int res = comparer.Compare (item1, t.item1);
534                         if (res != 0) return res;
535                         res = comparer.Compare (item2, t.item2);
536                         if (res != 0) return res;
537                         res = comparer.Compare (item3, t.item3);
538                         if (res != 0) return res;
539                         res = comparer.Compare (item4, t.item4);
540                         if (res != 0) return res;
541                         res = comparer.Compare (item5, t.item5);
542                         if (res != 0) return res;
543                         return comparer.Compare (item6, t.item6);
544                 }
545
546                 public override bool Equals (object obj)
547                 {
548                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
549                 }
550
551                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
552                 {
553                         var t = other as Tuple<T1, T2, T3, T4, T5, T6>;
554                         if (t == null)
555                                 return false;
556
557                         return comparer.Equals (item1, t.item1) &&
558                                 comparer.Equals (item2, t.item2) &&
559                                 comparer.Equals (item3, t.item3) &&
560                                 comparer.Equals (item4, t.item4) &&
561                                 comparer.Equals (item5, t.item5) &&
562                                 comparer.Equals (item6, t.item6);
563                 }
564
565                 public override int GetHashCode ()
566                 {
567                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
568                 }
569
570                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
571                 {
572                         int h0, h1;
573                         h0 = comparer.GetHashCode (item1);
574                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
575                         h1 = comparer.GetHashCode (item3);
576                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
577                         h0 = (h0 << 5) + h0 ^ h1;
578                         h1 = comparer.GetHashCode (item5);
579                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
580                         h0 = (h0 << 5) + h0 ^ h1;
581                         return h0;
582                 }
583
584                 public override string ToString ()
585                 {
586                         return String.Format ("({0}, {1}, {2}, {3}, {4}, {5})", item1, item2, item3, item4, item5, item6);
587                 }
588         }
589
590         [Serializable]
591         public class Tuple<T1, T2, T3, T4, T5, T6, T7> : IStructuralEquatable, IStructuralComparable, IComparable
592         {
593                 T1 item1;
594                 T2 item2;
595                 T3 item3;
596                 T4 item4;
597                 T5 item5;
598                 T6 item6;
599                 T7 item7;
600
601                 public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
602                 {
603                          this.item1 = item1;
604                          this.item2 = item2;
605                          this.item3 = item3;
606                          this.item4 = item4;
607                          this.item5 = item5;
608                          this.item6 = item6;
609                          this.item7 = item7;
610                 }
611
612                 public T1 Item1 {
613                         get { return item1; }
614                 }
615
616                 public T2 Item2 {
617                         get { return item2; }
618                 }
619
620                 public T3 Item3 {
621                         get { return item3; }
622                 }
623
624                 public T4 Item4 {
625                         get { return item4; }
626                 }
627
628                 public T5 Item5 {
629                         get { return item5; }
630                 }
631
632                 public T6 Item6 {
633                         get { return item6; }
634                 }
635
636                 public T7 Item7 {
637                         get { return item7; }
638                 }
639
640                 int IComparable.CompareTo (object obj)
641                 {
642                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
643                 }
644
645                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
646                 {
647                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
648                         if (t == null) {
649                                 if (other == null) return 1;
650                                 throw new ArgumentException ("other");
651                         }
652
653                         int res = comparer.Compare (item1, t.item1);
654                         if (res != 0) return res;
655                         res = comparer.Compare (item2, t.item2);
656                         if (res != 0) return res;
657                         res = comparer.Compare (item3, t.item3);
658                         if (res != 0) return res;
659                         res = comparer.Compare (item4, t.item4);
660                         if (res != 0) return res;
661                         res = comparer.Compare (item5, t.item5);
662                         if (res != 0) return res;
663                         res = comparer.Compare (item6, t.item6);
664                         if (res != 0) return res;
665                         return comparer.Compare (item7, t.item7);
666                 }
667
668                 public override bool Equals (object obj)
669                 {
670                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
671                 }
672
673                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
674                 {
675                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
676                         if (t == null)
677                                 return false;
678
679                         return comparer.Equals (item1, t.item1) &&
680                                 comparer.Equals (item2, t.item2) &&
681                                 comparer.Equals (item3, t.item3) &&
682                                 comparer.Equals (item4, t.item4) &&
683                                 comparer.Equals (item5, t.item5) &&
684                                 comparer.Equals (item6, t.item6) &&
685                                 comparer.Equals (item7, t.item7);
686                 }
687
688                 public override int GetHashCode ()
689                 {
690                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
691                 }
692
693                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
694                 {
695                         int h0, h1;
696                         h0 = comparer.GetHashCode (item1);
697                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
698                         h1 = comparer.GetHashCode (item3);
699                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
700                         h0 = (h0 << 5) + h0 ^ h1;
701                         h1 = comparer.GetHashCode (item5);
702                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
703                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item7);
704                         h0 = (h0 << 5) + h0 ^ h1;
705                         return h0;
706                 }
707
708                 public override string ToString ()
709                 {
710                         return String.Format ("({0}, {1}, {2}, {3}, {4}, {5}, {6})", item1, item2, item3, item4, item5, item6, item7);
711                 }
712         }
713
714         [Serializable]
715         public partial class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> : IStructuralEquatable, IStructuralComparable, IComparable
716         {
717                 T1 item1;
718                 T2 item2;
719                 T3 item3;
720                 T4 item4;
721                 T5 item5;
722                 T6 item6;
723                 T7 item7;
724                 TRest rest;
725
726                 public T1 Item1 {
727                         get { return item1; }
728                 }
729
730                 public T2 Item2 {
731                         get { return item2; }
732                 }
733
734                 public T3 Item3 {
735                         get { return item3; }
736                 }
737
738                 public T4 Item4 {
739                         get { return item4; }
740                 }
741
742                 public T5 Item5 {
743                         get { return item5; }
744                 }
745
746                 public T6 Item6 {
747                         get { return item6; }
748                 }
749
750                 public T7 Item7 {
751                         get { return item7; }
752                 }
753
754                 public TRest Rest {
755                         get { return rest; }
756                 }
757
758                 int IComparable.CompareTo (object obj)
759                 {
760                         return ((IStructuralComparable) this).CompareTo (obj, Comparer<object>.Default);
761                 }
762
763                 int IStructuralComparable.CompareTo (object other, IComparer comparer)
764                 {
765                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>;
766                         if (t == null) {
767                                 if (other == null) return 1;
768                                 throw new ArgumentException ("other");
769                         }
770
771                         int res = comparer.Compare (item1, t.item1);
772                         if (res != 0) return res;
773                         res = comparer.Compare (item2, t.item2);
774                         if (res != 0) return res;
775                         res = comparer.Compare (item3, t.item3);
776                         if (res != 0) return res;
777                         res = comparer.Compare (item4, t.item4);
778                         if (res != 0) return res;
779                         res = comparer.Compare (item5, t.item5);
780                         if (res != 0) return res;
781                         res = comparer.Compare (item6, t.item6);
782                         if (res != 0) return res;
783                         res = comparer.Compare (item7, t.item7);
784                         if (res != 0) return res;
785                         return comparer.Compare (rest, t.rest);
786                 }
787
788                 public override bool Equals (object obj)
789                 {
790                         return ((IStructuralEquatable) this).Equals (obj, EqualityComparer<object>.Default);
791                 }
792
793                 bool IStructuralEquatable.Equals (object other, IEqualityComparer comparer)
794                 {
795                         var t = other as Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>;
796                         if (t == null)
797                                 return false;
798
799                         return comparer.Equals (item1, t.item1) &&
800                                 comparer.Equals (item2, t.item2) &&
801                                 comparer.Equals (item3, t.item3) &&
802                                 comparer.Equals (item4, t.item4) &&
803                                 comparer.Equals (item5, t.item5) &&
804                                 comparer.Equals (item6, t.item6) &&
805                                 comparer.Equals (item7, t.item7) &&
806                                 comparer.Equals (rest, t.rest);
807                 }
808
809                 public override int GetHashCode ()
810                 {
811                         return ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);
812                 }
813
814                 int IStructuralEquatable.GetHashCode (IEqualityComparer comparer)
815                 {
816                         int h0, h1, h2;
817                         h0 = comparer.GetHashCode (item1);
818                         h0 = (h0 << 5) + h0 ^ comparer.GetHashCode (item2);
819                         h1 = comparer.GetHashCode (item3);
820                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item4);
821                         h0 = (h0 << 5) + h0 ^ h1;
822                         h1 = comparer.GetHashCode (item5);
823                         h1 = (h1 << 5) + h1 ^ comparer.GetHashCode (item6);
824                         h2 = comparer.GetHashCode (item7);
825                         h2 = (h2 << 5) + h2 ^ comparer.GetHashCode (rest);
826                         h1 = (h1 << 5) + h1 ^ h2;
827                         h0 = (h0 << 5) + h0 ^ h1;
828                         return h0;
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 (\"other\");");
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\treturn false;");
927                         Console.WriteLine ();
928                         Console.Write ("\t\t\treturn");
929                         
930                         for (int i = 1; i <= arity; ++i) {
931                                 if (i == 1)
932                                         Console.Write (" ");
933                                 else
934                                         Console.Write ("\t\t\t\t");
935
936                                 Console.Write ("comparer.Equals ({0}, t.{0})", GetItemName (i));
937                                 if (i != arity)
938                                         Console.WriteLine (" &&");
939                                 else
940                                         Console.WriteLine (";");
941                         }
942                         Console.WriteLine ("\t\t}");
943                         
944                         Console.WriteLine ();
945                         Console.WriteLine ("\t\tpublic override int GetHashCode ()");
946                         Console.WriteLine ("\t\t{");
947                         Console.WriteLine ("\t\t\treturn ((IStructuralEquatable) this).GetHashCode (EqualityComparer<object>.Default);");
948                         Console.WriteLine ("\t\t}");
949                         
950                         Console.WriteLine ();
951                         Console.WriteLine ("\t\tint IStructuralEquatable.GetHashCode (IEqualityComparer comparer)");
952                         Console.WriteLine ("\t\t{");
953                         if (arity == 1) {
954                                 Console.WriteLine ("\t\t\treturn comparer.GetHashCode ({0});", GetItemName (arity));
955                         } else {
956                                 int varnum = IntLog2(arity);
957                                 Console.Write ("\t\t\tint h0");
958                                 for (int i = 1; i < varnum; ++i)
959                                         Console.Write (", h{0}", i);
960                                 Console.WriteLine (";");
961
962                                 WriteHash(0, 1, arity);
963
964                                 Console.WriteLine ("\t\t\treturn h0;");
965                         }
966
967                         Console.WriteLine ("\t\t}");
968
969                         Console.WriteLine ();
970                         Console.WriteLine ("\t\tpublic override string ToString ()");
971                         Console.WriteLine ("\t\t{");
972                         Console.Write ("\t\t\treturn String.Format (\"(");
973                         for (int i = 1; i <= arity; ++i) {
974                                 Console.Write ("{" + (i - 1) + "}");
975                                 if (i < arity)
976                                         Console.Write (", ");
977                         }
978                         Console.Write (")\", ");
979                         for (int i = 1; i <= arity; ++i) {
980                                 Console.Write (GetItemName (i));
981                                 if (i < arity)
982                                         Console.Write (", ");
983                         }
984                         Console.WriteLine (");");
985                         Console.WriteLine ("\t\t}");
986
987                         Console.WriteLine ("\t}\n");
988                 }
989         }
990
991         static int IntLog2 (int n)
992         {
993                 int r = -1;
994
995                 while (n != 0) {
996                         n >>= 1;
997                         r++;
998                 }
999
1000                 return r;
1001         }
1002
1003         static void WriteHash (int destVar, int start, int count)
1004         {
1005                 if (count == 1) {
1006                         Console.WriteLine ("\t\t\th{0} = comparer.GetHashCode ({1});", destVar, GetItemName (start));
1007                 } else {
1008                         int subCount = 1 << IntLog2(count-1);
1009                         computeHash(destVar, start, subCount);
1010                         start += subCount;
1011                         count -= subCount;
1012                         if (count == 1) {
1013                                 Console.WriteLine ("\t\t\th{0} = (h{0} << 5) + h{0} ^ comparer.GetHashCode ({1});", destVar, GetItemName (start));
1014                         } else {
1015                                 WriteHash(destVar+1, start, count);
1016                                 Console.WriteLine ("\t\t\th{0} = (h{0} << 5) + h{0} ^ h{1};", destVar, destVar+1);
1017                         }
1018                 }
1019         }
1020
1021         static string GetTypeName (int arity)
1022         {
1023                 StringBuilder sb = new StringBuilder ();
1024                 sb.Append ("Tuple<");
1025                 for (int i = 1; i <= arity; ++i) {
1026                         sb.Append (GetItemTypeName (i));
1027                         if (i < arity)
1028                                 sb.Append (", ");
1029                 }
1030                 sb.Append (">");
1031                 
1032                 return sb.ToString ();
1033         }
1034         
1035         static string GetItemName (int arity)
1036         {
1037                 return arity < 8 ? "item" + arity.ToString () : "rest";
1038         }
1039         
1040         static string GetItemTypeName (int arity)
1041         {
1042                 return arity < 8 ? "T" + arity.ToString () : "TRest";
1043         }
1044 }
1045
1046 #endif