//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using Microsoft.Contracts;
namespace Microsoft.AbstractInterpretationFramework.Collections
{
using System.Collections;
/// Represents a functional collection of key/value pairs.
/// 2
public interface IFunctionalMap : System.Collections.ICollection, System.Collections.IEnumerable
{
/// Adds an element with the provided key and value to the .
/// The to use as the value of the element to add.
/// The to use as the key of the element to add.
/// 2
IFunctionalMap! Add(object! key, object value);
///
/// Set the value of the key (that is already in the map)
///
IFunctionalMap! Set(object! key, object value);
/// Determines whether the contains an element with the specified key.
/// true if the contains an element with the key; otherwise, false.
/// The key to locate in the .
/// 2
[Pure][Reads(ReadsAttribute.Reads.Owned)]
bool Contains(object! key);
/// Returns an for the .
/// An for the .
/// 2
[Pure] [GlobalAccess(false)] [Escapes(true,false)]
new System.Collections.IDictionaryEnumerator GetEnumerator();
/// Gets an containing the keys of the .
/// An containing the keys of the .
/// 2
System.Collections.ICollection Keys { get; }
/// Removes the element with the specified key from the .
/// The key of the element to remove.
/// 2
IFunctionalMap! Remove(object! key);
/// Gets an containing the values in the .
/// An containing the values in the .
/// 2
System.Collections.ICollection Values { get; }
object this [object! key] { get; /*set;*/ }
}
///
/// An implementation of the
///
/// interface with a as the backing store.
///
class FunctionalHashtable : IFunctionalMap
{
private readonly Hashtable! h;
///
/// Cannot directly construct an instance of a FunctionalHashtbl.
///
private FunctionalHashtable()
{
this.h = new Hashtable();
// base();
}
///
/// Cannot directly construct an instance of a FunctionalHashtbl.
///
private FunctionalHashtable(Hashtable! h)
{
this.h = h;
// base();
}
private static readonly IFunctionalMap! empty = new FunctionalHashtable();
public static IFunctionalMap! Empty { get { return empty; } }
public IFunctionalMap! Add(object! key, object value)
{
Hashtable r = h.Clone() as Hashtable;
assume r != null;
r.Add(key, value);
return new FunctionalHashtable(r);
}
public IFunctionalMap! Set(object! key, object value)
{
Hashtable r = h.Clone() as Hashtable;
assume r != null;
assert this.Contains(key); // The entry must be defined
r[key] = value;
return new FunctionalHashtable(r);
}
[Pure][Reads(ReadsAttribute.Reads.Owned)]
public bool Contains(object! key)
{
return h.Contains(key);
}
[Pure] [GlobalAccess(false)] [Escapes(true,false)]
IEnumerator! IEnumerable.GetEnumerator()
{
return h.GetEnumerator();
}
[Pure] [GlobalAccess(false)] [Escapes(true,false)]
IDictionaryEnumerator IFunctionalMap.GetEnumerator()
{
return h.GetEnumerator();
}
public ICollection Keys
{
get { return h.Keys; }
}
public IFunctionalMap! Remove(object! key)
{
Hashtable r = h.Clone() as Hashtable;
assume r != null;
r.Remove(key);
return new FunctionalHashtable(r);
}
public ICollection Values
{
get { return h.Values; }
}
public object this[object! key]
{
get { return h[key]; }
}
public int Count
{
[Pure] get { return h.Count; }
}
public bool IsSynchronized
{
[Pure] get { return h.IsSynchronized; }
}
public object! SyncRoot
{
[Pure] get { return h.SyncRoot; }
}
public void CopyTo(System.Array! a, int index)
{
h.CopyTo(a, index);
}
}
public struct Pair/**/
{
private object first;
private object second;
public object First { get { return first; } }
public object Second { get { return second; } }
public Pair(object first, object second)
{
this.first = first;
this.second = second;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (!(obj is Pair)) return false;
Pair other = (Pair)obj;
return object.Equals(this.first, other.first) && object.Equals(this.second, other.second);
}
public override int GetHashCode()
{
int h = this.first == null ? 0 : this.first.GetHashCode();
h ^= this.second == null ? 0 : this.second.GetHashCode();
return h;
}
}
}
namespace Microsoft.AbstractInterpretationFramework.Collections.Generic
{
using System.Collections.Generic;
public struct Pair
{
private T1 first;
private T2 second;
public T1 First { get { return first; } }
public T2 Second { get { return second; } }
public Pair(T1 first, T2 second)
{
this.first = first;
this.second = second;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (!(obj is Pair)) return false;
Pair other = (Pair)obj;
return object.Equals(this.first, other.first) && object.Equals(this.second, other.second);
}
public override int GetHashCode()
{
int h = this.first == null ? 0 : this.first.GetHashCode();
h ^= this.second == null ? 0 : this.second.GetHashCode();
return h;
}
public override string! ToString()
{
return string.Format("({0},{1})", first, second);
}
}
public struct Triple
{
private T1 first;
private T2 second;
private T3 third;
public T1 First { get { return first; } }
public T2 Second { get { return second; } }
public T3 Third { get { return third; } }
public Triple(T1 first, T2 second, T3 third)
{
this.first = first;
this.second = second;
this.third = third;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (!(obj is Triple)) return false;
Triple other = (Triple)obj;
return object.Equals(this.first, other.first) && object.Equals(this.second, other.second) && object.Equals(this.third, other.third);
}
public override int GetHashCode()
{
int h = this.first == null ? 0 : this.first.GetHashCode();
h ^= this.second == null ? 0 : this.second.GetHashCode();
h ^= this.third == null ? 0 : this.third.GetHashCode();
return h;
}
public override string! ToString()
{
return string.Format("({0},{1},{2})", first, second, third);
}
}
}