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:
10 The above copyright notice and this permission notice shall be included in
11 all copies or substantial portions of the Software.
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
24 using System.Reflection;
25 using System.Reflection.Emit;
26 using System.Diagnostics;
32 public const int HASHFACTOR = 387281;
35 /// A generic record type with two fields.
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"/>).
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"/>.
45 /// <typeparam name="T1"></typeparam>
46 /// <typeparam name="T2"></typeparam>
47 public struct Rec<T1, T2> : IEquatable<Rec<T1, T2>>, IShowable
52 public readonly T1 X1;
56 public readonly T2 X2;
61 /// <param name="x1"></param>
62 /// <param name="x2"></param>
64 public Rec(T1 x1, T2 x2)
66 this.X1 = x1; this.X2 = x2;
72 /// <param name="other"></param>
73 /// <returns></returns>
75 public bool Equals(Rec<T1, T2> other)
78 (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
79 (X2 == null ? other.X2 == null : X2.Equals(other.X2))
85 /// <param name="obj"></param>
86 /// <returns></returns>
88 public override bool Equals(object obj)
90 return obj is Rec<T1, T2> ? Equals((Rec<T1, T2>)obj) : false;
95 /// <param name="record1"></param>
96 /// <param name="record2"></param>
97 /// <returns></returns>
99 public static bool operator ==(Rec<T1, T2> record1, Rec<T1, T2> record2)
101 return record1.Equals(record2);
106 /// <param name="record1"></param>
107 /// <param name="record2"></param>
108 /// <returns></returns>
110 public static bool operator !=(Rec<T1, T2> record1, Rec<T1, T2> record2)
112 return !record1.Equals(record2);
117 /// <returns></returns>
119 public override int GetHashCode()
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());
130 /// <returns></returns>
131 public override string ToString()
133 return String.Format("({0}, {1})", X1, X2);
136 #region IShowable Members
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)
147 bool incomplete = true;
148 stringbuilder.Append("(");
152 if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
154 stringbuilder.Append(", ");
156 if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
163 stringbuilder.Append("...");
166 stringbuilder.Append(")");
172 #region IFormattable Members
177 /// <param name="format"></param>
178 /// <param name="formatProvider"></param>
179 /// <returns></returns>
180 public string ToString(string format, IFormatProvider formatProvider)
182 return Showing.ShowString(this, format, formatProvider);
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
198 public readonly T1 X1;
202 public readonly T2 X2;
206 public readonly T3 X3;
210 /// <param name="x1"></param>
211 /// <param name="x2"></param>
212 /// <param name="x3"></param>
214 public Rec(T1 x1, T2 x2, T3 x3)
216 this.X1 = x1; this.X2 = x2; this.X3 = x3;
221 /// <param name="other"></param>
222 /// <returns></returns>
224 public bool Equals(Rec<T1, T2, T3> other)
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))
235 /// <param name="obj"></param>
236 /// <returns></returns>
238 public override bool Equals(object obj)
240 return obj is Rec<T1, T2, T3> ? Equals((Rec<T1, T2, T3>)obj) : false;
245 /// <param name="record1"></param>
246 /// <param name="record2"></param>
247 /// <returns></returns>
249 public static bool operator ==(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)
251 return record1.Equals(record2);
256 /// <param name="record1"></param>
257 /// <param name="record2"></param>
258 /// <returns></returns>
260 public static bool operator !=(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)
262 return !record1.Equals(record2);
267 /// <returns></returns>
269 public override int GetHashCode()
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());
281 /// <returns></returns>
282 public override string ToString()
284 return String.Format("({0}, {1}, {2})", X1, X2, X3);
286 #region IShowable Members
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)
297 bool incomplete = true;
298 stringbuilder.Append("(");
302 if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
304 stringbuilder.Append(", ");
306 if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
308 stringbuilder.Append(", ");
310 if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))
317 stringbuilder.Append("...");
320 stringbuilder.Append(")");
326 #region IFormattable Members
331 /// <param name="format"></param>
332 /// <param name="formatProvider"></param>
333 /// <returns></returns>
334 public string ToString(string format, IFormatProvider formatProvider)
336 return Showing.ShowString(this, format, formatProvider);
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
354 public readonly T1 X1;
358 public readonly T2 X2;
362 public readonly T3 X3;
366 public readonly T4 X4;
370 /// <param name="x1"></param>
371 /// <param name="x2"></param>
372 /// <param name="x3"></param>
373 /// <param name="x4"></param>
375 public Rec(T1 x1, T2 x2, T3 x3, T4 x4)
377 this.X1 = x1; this.X2 = x2; this.X3 = x3; this.X4 = x4;
382 /// <param name="other"></param>
383 /// <returns></returns>
385 public bool Equals(Rec<T1, T2, T3, T4> other)
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))
397 /// <param name="obj"></param>
398 /// <returns></returns>
400 public override bool Equals(object obj)
402 return obj is Rec<T1, T2, T3, T4> ? Equals((Rec<T1, T2, T3, T4>)obj) : false;
408 /// <param name="record1"></param>
409 /// <param name="record2"></param>
410 /// <returns></returns>
412 public static bool operator ==(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)
414 return record1.Equals(record2);
419 /// <param name="record1"></param>
420 /// <param name="record2"></param>
421 /// <returns></returns>
423 public static bool operator !=(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)
425 return !record1.Equals(record2);
431 /// <returns></returns>
433 public override int GetHashCode()
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());
446 /// <returns></returns>
447 public override string ToString()
449 return String.Format("({0}, {1}, {2}, {3})", X1, X2, X3, X4);
451 #region IShowable Members
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)
462 bool incomplete = true;
463 stringbuilder.Append("(");
467 if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
469 stringbuilder.Append(", ");
471 if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
473 stringbuilder.Append(", ");
475 if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))
477 stringbuilder.Append(", ");
479 if (incomplete = !Showing.Show(X4, stringbuilder, ref rest, formatProvider))
486 stringbuilder.Append("...");
489 stringbuilder.Append(")");
495 #region IFormattable Members
500 /// <param name="format"></param>
501 /// <param name="formatProvider"></param>
502 /// <returns></returns>
503 public string ToString(string format, IFormatProvider formatProvider)
505 return Showing.ShowString(this, format, formatProvider);