3 Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft
\r
4 Permission is hereby granted, free of charge, to any person obtaining a copy
\r
5 of this software and associated documentation files (the "Software"), to deal
\r
6 in the Software without restriction, including without limitation the rights
\r
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
8 copies of the Software, and to permit persons to whom the Software is
\r
9 furnished to do so, subject to the following conditions:
\r
11 The above copyright notice and this permission notice shall be included in
\r
12 all copies or substantial portions of the Software.
\r
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
25 using System.Reflection;
\r
26 using System.Reflection.Emit;
\r
27 using System.Diagnostics;
\r
33 public const int HASHFACTOR = 387281;
\r
36 /// A generic record type with two fields.
\r
38 /// Equality is defined field by field, using the <code>Equals</code> method
\r
39 /// inherited from <code>System.Object</code> (i.e. using <see cref="T:C5.NaturalEqualityComparer`1"/>).
\r
42 /// This type is similar to <see cref="T:C5.KeyValuePair`2"/>, but the latter
\r
43 /// uses <see cref="P:C5.EqualityComparer`1.Default"/> to define field equality instead of <see cref="T:C5.NaturalEqualityComparer`1"/>.
\r
46 /// <typeparam name="T1"></typeparam>
\r
47 /// <typeparam name="T2"></typeparam>
\r
48 public struct Rec<T1, T2> : IEquatable<Rec<T1, T2>>, IShowable
\r
53 public readonly T1 X1;
\r
57 public readonly T2 X2;
\r
62 /// <param name="x1"></param>
\r
63 /// <param name="x2"></param>
\r
65 public Rec(T1 x1, T2 x2)
\r
67 this.X1 = x1; this.X2 = x2;
\r
73 /// <param name="other"></param>
\r
74 /// <returns></returns>
\r
76 public bool Equals(Rec<T1, T2> other)
\r
79 (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
\r
80 (X2 == null ? other.X2 == null : X2.Equals(other.X2))
\r
86 /// <param name="obj"></param>
\r
87 /// <returns></returns>
\r
89 public override bool Equals(object obj)
\r
91 return obj is Rec<T1, T2> ? Equals((Rec<T1, T2>)obj) : false;
\r
96 /// <param name="record1"></param>
\r
97 /// <param name="record2"></param>
\r
98 /// <returns></returns>
\r
100 public static bool operator ==(Rec<T1, T2> record1, Rec<T1, T2> record2)
\r
102 return record1.Equals(record2);
\r
107 /// <param name="record1"></param>
\r
108 /// <param name="record2"></param>
\r
109 /// <returns></returns>
\r
111 public static bool operator !=(Rec<T1, T2> record1, Rec<T1, T2> record2)
\r
113 return !record1.Equals(record2);
\r
118 /// <returns></returns>
\r
120 public override int GetHashCode()
\r
122 //TODO: don't use 0 as hashcode for null, but something else!
\r
123 int hashcode = X1 == null ? 0 : X1.GetHashCode();
\r
124 hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
\r
131 /// <returns></returns>
\r
132 public override string ToString()
\r
134 return String.Format("({0}, {1})", X1, X2);
\r
137 #region IShowable Members
\r
142 /// <param name="stringbuilder"></param>
\r
143 /// <param name="rest"></param>
\r
144 /// <param name="formatProvider"></param>
\r
145 /// <returns></returns>
\r
146 public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
\r
148 bool incomplete = true;
\r
149 stringbuilder.Append("(");
\r
153 if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
\r
155 stringbuilder.Append(", ");
\r
157 if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
\r
164 stringbuilder.Append("...");
\r
167 stringbuilder.Append(")");
\r
173 #region IFormattable Members
\r
178 /// <param name="format"></param>
\r
179 /// <param name="formatProvider"></param>
\r
180 /// <returns></returns>
\r
181 public string ToString(string format, IFormatProvider formatProvider)
\r
183 return Showing.ShowString(this, format, formatProvider);
\r
191 /// <typeparam name="T1"></typeparam>
\r
192 /// <typeparam name="T2"></typeparam>
\r
193 /// <typeparam name="T3"></typeparam>
\r
194 public struct Rec<T1, T2, T3> : IEquatable<Rec<T1, T2, T3>>, IShowable
\r
199 public readonly T1 X1;
\r
203 public readonly T2 X2;
\r
207 public readonly T3 X3;
\r
211 /// <param name="x1"></param>
\r
212 /// <param name="x2"></param>
\r
213 /// <param name="x3"></param>
\r
215 public Rec(T1 x1, T2 x2, T3 x3)
\r
217 this.X1 = x1; this.X2 = x2; this.X3 = x3;
\r
222 /// <param name="other"></param>
\r
223 /// <returns></returns>
\r
225 public bool Equals(Rec<T1, T2, T3> other)
\r
228 (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
\r
229 (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&
\r
230 (X3 == null ? other.X3 == null : X3.Equals(other.X3))
\r
236 /// <param name="obj"></param>
\r
237 /// <returns></returns>
\r
239 public override bool Equals(object obj)
\r
241 return obj is Rec<T1, T2, T3> ? Equals((Rec<T1, T2, T3>)obj) : false;
\r
246 /// <param name="record1"></param>
\r
247 /// <param name="record2"></param>
\r
248 /// <returns></returns>
\r
250 public static bool operator ==(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)
\r
252 return record1.Equals(record2);
\r
257 /// <param name="record1"></param>
\r
258 /// <param name="record2"></param>
\r
259 /// <returns></returns>
\r
261 public static bool operator !=(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)
\r
263 return !record1.Equals(record2);
\r
268 /// <returns></returns>
\r
270 public override int GetHashCode()
\r
272 //TODO: don't use 0 as hashcode for null, but something else!
\r
273 int hashcode = X1 == null ? 0 : X1.GetHashCode();
\r
274 hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
\r
275 hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());
\r
282 /// <returns></returns>
\r
283 public override string ToString()
\r
285 return String.Format("({0}, {1}, {2})", X1, X2, X3);
\r
287 #region IShowable Members
\r
292 /// <param name="stringbuilder"></param>
\r
293 /// <param name="rest"></param>
\r
294 /// <param name="formatProvider"></param>
\r
295 /// <returns></returns>
\r
296 public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
\r
298 bool incomplete = true;
\r
299 stringbuilder.Append("(");
\r
303 if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
\r
305 stringbuilder.Append(", ");
\r
307 if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
\r
309 stringbuilder.Append(", ");
\r
311 if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))
\r
318 stringbuilder.Append("...");
\r
321 stringbuilder.Append(")");
\r
327 #region IFormattable Members
\r
332 /// <param name="format"></param>
\r
333 /// <param name="formatProvider"></param>
\r
334 /// <returns></returns>
\r
335 public string ToString(string format, IFormatProvider formatProvider)
\r
337 return Showing.ShowString(this, format, formatProvider);
\r
346 /// <typeparam name="T1"></typeparam>
\r
347 /// <typeparam name="T2"></typeparam>
\r
348 /// <typeparam name="T3"></typeparam>
\r
349 /// <typeparam name="T4"></typeparam>
\r
350 public struct Rec<T1, T2, T3, T4> : IEquatable<Rec<T1, T2, T3, T4>>, IShowable
\r
355 public readonly T1 X1;
\r
359 public readonly T2 X2;
\r
363 public readonly T3 X3;
\r
367 public readonly T4 X4;
\r
371 /// <param name="x1"></param>
\r
372 /// <param name="x2"></param>
\r
373 /// <param name="x3"></param>
\r
374 /// <param name="x4"></param>
\r
376 public Rec(T1 x1, T2 x2, T3 x3, T4 x4)
\r
378 this.X1 = x1; this.X2 = x2; this.X3 = x3; this.X4 = x4;
\r
383 /// <param name="other"></param>
\r
384 /// <returns></returns>
\r
386 public bool Equals(Rec<T1, T2, T3, T4> other)
\r
389 (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
\r
390 (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&
\r
391 (X3 == null ? other.X3 == null : X3.Equals(other.X3)) &&
\r
392 (X4 == null ? other.X4 == null : X4.Equals(other.X4))
\r
398 /// <param name="obj"></param>
\r
399 /// <returns></returns>
\r
401 public override bool Equals(object obj)
\r
403 return obj is Rec<T1, T2, T3, T4> ? Equals((Rec<T1, T2, T3, T4>)obj) : false;
\r
409 /// <param name="record1"></param>
\r
410 /// <param name="record2"></param>
\r
411 /// <returns></returns>
\r
413 public static bool operator ==(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)
\r
415 return record1.Equals(record2);
\r
420 /// <param name="record1"></param>
\r
421 /// <param name="record2"></param>
\r
422 /// <returns></returns>
\r
424 public static bool operator !=(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)
\r
426 return !record1.Equals(record2);
\r
432 /// <returns></returns>
\r
434 public override int GetHashCode()
\r
436 //TODO: don't use 0 as hashcode for null, but something else!
\r
437 int hashcode = X1 == null ? 0 : X1.GetHashCode();
\r
438 hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
\r
439 hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());
\r
440 hashcode = hashcode * RecConst.HASHFACTOR + (X4 == null ? 0 : X4.GetHashCode());
\r
447 /// <returns></returns>
\r
448 public override string ToString()
\r
450 return String.Format("({0}, {1}, {2}, {3})", X1, X2, X3, X4);
\r
452 #region IShowable Members
\r
457 /// <param name="stringbuilder"></param>
\r
458 /// <param name="rest"></param>
\r
459 /// <param name="formatProvider"></param>
\r
460 /// <returns></returns>
\r
461 public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
\r
463 bool incomplete = true;
\r
464 stringbuilder.Append("(");
\r
468 if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
\r
470 stringbuilder.Append(", ");
\r
472 if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
\r
474 stringbuilder.Append(", ");
\r
476 if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))
\r
478 stringbuilder.Append(", ");
\r
480 if (incomplete = !Showing.Show(X4, stringbuilder, ref rest, formatProvider))
\r
487 stringbuilder.Append("...");
\r
490 stringbuilder.Append(")");
\r
496 #region IFormattable Members
\r
501 /// <param name="format"></param>
\r
502 /// <param name="formatProvider"></param>
\r
503 /// <returns></returns>
\r
504 public string ToString(string format, IFormatProvider formatProvider)
\r
506 return Showing.ShowString(this, format, formatProvider);
\r