# 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
}
}