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