using System; using System.Diagnostics; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Runtime.Serialization; using glue.Extensions.String; namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// This is an immutable value type which indicates a node position within the shared TFS pools. Such edges are /// themselves typically stored in the pools, but this is not a requirement. As the edge is not aware of its owning /// pool, there is no ability to change the Type or Mark on this edge itself in a way that is persistent in the /// pools. For this, the ConstraintRef object is used. /// </summary> /// <remarks> /// This file generally contains functionality related to a single Edge in isolation. Functions which treat edges as /// participants in feature structure instances, though currently members of this same class, are generally located /// in pool-edge-tfs.cs /// </remarks> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerDisplay("{ToString(),nq}")] public partial struct Edge : IEquatable<Edge> { public const Int32 MarkBare = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Edge consists of only two fields: /// 1. FlagsId (32-bits) /// 2. Mark (32-bits) /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerDisplay("{Edge._FlagsReport(this.FlagsId, true),nq}")] readonly public Flag FlagsId; [DebuggerDisplay("{Edge.FormatMark(this),nq}")] readonly public Int32 Mark; public static Edge PrunedEdge = new Edge(Edge.Flag.PrunedDuringParsing, MarkBare); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Regarding the FlagsId field: /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [Flags] [DebuggerDisplay("{Edge._FlagsReport(this, true),nq}")] public enum Flag : uint { Coreference = 0x80000000, PrunedDuringParsing = 0x40000000, /// mutually exclusive edge type modes: EtmMask = 0x30000000, EtmConfigMapped = 0x30000000, EtmString = 0x20000000, EtmNonBareType = 0x10000000, LowestFlagValue = EtmNonBareType, //Readonly = 0x08000000, //FlagMask = 0xFF000000, CachedBottom = 0xFFFFFFFF }; [DebuggerBrowsable(DebuggerBrowsableState.Never)] public bool IsCoreferenced { get { return (FlagsId & Flag.Coreference) != 0; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public bool IsConstrained { get { return Mark != MarkBare; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// C O N S T R U C T O R /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public Edge(Flag force_flagsid, int force_mark) { this.FlagsId = force_flagsid; this.Mark = force_mark; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Edges can be compared for equality, hashed, and (explicitly) cast to and from UInt64 /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public bool Equals(Edge other) { return Mark == other.Mark && FlagsId == other.FlagsId; } public static bool operator ==(Edge x, Edge y) { throw new NotImplementedException(); } public static bool operator !=(Edge x, Edge y) { throw new NotImplementedException(); } public override bool Equals(object obj) { throw new NotImplementedException("--> use strongly typed IEquatable<T> instead"); } public override int GetHashCode() { return Mark + (int)FlagsId; } public static explicit operator UInt64(Edge e) { return ((UInt64)e.FlagsId << 32) | (uint)e.Mark; } public static explicit operator Edge(UInt64 ui64) { return new Edge((Flag)(UInt32)(ui64 >> 32), (Int32)ui64); } }; }