Click here to Skip to main content
15,896,118 members
Articles / Programming Languages / C#

Set Collections for C#

Rate me:
Please Sign up or sign in to vote.
4.85/5 (18 votes)
3 Feb 2008CPOL10 min read 115.2K   642   54  
Describes a library of set collections I have written
// Copyright � Keith Barrett 2008.

using System;
using System.Collections.Generic;
using System.Text;
using Iesi.Collections;
using System.Collections;

namespace KMB.Library.Collections
{
    /// <summary>
    /// A value type for small sets of integers.  
    /// It uses the bits of a 16 bit integer to record membership.
    /// </summary>
    public struct SetOfInts16 : ISet
    {
        private short _bits;

        public SetOfInts16(short val)
        {
            _bits = val;
        }
        
        /// <summary>
        /// Copy constructor.
        /// </summary>
        public SetOfInts16(SetOfInts16 that)
        {
            _bits = that._bits;
        }

        #region ISet Members

        public ISet Union(ISet a)
        {
            if (a is SetOfInts16)
                return Union((SetOfInts16)a);
            else
                return new UnionSet(this, a);
        }

        public SetOfInts16 Union(SetOfInts16 a)
        {
            short newBits = (short)(this._bits | a._bits);
            return new SetOfInts16(newBits);
        }

        public ISet Intersect(ISet a)
        {
            if (a is SetOfInts16)
                return Intersect((SetOfInts16)a);
            else
                return new IntersectSet(this, a);
        }

        public SetOfInts16 Intersect(SetOfInts16 a)
        {
            short newBits = (short)(this._bits & a._bits);
            return new SetOfInts16(newBits);
        }

        public ISet Minus(ISet a)
        {
            if (a is SetOfInts16)
                return Minus((SetOfInts16)a);
            else
                return new MinusSet(this, a);
        }

        public SetOfInts16 Minus(SetOfInts16 a)
        {
            short newBits = (short)(this._bits & ~a._bits);
            return new SetOfInts16(newBits);
        }

        public ISet ExclusiveOr(ISet a)
        {
            if (a is SetOfInts16)
                return ExclusiveOr((SetOfInts16)a);
            else
                return new ExclusiveOrSet(this, a);
        }

        public SetOfInts16 ExclusiveOr(SetOfInts16 a)
        {
            short newBits = (short)(this._bits ^ a._bits);
            return new SetOfInts16(newBits);
        }

        public bool Contains(int i)
        {
            if (i < 0 || i > 15)
                return false;
            int x = (_bits & (1 << i));
            return (x != 0);
        }

        public bool Contains(object o)
        {
            if (o == null)
                return false;
            try
            {
                int i = (int)o;
                return Contains(i);
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool Set(int i, bool val)
        {
            if (i < 0 || i > 15)
               throw new Exception("range error");

            bool bOldVal = Contains(i);

            if( val )
                _bits |= (short)(1 << i);
            else
                _bits &= (short) ~(1 << i);

            return (bOldVal != val);
        }

        public void SetRange(int first, int last, bool val)
        {
            for (int i = first; i <= last; i++)
                Set(i, val);
        }

        public bool Add(int i)
        {
            return Set(i, true);
        }

        public bool Add(object o)
        {
            if (o == null)
                return false;
            try
            {
                int i = (int)o;
                return Add(i);
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool Remove(int i)
        {
            if (i < 0 || i >= 16)
                return false;
            else
                return Set(i, false);
        }

        public bool Remove(object o)
        {
            if (o == null)
                return false;
            try
            {
                int i = (int)o;
                return Remove(i);
            }
            catch (Exception)
            {
                return false;
            }
        }

        public void Clear()
        {
            _bits = 0;
        }

        #endregion

        #region ICollection Members

        int GetCount()
        {
            int total = 0;
            for (int i = 0; i < 16; i++)
            {
                if (Contains(i))
                    total++;
            }
            return total;
        }

        #endregion

        #region IEnumerable Members

        public System.Collections.IEnumerator GetEnumerator()
        {
            for(int i=0; i < 16; i++)
            {
                if( Contains(i) )
                    yield return i;
            }
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            return new SetOfInts16(this);
        }

        // How can I make this belong to the class type, 
        // so that set1.GetType().GetElementType() works?
        public Type GetElementType()
        {
            return typeof(int);
        }
        #endregion

        #region ISet Members


        public bool ContainsAll(ICollection c)
        {
            return Sets.ContainsAll(this, c);
        }

        public bool IsEmpty
        {
            get { return (_bits == 0); }
        }

        public bool AddAll(ICollection c)
        {
            foreach (object o in c)
            {
                if (!this.Add(o))
                    return false;
            }
            return true;
        }

        public bool RemoveAll(ICollection c)
        {
            foreach (object o in c)
            {
                if (!this.Remove(o))
                    return false;
            }
            return true;
        }

        public bool RetainAll(ICollection c)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region ICollection Members

        public void CopyTo(Array array, int index)
        {
            Sets.CopyTo(this, array, index);
        }

        public int Count
        {
            get { return GetCount(); }
        }

        public bool IsSynchronized
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        public object SyncRoot
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        #endregion

        public override bool Equals(object o)
        {
            if (o == null)
                return false;
            if (o is SetOfInts16)
                return Equals((SetOfInts16)o);
            return false;
        }

        public bool Equals(SetOfInts16 that)
        {
            return (_bits == that._bits);
        }

        public override int GetHashCode()
        {
            return _bits.GetHashCode();
        }

        public override string ToString()
        {
            return Sets.ToString(this);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Imagine Communications
United Kingdom United Kingdom
I have been working in IT since 1975, in various roles from junior programmer to system architect, and with many different languages and platforms. I have written shedloads of code.

I now live in Bedfordshire, England. As well as working full time I am the primary carer for my wife who has MS. I am learning to play the piano. I have three grown up children and a cat.

Comments and Discussions