Implement IEquatable<T> 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.
This commit is contained in:
Mike Kestner 2011-10-07 21:55:26 -05:00
parent 9d448f4eab
commit aae2b05300
5 changed files with 72 additions and 34 deletions

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<metadata> <metadata>
<attr path="/api/namespace/boxed[@cname='GdkColor']" name="nohash">true</attr>
<attr path="/api/namespace/boxed[@cname='GdkColor']/method[@name='Copy']" name="hidden">1</attr> <attr path="/api/namespace/boxed[@cname='GdkColor']/method[@name='Copy']" name="hidden">1</attr>
<attr path="/api/namespace/boxed[@cname='GdkColor']/method[@name='Free']" name="hidden">1</attr> <attr path="/api/namespace/boxed[@cname='GdkColor']/method[@name='Free']" name="hidden">1</attr>
<attr path="/api/namespace/boxed[@cname='GdkColor']/method[@name='Hash']" name="hidden">1</attr> <attr path="/api/namespace/boxed[@cname='GdkColor']/method[@name='Hash']" name="hidden">1</attr>

View file

@ -43,19 +43,6 @@ public Point (Size sz)
this.Y = sz.Height; 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) public void Offset (int dx, int dy)
{ {
X += dx; X += dx;

View file

@ -24,6 +24,7 @@ namespace GtkSharp.Generation {
using System; using System;
using System.Collections; using System.Collections;
using System.IO; using System.IO;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Xml; 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) protected new void GenFields (GenerationInfo gen_info)
{ {
int bitfields = 0; int bitfields = 0;
@ -160,7 +208,7 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\t[Obsolete]"); sw.WriteLine ("\t[Obsolete]");
sw.WriteLine ("\t[StructLayout(LayoutKind.Sequential)]"); sw.WriteLine ("\t[StructLayout(LayoutKind.Sequential)]");
string access = IsInternal ? "internal" : "public"; string access = IsInternal ? "internal" : "public";
sw.WriteLine ("\t" + access + " partial struct " + Name + " {"); sw.WriteLine ("\t" + access + " partial struct {0} : IEquatable<{0}> {{", Name);
sw.WriteLine (); sw.WriteLine ();
need_read_native = false; need_read_native = false;
@ -170,6 +218,7 @@ namespace GtkSharp.Generation {
GenMethods (gen_info, null, this); GenMethods (gen_info, null, this);
if (need_read_native) if (need_read_native)
GenReadNative (sw); GenReadNative (sw);
GenEqualsAndHash (sw);
if (!need_close) if (!need_close)
return; return;

View file

@ -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 { bool IsPadding {
get { get {
return (CName.StartsWith ("dummy") || CName.StartsWith ("padding")); return (CName.StartsWith ("dummy") || CName.StartsWith ("padding"));
@ -93,7 +113,7 @@ namespace GtkSharp.Generation {
} }
} }
string StudlyName { public string StudlyName {
get { get {
string studly = base.Name; string studly = base.Name;
if (studly == "") if (studly == "")

View file

@ -16,25 +16,6 @@
// Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA. // 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 { public IntPtr UserData {
get { get {
return _user_data; return _user_data;