Merge pull request #4198 from vkargov/vk-prevbb
[mono.git] / mcs / class / Mono.C5 / C5 / Records.cs
index 5eb0df18b98ae49ffa2b988f1dbcefff71b3fa98..ff30435b534ef7cd8f3ccb9564f27bc1a8f2ca9a 100644 (file)
-#if NET_2_0
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
\r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
\r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using C5;\r
-using System;\r
-using System.Reflection;\r
-using System.Reflection.Emit;\r
-using System.Diagnostics;\r
-\r
-namespace C5\r
-{\r
-  struct RecConst\r
-  {\r
-    public const int HASHFACTOR = 387281;\r
-  }\r
-  /// <summary>\r
-  /// A generic record type with two fields. \r
-  /// <para>\r
-  /// Equality is defined field by field, using the <code>Equals</code> method \r
-  /// inherited from <code>System.Object</code> (i.e. using <see cref="T:C5.NaturalEqualityComparer`1"/>).\r
-  /// </para>\r
-  /// <para>\r
-  /// This type is similar to <see cref="T:C5.KeyValuePair`2"/>, but the latter\r
-  /// uses <see cref="P:C5.EqualityComparer`1.Default"/> to define field equality instead of <see cref="T:C5.NaturalEqualityComparer`1"/>.\r
-  /// </para>\r
-  /// </summary>\r
-  /// <typeparam name="T1"></typeparam>\r
-  /// <typeparam name="T2"></typeparam>\r
-  public struct Rec<T1, T2> : IEquatable<Rec<T1, T2>>, IShowable\r
-  {\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T1 X1;\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T2 X2;\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="x1"></param>\r
-    /// <param name="x2"></param>\r
-    [Tested]\r
-    public Rec(T1 x1, T2 x2)\r
-    {\r
-      this.X1 = x1; this.X2 = x2;\r
-    }\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="other"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public bool Equals(Rec<T1, T2> other)\r
-    {\r
-      return\r
-        (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&\r
-        (X2 == null ? other.X2 == null : X2.Equals(other.X2))\r
-        ;\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="obj"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public override bool Equals(object obj)\r
-    {\r
-      return obj is Rec<T1, T2> ? Equals((Rec<T1, T2>)obj) : false;\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="record1"></param>\r
-    /// <param name="record2"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public static bool operator ==(Rec<T1, T2> record1, Rec<T1, T2> record2)\r
-    {\r
-      return record1.Equals(record2);\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="record1"></param>\r
-    /// <param name="record2"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public static bool operator !=(Rec<T1, T2> record1, Rec<T1, T2> record2)\r
-    {\r
-      return !record1.Equals(record2);\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public override int GetHashCode()\r
-    {\r
-      //TODO: don't use 0 as hashcode for null, but something else!\r
-      int hashcode = X1 == null ? 0 : X1.GetHashCode();\r
-      hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());\r
-      return hashcode;\r
-    }\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <returns></returns>\r
-    public override string ToString()\r
-    {\r
-      return String.Format("({0}, {1})", X1, X2);\r
-    }\r
-\r
-    #region IShowable Members\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="stringbuilder"></param>\r
-    /// <param name="rest"></param>\r
-    /// <param name="formatProvider"></param>\r
-    /// <returns></returns>\r
-    public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
-    {\r
-      bool incomplete = true;\r
-      stringbuilder.Append("(");\r
-      rest -= 2;\r
-      try\r
-      {\r
-        if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-        stringbuilder.Append(", ");\r
-        rest -= 2;\r
-        if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-      }\r
-      finally\r
-      {\r
-        if (incomplete)\r
-        {\r
-          stringbuilder.Append("...");\r
-          rest -= 3;\r
-        }\r
-        stringbuilder.Append(")");\r
-      }\r
-      return true;\r
-    }\r
-    #endregion\r
-\r
-    #region IFormattable Members\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="format"></param>\r
-    /// <param name="formatProvider"></param>\r
-    /// <returns></returns>\r
-    public string ToString(string format, IFormatProvider formatProvider)\r
-    {\r
-      return Showing.ShowString(this, format, formatProvider);\r
-    }\r
-\r
-    #endregion\r
-  }\r
-  /// <summary>\r
-  /// \r
-  /// </summary>\r
-  /// <typeparam name="T1"></typeparam>\r
-  /// <typeparam name="T2"></typeparam>\r
-  /// <typeparam name="T3"></typeparam>\r
-  public struct Rec<T1, T2, T3> : IEquatable<Rec<T1, T2, T3>>, IShowable\r
-  {\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T1 X1;\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T2 X2;\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T3 X3;\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="x1"></param>\r
-    /// <param name="x2"></param>\r
-    /// <param name="x3"></param>\r
-    [Tested]\r
-    public Rec(T1 x1, T2 x2, T3 x3)\r
-    {\r
-      this.X1 = x1; this.X2 = x2; this.X3 = x3;\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="other"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public bool Equals(Rec<T1, T2, T3> other)\r
-    {\r
-      return\r
-        (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&\r
-        (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&\r
-        (X3 == null ? other.X3 == null : X3.Equals(other.X3))\r
-        ;\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="obj"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public override bool Equals(object obj)\r
-    {\r
-      return obj is Rec<T1, T2, T3> ? Equals((Rec<T1, T2, T3>)obj) : false;\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="record1"></param>\r
-    /// <param name="record2"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public static bool operator ==(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)\r
-    {\r
-      return record1.Equals(record2);\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="record1"></param>\r
-    /// <param name="record2"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public static bool operator !=(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)\r
-    {\r
-      return !record1.Equals(record2);\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public override int GetHashCode()\r
-    {\r
-      //TODO: don't use 0 as hashcode for null, but something else!\r
-      int hashcode = X1 == null ? 0 : X1.GetHashCode();\r
-      hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());\r
-      hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());\r
-      return hashcode;\r
-    }\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <returns></returns>\r
-    public override string ToString()\r
-    {\r
-      return String.Format("({0}, {1}, {2})", X1, X2, X3);\r
-    }\r
-    #region IShowable Members\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="stringbuilder"></param>\r
-    /// <param name="rest"></param>\r
-    /// <param name="formatProvider"></param>\r
-    /// <returns></returns>\r
-    public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
-    {\r
-      bool incomplete = true;\r
-      stringbuilder.Append("(");\r
-      rest -= 2;\r
-      try\r
-      {\r
-        if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-        stringbuilder.Append(", ");\r
-        rest -= 2;\r
-        if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-        stringbuilder.Append(", ");\r
-        rest -= 2;\r
-        if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-      }\r
-      finally\r
-      {\r
-        if (incomplete)\r
-        {\r
-          stringbuilder.Append("...");\r
-          rest -= 3;\r
-        }\r
-        stringbuilder.Append(")");\r
-      }\r
-      return true;\r
-    }\r
-    #endregion\r
-\r
-    #region IFormattable Members\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="format"></param>\r
-    /// <param name="formatProvider"></param>\r
-    /// <returns></returns>\r
-    public string ToString(string format, IFormatProvider formatProvider)\r
-    {\r
-      return Showing.ShowString(this, format, formatProvider);\r
-    }\r
-\r
-    #endregion\r
-  }\r
-\r
-  /// <summary>\r
-  /// \r
-  /// </summary>\r
-  /// <typeparam name="T1"></typeparam>\r
-  /// <typeparam name="T2"></typeparam>\r
-  /// <typeparam name="T3"></typeparam>\r
-  /// <typeparam name="T4"></typeparam>\r
-  public struct Rec<T1, T2, T3, T4> : IEquatable<Rec<T1, T2, T3, T4>>, IShowable\r
-  {\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T1 X1;\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T2 X2;\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T3 X3;\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    public readonly T4 X4;\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="x1"></param>\r
-    /// <param name="x2"></param>\r
-    /// <param name="x3"></param>\r
-    /// <param name="x4"></param>\r
-    [Tested]\r
-    public Rec(T1 x1, T2 x2, T3 x3, T4 x4)\r
-    {\r
-      this.X1 = x1; this.X2 = x2; this.X3 = x3; this.X4 = x4;\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="other"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public bool Equals(Rec<T1, T2, T3, T4> other)\r
-    {\r
-      return\r
-        (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&\r
-        (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&\r
-        (X3 == null ? other.X3 == null : X3.Equals(other.X3)) &&\r
-        (X4 == null ? other.X4 == null : X4.Equals(other.X4))\r
-        ;\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="obj"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public override bool Equals(object obj)\r
-    {\r
-      return obj is Rec<T1, T2, T3, T4> ? Equals((Rec<T1, T2, T3, T4>)obj) : false;\r
-    }\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="record1"></param>\r
-    /// <param name="record2"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public static bool operator ==(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)\r
-    {\r
-      return record1.Equals(record2);\r
-    }\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="record1"></param>\r
-    /// <param name="record2"></param>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public static bool operator !=(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)\r
-    {\r
-      return !record1.Equals(record2);\r
-    }\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <returns></returns>\r
-    [Tested]\r
-    public override int GetHashCode()\r
-    {\r
-      //TODO: don't use 0 as hashcode for null, but something else!\r
-      int hashcode = X1 == null ? 0 : X1.GetHashCode();\r
-      hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());\r
-      hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());\r
-      hashcode = hashcode * RecConst.HASHFACTOR + (X4 == null ? 0 : X4.GetHashCode());\r
-      return hashcode;\r
-    }\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <returns></returns>\r
-    public override string ToString()\r
-    {\r
-      return String.Format("({0}, {1}, {2}, {3})", X1, X2, X3, X4);\r
-    }\r
-    #region IShowable Members\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="stringbuilder"></param>\r
-    /// <param name="rest"></param>\r
-    /// <param name="formatProvider"></param>\r
-    /// <returns></returns>\r
-    public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
-    {\r
-      bool incomplete = true;\r
-      stringbuilder.Append("(");\r
-      rest -= 2;\r
-      try\r
-      {\r
-        if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-        stringbuilder.Append(", ");\r
-        rest -= 2;\r
-        if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-        stringbuilder.Append(", ");\r
-        rest -= 2;\r
-        if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-        stringbuilder.Append(", ");\r
-        rest -= 2;\r
-        if (incomplete = !Showing.Show(X4, stringbuilder, ref rest, formatProvider))\r
-          return false;\r
-      }\r
-      finally\r
-      {\r
-        if (incomplete)\r
-        {\r
-          stringbuilder.Append("...");\r
-          rest -= 3;\r
-        }\r
-        stringbuilder.Append(")");\r
-      }\r
-      return true;\r
-    }\r
-    #endregion\r
-\r
-    #region IFormattable Members\r
-\r
-    /// <summary>\r
-    /// \r
-    /// </summary>\r
-    /// <param name="format"></param>\r
-    /// <param name="formatProvider"></param>\r
-    /// <returns></returns>\r
-    public string ToString(string format, IFormatProvider formatProvider)\r
-    {\r
-      return Showing.ShowString(this, format, formatProvider);\r
-    }\r
-\r
-    #endregion\r
-  }\r
-}\r
+/*
+ Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
 
-#endif
+using C5;
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Diagnostics;
+
+namespace C5
+{
+  struct RecConst
+  {
+    public const int HASHFACTOR = 387281;
+  }
+  /// <summary>
+  /// A generic record type with two fields. 
+  /// <para>
+  /// Equality is defined field by field, using the <code>Equals</code> method 
+  /// inherited from <code>System.Object</code> (i.e. using <see cref="T:C5.NaturalEqualityComparer`1"/>).
+  /// </para>
+  /// <para>
+  /// This type is similar to <see cref="T:C5.KeyValuePair`2"/>, but the latter
+  /// uses <see cref="P:C5.EqualityComparer`1.Default"/> to define field equality instead of <see cref="T:C5.NaturalEqualityComparer`1"/>.
+  /// </para>
+  /// </summary>
+  /// <typeparam name="T1"></typeparam>
+  /// <typeparam name="T2"></typeparam>
+  public struct Rec<T1, T2> : IEquatable<Rec<T1, T2>>, IShowable
+  {
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T1 X1;
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T2 X2;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="x1"></param>
+    /// <param name="x2"></param>
+    [Tested]
+    public Rec(T1 x1, T2 x2)
+    {
+      this.X1 = x1; this.X2 = x2;
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="other"></param>
+    /// <returns></returns>
+    [Tested]
+    public bool Equals(Rec<T1, T2> other)
+    {
+      return
+        (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
+        (X2 == null ? other.X2 == null : X2.Equals(other.X2))
+        ;
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="obj"></param>
+    /// <returns></returns>
+    [Tested]
+    public override bool Equals(object obj)
+    {
+      return obj is Rec<T1, T2> ? Equals((Rec<T1, T2>)obj) : false;
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="record1"></param>
+    /// <param name="record2"></param>
+    /// <returns></returns>
+    [Tested]
+    public static bool operator ==(Rec<T1, T2> record1, Rec<T1, T2> record2)
+    {
+      return record1.Equals(record2);
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="record1"></param>
+    /// <param name="record2"></param>
+    /// <returns></returns>
+    [Tested]
+    public static bool operator !=(Rec<T1, T2> record1, Rec<T1, T2> record2)
+    {
+      return !record1.Equals(record2);
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <returns></returns>
+    [Tested]
+    public override int GetHashCode()
+    {
+      //TODO: don't use 0 as hashcode for null, but something else!
+      int hashcode = X1 == null ? 0 : X1.GetHashCode();
+      hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
+      return hashcode;
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <returns></returns>
+    public override string ToString()
+    {
+      return String.Format("({0}, {1})", X1, X2);
+    }
+
+    #region IShowable Members
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="stringbuilder"></param>
+    /// <param name="rest"></param>
+    /// <param name="formatProvider"></param>
+    /// <returns></returns>
+    public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
+    {
+      bool incomplete = true;
+      stringbuilder.Append("(");
+      rest -= 2;
+      try
+      {
+        if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
+          return false;
+        stringbuilder.Append(", ");
+        rest -= 2;
+        if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
+          return false;
+      }
+      finally
+      {
+        if (incomplete)
+        {
+          stringbuilder.Append("...");
+          rest -= 3;
+        }
+        stringbuilder.Append(")");
+      }
+      return true;
+    }
+    #endregion
+
+    #region IFormattable Members
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="format"></param>
+    /// <param name="formatProvider"></param>
+    /// <returns></returns>
+    public string ToString(string format, IFormatProvider formatProvider)
+    {
+      return Showing.ShowString(this, format, formatProvider);
+    }
+
+    #endregion
+  }
+  /// <summary>
+  /// 
+  /// </summary>
+  /// <typeparam name="T1"></typeparam>
+  /// <typeparam name="T2"></typeparam>
+  /// <typeparam name="T3"></typeparam>
+  public struct Rec<T1, T2, T3> : IEquatable<Rec<T1, T2, T3>>, IShowable
+  {
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T1 X1;
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T2 X2;
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T3 X3;
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="x1"></param>
+    /// <param name="x2"></param>
+    /// <param name="x3"></param>
+    [Tested]
+    public Rec(T1 x1, T2 x2, T3 x3)
+    {
+      this.X1 = x1; this.X2 = x2; this.X3 = x3;
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="other"></param>
+    /// <returns></returns>
+    [Tested]
+    public bool Equals(Rec<T1, T2, T3> other)
+    {
+      return
+        (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
+        (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&
+        (X3 == null ? other.X3 == null : X3.Equals(other.X3))
+        ;
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="obj"></param>
+    /// <returns></returns>
+    [Tested]
+    public override bool Equals(object obj)
+    {
+      return obj is Rec<T1, T2, T3> ? Equals((Rec<T1, T2, T3>)obj) : false;
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="record1"></param>
+    /// <param name="record2"></param>
+    /// <returns></returns>
+    [Tested]
+    public static bool operator ==(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)
+    {
+      return record1.Equals(record2);
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="record1"></param>
+    /// <param name="record2"></param>
+    /// <returns></returns>
+    [Tested]
+    public static bool operator !=(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)
+    {
+      return !record1.Equals(record2);
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <returns></returns>
+    [Tested]
+    public override int GetHashCode()
+    {
+      //TODO: don't use 0 as hashcode for null, but something else!
+      int hashcode = X1 == null ? 0 : X1.GetHashCode();
+      hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
+      hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());
+      return hashcode;
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <returns></returns>
+    public override string ToString()
+    {
+      return String.Format("({0}, {1}, {2})", X1, X2, X3);
+    }
+    #region IShowable Members
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="stringbuilder"></param>
+    /// <param name="rest"></param>
+    /// <param name="formatProvider"></param>
+    /// <returns></returns>
+    public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
+    {
+      bool incomplete = true;
+      stringbuilder.Append("(");
+      rest -= 2;
+      try
+      {
+        if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
+          return false;
+        stringbuilder.Append(", ");
+        rest -= 2;
+        if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
+          return false;
+        stringbuilder.Append(", ");
+        rest -= 2;
+        if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))
+          return false;
+      }
+      finally
+      {
+        if (incomplete)
+        {
+          stringbuilder.Append("...");
+          rest -= 3;
+        }
+        stringbuilder.Append(")");
+      }
+      return true;
+    }
+    #endregion
+
+    #region IFormattable Members
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="format"></param>
+    /// <param name="formatProvider"></param>
+    /// <returns></returns>
+    public string ToString(string format, IFormatProvider formatProvider)
+    {
+      return Showing.ShowString(this, format, formatProvider);
+    }
+
+    #endregion
+  }
+
+  /// <summary>
+  /// 
+  /// </summary>
+  /// <typeparam name="T1"></typeparam>
+  /// <typeparam name="T2"></typeparam>
+  /// <typeparam name="T3"></typeparam>
+  /// <typeparam name="T4"></typeparam>
+  public struct Rec<T1, T2, T3, T4> : IEquatable<Rec<T1, T2, T3, T4>>, IShowable
+  {
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T1 X1;
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T2 X2;
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T3 X3;
+    /// <summary>
+    /// 
+    /// </summary>
+    public readonly T4 X4;
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="x1"></param>
+    /// <param name="x2"></param>
+    /// <param name="x3"></param>
+    /// <param name="x4"></param>
+    [Tested]
+    public Rec(T1 x1, T2 x2, T3 x3, T4 x4)
+    {
+      this.X1 = x1; this.X2 = x2; this.X3 = x3; this.X4 = x4;
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="other"></param>
+    /// <returns></returns>
+    [Tested]
+    public bool Equals(Rec<T1, T2, T3, T4> other)
+    {
+      return
+        (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&
+        (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&
+        (X3 == null ? other.X3 == null : X3.Equals(other.X3)) &&
+        (X4 == null ? other.X4 == null : X4.Equals(other.X4))
+        ;
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="obj"></param>
+    /// <returns></returns>
+    [Tested]
+    public override bool Equals(object obj)
+    {
+      return obj is Rec<T1, T2, T3, T4> ? Equals((Rec<T1, T2, T3, T4>)obj) : false;
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="record1"></param>
+    /// <param name="record2"></param>
+    /// <returns></returns>
+    [Tested]
+    public static bool operator ==(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)
+    {
+      return record1.Equals(record2);
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="record1"></param>
+    /// <param name="record2"></param>
+    /// <returns></returns>
+    [Tested]
+    public static bool operator !=(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)
+    {
+      return !record1.Equals(record2);
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <returns></returns>
+    [Tested]
+    public override int GetHashCode()
+    {
+      //TODO: don't use 0 as hashcode for null, but something else!
+      int hashcode = X1 == null ? 0 : X1.GetHashCode();
+      hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());
+      hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());
+      hashcode = hashcode * RecConst.HASHFACTOR + (X4 == null ? 0 : X4.GetHashCode());
+      return hashcode;
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <returns></returns>
+    public override string ToString()
+    {
+      return String.Format("({0}, {1}, {2}, {3})", X1, X2, X3, X4);
+    }
+    #region IShowable Members
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="stringbuilder"></param>
+    /// <param name="rest"></param>
+    /// <param name="formatProvider"></param>
+    /// <returns></returns>
+    public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
+    {
+      bool incomplete = true;
+      stringbuilder.Append("(");
+      rest -= 2;
+      try
+      {
+        if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))
+          return false;
+        stringbuilder.Append(", ");
+        rest -= 2;
+        if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))
+          return false;
+        stringbuilder.Append(", ");
+        rest -= 2;
+        if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))
+          return false;
+        stringbuilder.Append(", ");
+        rest -= 2;
+        if (incomplete = !Showing.Show(X4, stringbuilder, ref rest, formatProvider))
+          return false;
+      }
+      finally
+      {
+        if (incomplete)
+        {
+          stringbuilder.Append("...");
+          rest -= 3;
+        }
+        stringbuilder.Append(")");
+      }
+      return true;
+    }
+    #endregion
+
+    #region IFormattable Members
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="format"></param>
+    /// <param name="formatProvider"></param>
+    /// <returns></returns>
+    public string ToString(string format, IFormatProvider formatProvider)
+    {
+      return Showing.ShowString(this, format, formatProvider);
+    }
+
+    #endregion
+  }
+}