# region Heading /**************************************************************************************************************/ /* */ /* Set.cs */ /* */ /* Implements a Set class */ /* */ /* This is free code, use it as you require. It was a good learning exercise for me and I hope it will be */ /* for you too. If you modify it please use your own namespace. */ /* */ /* If you like it or have suggestions for improvements please let me know at: PIEBALDconsult@aol.com */ /* */ /* Modification history: */ /* 2005-07-05 Sir John E. Boucher Created */ /* 2006-11-12 Sir John E. Boucher Fixed some problems, made generic, and added comments */ /* 2006-11-13 Sir John E. Boucher Pretty much a complete rewrite */ /* 2006-11-15 Sir John E. Boucher Reworked again to add ability to specify the Comparer */ /* and ability to specify parameters for ToString() */ /* */ /**************************************************************************************************************/ # endregion // # define Explicit // # define ThrowOnNull namespace BrazilTimestampReconstruction { /** Represents a Set. */ public partial class Set : System.Collections.IEnumerable { private System.Collections.Generic.Dictionary elements = new System.Collections.Generic.Dictionary() ; # region Constructor /** Constructs and populates a Set. (Optional) Items to add to the new Set. */ public Set ( params object[] Items ) { Add ( Items ) ; } # endregion # region Properties /** The number of elements in the Set. */ public virtual int Cardinality { get { return ( this.elements.Count ) ; } } /** The System.Collections.Generic.IEqualityComparer to use */ public virtual System.Collections.Generic.IEqualityComparer EqualityComparer { get { return ( this.elements.Comparer ) ; } set { if ( value != EqualityComparer ) { System.Collections.IEnumerable temp = this.elements.Keys ; this.elements = new System.Collections.Generic.Dictionary ( value ) ; this.Add ( temp ) ; } } } # endregion # region Conversions /** Converts an item to a Set */ # if Explicit public static explicit operator Set # else public static implicit operator Set # endif ( T Item ) { return ( new Set ( Item ) ) ; } /** Converts an array of items to a Set */ # if Explicit public static explicit operator Set # else public static implicit operator Set # endif ( T[] Items ) { return ( new Set ( Items ) ) ; } /** Converts an array of items to a Set */ # if Explicit public static explicit operator Set # else public static implicit operator Set # endif ( System.Array Items ) { return ( new Set ( Items ) ) ; } /** Converts a Collection of items to a Set */ # if Explicit public static explicit operator Set # else public static implicit operator Set # endif ( System.Collections.CollectionBase Items ) { return ( new Set ( Items ) ) ; } /** Converts an ArrayList of items to a Set */ # if Explicit public static explicit operator Set # else public static implicit operator Set # endif ( System.Collections.ArrayList Items ) { return ( new Set ( Items ) ) ; } # endregion # region Mathematical Operators /** Union of the two Sets; Set of items that are elements of at least one of the Sets. */ public static Set operator + ( Set lhs , Set rhs ) { return ( new Set ( lhs , rhs ) ) ; } /** Relative complement; items that are elements of the first Set, but not Elements of the second Set. */ public static Set operator - ( Set lhs , Set rhs ) { Set result = new Set() ; foreach ( T t in lhs ) { if ( !rhs.Contains ( t ) ) { result.Add ( t ) ; } } return ( result ) ; } /** Union of the two Sets; items that are elements of at least one of the Sets. */ public static Set operator | ( Set lhs , Set rhs ) { return ( lhs + rhs ) ; } /** Intersection of the two Sets; items that are elements of both of the Sets. */ public static Set operator & ( Set lhs , Set rhs ) { Set result = new Set() ; foreach ( T t in lhs ) { if ( rhs.Contains ( t ) ) { result.Add ( t ) ; } } return ( result ) ; } /** Exclusive Or of the two Sets; items that are elements of only one of the Sets. */ public static Set operator ^ ( Set lhs , Set rhs ) { Set result = new Set() ; foreach ( T t in lhs + rhs ) { if ( !lhs.Contains ( t ) || !rhs.Contains ( t ) ) { result.Add ( t ) ; } } return ( result ) ; } # endregion # region Comparison Operators /** Test equality of Sets; True if both Sets have the same elements */ public static bool operator == ( Set lhs , Set rhs ) { return ( ( lhs.Cardinality == rhs.Cardinality ) && ( lhs.Contains ( rhs ) ) ) ; } /** Test inequality of Sets; True if the Sets do not have the same elements */ public static bool operator != ( Set lhs , Set rhs ) { return ( !( lhs == rhs ) ) ; } /** Subset; true if the first Set is a subset of (but is not equal to) the second */ public static bool operator < ( Set lhs , Set rhs ) { return ( ( lhs.Cardinality < rhs.Cardinality ) && ( rhs.Contains ( lhs ) ) ); } /** Superset; true if the first Set is a superset of (but is not equal to) the second */ public static bool operator > ( Set lhs , Set rhs ) { return ( rhs < lhs ) ; } /** Subset; true if the first Set is a subset of the second */ public static bool operator <= ( Set lhs , Set rhs ) { return ( ( lhs.Cardinality <= rhs.Cardinality ) && ( rhs.Contains ( lhs ) ) ); } /** Superset; true if the first Set is a superset of the second */ public static bool operator >= ( Set lhs , Set rhs ) { return ( rhs <= lhs ) ; } # endregion # region Overrides /** Enumerator for the elements of the Set */ public virtual System.Collections.IEnumerator GetEnumerator ( ) { return ( this.elements.Keys.GetEnumerator() ) ; } /** Yada yada yada */ public override bool Equals ( object rhs ) { return ((rhs.GetType() == typeof(Set)) && (this == (Set)rhs)); } /** Yada yada yada */ public override int GetHashCode ( ) { return ( this.elements.GetHashCode() ) ; } # endregion # region Operations /** Attempts to add Items to the Set */ public virtual Set Add ( params object[] Items ) { foreach ( object i in Items ) { if ( i is T ) { if ( !this.elements.ContainsKey ( (T) i ) ) { this.elements.Add ( (T) i , null ) ; } } else { if ( i is System.Collections.IEnumerable ) { foreach ( object o in (System.Collections.IEnumerable) i ) { Add ( o ) ; } } else { if ( i == null ) { /* If ThrowOnNull is defined, nulls in the data will cause an exception to be thrown, otherwise they are ignored */ # if ThrowOnNull throw ( new System.NullReferenceException ( "The Set may not contain null" ) ) ; # endif } else { throw ( new System.InvalidOperationException ( i.ToString() + " is not a " + typeof(T).ToString() ) ) ; } } } } return ( this ) ; } /** Attempts to remove Items from the Set */ public virtual Set Remove ( params object[] Items ) { foreach ( object i in Items ) { if ( i is T ) { this.elements.Remove ( (T) i ) ; } else { if ( i is System.Collections.IEnumerable ) { foreach ( object o in (System.Collections.IEnumerable) i ) { Remove ( o ) ; } } } } return ( this ) ; } /** Returns true if the Set contains the Item(s) */ public virtual bool Contains ( params object[] Items ) { bool result = true ; foreach ( object i in Items ) { if ( i is T ) { if ( !this.elements.ContainsKey ( (T) i ) ) { result = false ; break ; } } else { if ( i is System.Collections.IEnumerable ) { foreach ( object o in (System.Collections.IEnumerable) i ) { if ( !Contains ( o ) ) { result = false ; break ; } } } } } return ( result ) ; } /** Removes all elements from the Set */ public virtual Set Clear ( ) { this.elements.Clear() ; return ( this ) ; } # endregion } }