[sgen] Untag the vtable during concurrent mark
[mono.git] / mcs / class / Mono.C5 / C5 / Records.cs
1 /*
2  Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft
3  Permission is hereby granted, free of charge, to any person obtaining a copy
4  of this software and associated documentation files (the "Software"), to deal
5  in the Software without restriction, including without limitation the rights
6  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  copies of the Software, and to permit persons to whom the Software is
8  furnished to do so, subject to the following conditions:
9  
10  The above copyright notice and this permission notice shall be included in
11  all copies or substantial portions of the Software.
12  
13  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19  SOFTWARE.
20 */
21
22 using C5;
23 using System;
24 using System.Reflection;
25 using System.Reflection.Emit;
26 using System.Diagnostics;
27
28 namespace C5
29 {
30   struct RecConst
31   {
32     public const int HASHFACTOR = 387281;
33   }
34   /// <summary>
35   /// A generic record type with two fields. 
36   /// <para>
37   /// Equality is defined field by field, using the <code>Equals</code> method 
38   /// inherited from <code>System.Object</code> (i.e. using <see cref="T:C5.NaturalEqualityComparer`1"/>).
39   /// </para>
40   /// <para>
41   /// This type is similar to <see cref="T:C5.KeyValuePair`2"/>, but the latter
42   /// uses <see cref="P:C5.EqualityComparer`1.Default"/> to define field equality instead of <see cref="T:C5.NaturalEqualityComparer`1"/>.
43   /// </para>
44   /// </summary>
45   /// <typeparam name="T1"></typeparam>
46   /// <typeparam name="T2"></typeparam>
47   public struct Rec<T1, T2> : IEquatable<Rec<T1, T2>>, IShowable
48   {
49     /// <summary>
50     /// 
51     /// </summary>
52     public readonly T1 X1;
53     /// <summary>
54     /// 
55     /// </summary>
56     public readonly T2 X2;
57
58     /// <summary>
59     /// 
60     /// </summary>
61     /// <param name="x1"></param>
62     /// <param name="x2"></param>
63     [Tested]
64     public Rec(T1 x1, T2 x2)
65     {
66       this.X1 = x1; this.X2 = x2;
67     }
68
69     /// <summary>
70     /// 
71     /// </summary>
72     /// <param name="other"></param>
73     /// <returns></returns>
74     [Tested]
75     public bool Equals(Rec<T1, T2> other)
76     {
77       return
78         (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
79         (X2 == null ? other.X2 == null : X2.Equals(other.X2))
80         ;
81     }
82     /// <summary>
83     /// 
84     /// </summary>
85     /// <param name="obj"></param>
86     /// <returns></returns>
87     [Tested]
88     public override bool Equals(object obj)
89     {
90       return obj is Rec<T1, T2> ? Equals((Rec<T1, T2>)obj) : false;
91     }
92     /// <summary>
93     /// 
94     /// </summary>
95     /// <param name="record1"></param>
96     /// <param name="record2"></param>
97     /// <returns></returns>
98     [Tested]
99     public static bool operator ==(Rec<T1, T2> record1, Rec<T1, T2> record2)
100     {
101       return record1.Equals(record2);
102     }
103     /// <summary>
104     /// 
105     /// </summary>
106     /// <param name="record1"></param>
107     /// <param name="record2"></param>
108     /// <returns></returns>
109     [Tested]
110     public static bool operator !=(Rec<T1, T2> record1, Rec<T1, T2> record2)
111     {
112       return !record1.Equals(record2);
113     }
114     /// <summary>
115     /// 
116     /// </summary>
117     /// <returns></returns>
118     [Tested]
119     public override int GetHashCode()
120     {
121       //TODO: don't use 0 as hashcode for null, but something else!
122       int hashcode = X1 == null ? 0 : X1.GetHashCode();
123       hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
124       return hashcode;
125     }
126
127     /// <summary>
128     /// 
129     /// </summary>
130     /// <returns></returns>
131     public override string ToString()
132     {
133       return String.Format("({0}, {1})", X1, X2);
134     }
135
136     #region IShowable Members
137
138     /// <summary>
139     /// 
140     /// </summary>
141     /// <param name="stringbuilder"></param>
142     /// <param name="rest"></param>
143     /// <param name="formatProvider"></param>
144     /// <returns></returns>
145     public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
146     {
147       bool incomplete = true;
148       stringbuilder.Append("(");
149       rest -= 2;
150       try
151       {
152         if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
153           return false;
154         stringbuilder.Append(", ");
155         rest -= 2;
156         if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
157           return false;
158       }
159       finally
160       {
161         if (incomplete)
162         {
163           stringbuilder.Append("...");
164           rest -= 3;
165         }
166         stringbuilder.Append(")");
167       }
168       return true;
169     }
170     #endregion
171
172     #region IFormattable Members
173
174     /// <summary>
175     /// 
176     /// </summary>
177     /// <param name="format"></param>
178     /// <param name="formatProvider"></param>
179     /// <returns></returns>
180     public string ToString(string format, IFormatProvider formatProvider)
181     {
182       return Showing.ShowString(this, format, formatProvider);
183     }
184
185     #endregion
186   }
187   /// <summary>
188   /// 
189   /// </summary>
190   /// <typeparam name="T1"></typeparam>
191   /// <typeparam name="T2"></typeparam>
192   /// <typeparam name="T3"></typeparam>
193   public struct Rec<T1, T2, T3> : IEquatable<Rec<T1, T2, T3>>, IShowable
194   {
195     /// <summary>
196     /// 
197     /// </summary>
198     public readonly T1 X1;
199     /// <summary>
200     /// 
201     /// </summary>
202     public readonly T2 X2;
203     /// <summary>
204     /// 
205     /// </summary>
206     public readonly T3 X3;
207     /// <summary>
208     /// 
209     /// </summary>
210     /// <param name="x1"></param>
211     /// <param name="x2"></param>
212     /// <param name="x3"></param>
213     [Tested]
214     public Rec(T1 x1, T2 x2, T3 x3)
215     {
216       this.X1 = x1; this.X2 = x2; this.X3 = x3;
217     }
218     /// <summary>
219     /// 
220     /// </summary>
221     /// <param name="other"></param>
222     /// <returns></returns>
223     [Tested]
224     public bool Equals(Rec<T1, T2, T3> other)
225     {
226       return
227         (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
228         (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&
229         (X3 == null ? other.X3 == null : X3.Equals(other.X3))
230         ;
231     }
232     /// <summary>
233     /// 
234     /// </summary>
235     /// <param name="obj"></param>
236     /// <returns></returns>
237     [Tested]
238     public override bool Equals(object obj)
239     {
240       return obj is Rec<T1, T2, T3> ? Equals((Rec<T1, T2, T3>)obj) : false;
241     }
242     /// <summary>
243     /// 
244     /// </summary>
245     /// <param name="record1"></param>
246     /// <param name="record2"></param>
247     /// <returns></returns>
248     [Tested]
249     public static bool operator ==(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)
250     {
251       return record1.Equals(record2);
252     }
253     /// <summary>
254     /// 
255     /// </summary>
256     /// <param name="record1"></param>
257     /// <param name="record2"></param>
258     /// <returns></returns>
259     [Tested]
260     public static bool operator !=(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)
261     {
262       return !record1.Equals(record2);
263     }
264     /// <summary>
265     /// 
266     /// </summary>
267     /// <returns></returns>
268     [Tested]
269     public override int GetHashCode()
270     {
271       //TODO: don't use 0 as hashcode for null, but something else!
272       int hashcode = X1 == null ? 0 : X1.GetHashCode();
273       hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
274       hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());
275       return hashcode;
276     }
277
278     /// <summary>
279     /// 
280     /// </summary>
281     /// <returns></returns>
282     public override string ToString()
283     {
284       return String.Format("({0}, {1}, {2})", X1, X2, X3);
285     }
286     #region IShowable Members
287
288     /// <summary>
289     /// 
290     /// </summary>
291     /// <param name="stringbuilder"></param>
292     /// <param name="rest"></param>
293     /// <param name="formatProvider"></param>
294     /// <returns></returns>
295     public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
296     {
297       bool incomplete = true;
298       stringbuilder.Append("(");
299       rest -= 2;
300       try
301       {
302         if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
303           return false;
304         stringbuilder.Append(", ");
305         rest -= 2;
306         if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
307           return false;
308         stringbuilder.Append(", ");
309         rest -= 2;
310         if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))
311           return false;
312       }
313       finally
314       {
315         if (incomplete)
316         {
317           stringbuilder.Append("...");
318           rest -= 3;
319         }
320         stringbuilder.Append(")");
321       }
322       return true;
323     }
324     #endregion
325
326     #region IFormattable Members
327
328     /// <summary>
329     /// 
330     /// </summary>
331     /// <param name="format"></param>
332     /// <param name="formatProvider"></param>
333     /// <returns></returns>
334     public string ToString(string format, IFormatProvider formatProvider)
335     {
336       return Showing.ShowString(this, format, formatProvider);
337     }
338
339     #endregion
340   }
341
342   /// <summary>
343   /// 
344   /// </summary>
345   /// <typeparam name="T1"></typeparam>
346   /// <typeparam name="T2"></typeparam>
347   /// <typeparam name="T3"></typeparam>
348   /// <typeparam name="T4"></typeparam>
349   public struct Rec<T1, T2, T3, T4> : IEquatable<Rec<T1, T2, T3, T4>>, IShowable
350   {
351     /// <summary>
352     /// 
353     /// </summary>
354     public readonly T1 X1;
355     /// <summary>
356     /// 
357     /// </summary>
358     public readonly T2 X2;
359     /// <summary>
360     /// 
361     /// </summary>
362     public readonly T3 X3;
363     /// <summary>
364     /// 
365     /// </summary>
366     public readonly T4 X4;
367     /// <summary>
368     /// 
369     /// </summary>
370     /// <param name="x1"></param>
371     /// <param name="x2"></param>
372     /// <param name="x3"></param>
373     /// <param name="x4"></param>
374     [Tested]
375     public Rec(T1 x1, T2 x2, T3 x3, T4 x4)
376     {
377       this.X1 = x1; this.X2 = x2; this.X3 = x3; this.X4 = x4;
378     }
379     /// <summary>
380     /// 
381     /// </summary>
382     /// <param name="other"></param>
383     /// <returns></returns>
384     [Tested]
385     public bool Equals(Rec<T1, T2, T3, T4> other)
386     {
387       return
388         (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
389         (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&
390         (X3 == null ? other.X3 == null : X3.Equals(other.X3)) &&
391         (X4 == null ? other.X4 == null : X4.Equals(other.X4))
392         ;
393     }
394     /// <summary>
395     /// 
396     /// </summary>
397     /// <param name="obj"></param>
398     /// <returns></returns>
399     [Tested]
400     public override bool Equals(object obj)
401     {
402       return obj is Rec<T1, T2, T3, T4> ? Equals((Rec<T1, T2, T3, T4>)obj) : false;
403     }
404
405     /// <summary>
406     /// 
407     /// </summary>
408     /// <param name="record1"></param>
409     /// <param name="record2"></param>
410     /// <returns></returns>
411     [Tested]
412     public static bool operator ==(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)
413     {
414       return record1.Equals(record2);
415     }
416     /// <summary>
417     /// 
418     /// </summary>
419     /// <param name="record1"></param>
420     /// <param name="record2"></param>
421     /// <returns></returns>
422     [Tested]
423     public static bool operator !=(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)
424     {
425       return !record1.Equals(record2);
426     }
427
428     /// <summary>
429     /// 
430     /// </summary>
431     /// <returns></returns>
432     [Tested]
433     public override int GetHashCode()
434     {
435       //TODO: don't use 0 as hashcode for null, but something else!
436       int hashcode = X1 == null ? 0 : X1.GetHashCode();
437       hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
438       hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());
439       hashcode = hashcode * RecConst.HASHFACTOR + (X4 == null ? 0 : X4.GetHashCode());
440       return hashcode;
441     }
442
443     /// <summary>
444     /// 
445     /// </summary>
446     /// <returns></returns>
447     public override string ToString()
448     {
449       return String.Format("({0}, {1}, {2}, {3})", X1, X2, X3, X4);
450     }
451     #region IShowable Members
452
453     /// <summary>
454     /// 
455     /// </summary>
456     /// <param name="stringbuilder"></param>
457     /// <param name="rest"></param>
458     /// <param name="formatProvider"></param>
459     /// <returns></returns>
460     public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
461     {
462       bool incomplete = true;
463       stringbuilder.Append("(");
464       rest -= 2;
465       try
466       {
467         if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
468           return false;
469         stringbuilder.Append(", ");
470         rest -= 2;
471         if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
472           return false;
473         stringbuilder.Append(", ");
474         rest -= 2;
475         if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))
476           return false;
477         stringbuilder.Append(", ");
478         rest -= 2;
479         if (incomplete = !Showing.Show(X4, stringbuilder, ref rest, formatProvider))
480           return false;
481       }
482       finally
483       {
484         if (incomplete)
485         {
486           stringbuilder.Append("...");
487           rest -= 3;
488         }
489         stringbuilder.Append(")");
490       }
491       return true;
492     }
493     #endregion
494
495     #region IFormattable Members
496
497     /// <summary>
498     /// 
499     /// </summary>
500     /// <param name="format"></param>
501     /// <param name="formatProvider"></param>
502     /// <returns></returns>
503     public string ToString(string format, IFormatProvider formatProvider)
504     {
505       return Showing.ShowString(this, format, formatProvider);
506     }
507
508     #endregion
509   }
510 }