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