From aae2b053005753c5b1b0121cf620f6d22226c2d8 Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Fri, 7 Oct 2011 21:55:26 -0500 Subject: [PATCH] Implement IEquatable on structs. * gdk/Gdk.metadata: suppress Color.GetHashCode(). * gdk/Point.custom: remove generated methods. * generator/StructBase.cs: Generate Equals(T), Equals(object), and GetHashCode. * generator/StructField.cs: helper property for equality testing. * gtk/TreeIter.custom: remove generated methods. --- gdk/Gdk.metadata | 1 + gdk/Point.custom | 13 ---------- generator/StructBase.cs | 51 +++++++++++++++++++++++++++++++++++++++- generator/StructField.cs | 22 ++++++++++++++++- gtk/TreeIter.custom | 19 --------------- 5 files changed, 72 insertions(+), 34 deletions(-) diff --git a/gdk/Gdk.metadata b/gdk/Gdk.metadata index c852ef28f..7b6d37a99 100644 --- a/gdk/Gdk.metadata +++ b/gdk/Gdk.metadata @@ -1,5 +1,6 @@ + true 1 1 1 diff --git a/gdk/Point.custom b/gdk/Point.custom index 29fbd28a6..7e17cd949 100644 --- a/gdk/Point.custom +++ b/gdk/Point.custom @@ -43,19 +43,6 @@ public Point (Size sz) this.Y = sz.Height; } -public override bool Equals (object o) -{ - if (!(o is Point)) - return false; - - return (this == (Point) o); -} - -public override int GetHashCode () -{ - return X ^ Y; -} - public void Offset (int dx, int dy) { X += dx; diff --git a/generator/StructBase.cs b/generator/StructBase.cs index 217c8ca03..591a06e1a 100644 --- a/generator/StructBase.cs +++ b/generator/StructBase.cs @@ -24,6 +24,7 @@ namespace GtkSharp.Generation { using System; using System.Collections; using System.IO; + using System.Text; using System.Text.RegularExpressions; using System.Xml; @@ -106,6 +107,53 @@ namespace GtkSharp.Generation { } } + protected new void GenEqualsAndHash (StreamWriter sw) + { + int bitfields = 0; + bool need_field = true; + StringBuilder sb = new StringBuilder (); + + sw.WriteLine ("\t\tpublic bool Equals ({0} other)", Name); + sw.WriteLine ("\t\t{"); + + foreach (StructField field in fields) { + if (field.IsBitfield) { + if (need_field) { + sw.WriteLine ("\t\tif (!_bitfield{0}.Equals (other._bitfield{0})) return false;", bitfields); + if (sb.Length > 0) + sb.Append (" ^ "); + sb.Append ("_bitfield"); + sb.Append (bitfields++); + sb.Append (".GetHashCode ()"); + need_field = false; + } + } else { + need_field = true; + sw.WriteLine ("\t\t\tif (!{0}.Equals (other.{0})) return false;", field.EqualityName); + if (sb.Length > 0) + sb.Append (" ^ "); + sb.Append (field.EqualityName); + sb.Append (".GetHashCode ()"); + } + } + sw.WriteLine ("\t\t\treturn true;"); + sw.WriteLine ("\t\t}"); + sw.WriteLine (); + sw.WriteLine ("\t\tpublic override bool Equals (object other)"); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\treturn other is {0} && Equals (({0}) other);", Name); + sw.WriteLine ("\t\t}"); + sw.WriteLine (); + if (Elem.GetAttribute ("nohash") == "true") + return; + sw.WriteLine ("\t\tpublic override int GetHashCode ()"); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\treturn {0};", sb.ToString ()); + sw.WriteLine ("\t\t}"); + sw.WriteLine (); + + } + protected new void GenFields (GenerationInfo gen_info) { int bitfields = 0; @@ -160,7 +208,7 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t[Obsolete]"); sw.WriteLine ("\t[StructLayout(LayoutKind.Sequential)]"); string access = IsInternal ? "internal" : "public"; - sw.WriteLine ("\t" + access + " partial struct " + Name + " {"); + sw.WriteLine ("\t" + access + " partial struct {0} : IEquatable<{0}> {{", Name); sw.WriteLine (); need_read_native = false; @@ -170,6 +218,7 @@ namespace GtkSharp.Generation { GenMethods (gen_info, null, this); if (need_read_native) GenReadNative (sw); + GenEqualsAndHash (sw); if (!need_close) return; diff --git a/generator/StructField.cs b/generator/StructField.cs index 50389a75b..3fa6e8054 100644 --- a/generator/StructField.cs +++ b/generator/StructField.cs @@ -70,6 +70,26 @@ namespace GtkSharp.Generation { } } + public string EqualityName { + get { + SymbolTable table = SymbolTable.Table; + string wrapped = table.GetCSType (CType); + string wrapped_name = SymbolTable.Table.MangleName (CName); + IGeneratable gen = table [CType]; + + if (IsArray || gen is IAccessor) + return StudlyName; + else if (IsBitfield) + return Name; + else if (IsPointer && (gen is StructGen || gen is BoxedGen)) + return Access != "private" ? wrapped_name : Name; + else if (IsPointer && CSType != "string") + return Name; + else + return Access == "public" ? StudlyName : Name; + } + } + bool IsPadding { get { return (CName.StartsWith ("dummy") || CName.StartsWith ("padding")); @@ -93,7 +113,7 @@ namespace GtkSharp.Generation { } } - string StudlyName { + public string StudlyName { get { string studly = base.Name; if (studly == "") diff --git a/gtk/TreeIter.custom b/gtk/TreeIter.custom index 2ddfabe42..3a7e9accc 100644 --- a/gtk/TreeIter.custom +++ b/gtk/TreeIter.custom @@ -16,25 +16,6 @@ // Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. - public override int GetHashCode () - { - return Stamp ^ (int) _user_data ^ (int) _user_data2 ^ (int) _user_data3; - } - - public override bool Equals (object o) - { - if (o == null) - return false; - - if (!(o is TreeIter)) - return false; - TreeIter ti = (TreeIter) o; - return ti.Stamp == Stamp && - ti._user_data == _user_data && - ti._user_data2 == _user_data2 && - ti._user_data3 == _user_data3; - } - public IntPtr UserData { get { return _user_data;