Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[mono.git] / mcs / class / Mono.CodeContracts / Mono.CodeContracts.Static.DataStructures / ImmutableSet.cs
1 // 
2 // ImmutableSet.cs
3 // 
4 // Authors:
5 //      Alexander Chebaturkin (chebaturkin@gmail.com)
6 // 
7 // Copyright (C) 2011 Alexander Chebaturkin
8 // 
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //  
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 // 
28
29 using System;
30 using System.Collections.Generic;
31 using System.IO;
32
33 namespace Mono.CodeContracts.Static.DataStructures {
34         class ImmutableSet<T> : IImmutableSet<T>
35                 where T : IEquatable<T> {
36                 private readonly IImmutableMap<T, Dummy> underlying;
37
38                 public ImmutableSet (IImmutableMap<T, Dummy> immutableMap)
39                 {
40                         this.underlying = immutableMap;
41                 }
42
43                 #region Implementation of IImmutableSet<T>
44                 public T Any
45                 {
46                         get { return this.underlying.AnyKey; }
47                 }
48
49                 public int Count
50                 {
51                         get { return this.underlying.Count; }
52                 }
53
54                 public IEnumerable<T> Elements
55                 {
56                         get { return this.underlying.Keys; }
57                 }
58
59                 public IImmutableSet<T> Add (T item)
60                 {
61                         return new ImmutableSet<T> (this.underlying.Add (item, Dummy.Value));
62                 }
63
64                 public IImmutableSet<T> Remove (T item)
65                 {
66                         return new ImmutableSet<T> (this.underlying.Remove (item));
67                 }
68
69                 public bool Contains (T item)
70                 {
71                         return this.underlying.ContainsKey (item);
72                 }
73
74                 public bool IsContainedIn (IImmutableSet<T> that)
75                 {
76                         if (Count > that.Count)
77                                 return false;
78                         bool result = true;
79                         this.underlying.Visit ((e, dummy) => {
80                                                 if (that.Contains (e))
81                                                         return VisitStatus.ContinueVisit;
82
83                                                 result = false;
84                                                 return VisitStatus.StopVisit;
85                                                });
86                         return result;
87                 }
88
89                 public IImmutableSet<T> Intersect (IImmutableSet<T> that)
90                 {
91                         if (this == that)
92                                 return this;
93                         if (Count == 0)
94                                 return this;
95                         IImmutableSet<T> set;
96                         IImmutableSet<T> larger;
97                         if (Count < that.Count) {
98                                 set = this;
99                                 larger = that;
100                         } else {
101                                 if (that.Count == 0)
102                                         return that;
103                                 set = that;
104                                 larger = this;
105                         }
106                         IImmutableSet<T> result = set;
107                         set.Visit ((e) => {
108                                         if (!larger.Contains (e))
109                                                 result = result.Remove (e);
110                                    });
111                         return result;
112                 }
113
114                 public IImmutableSet<T> Union (IImmutableSet<T> that)
115                 {
116                         if (this == that)
117                                 return this;
118                         if (Count == 0)
119                                 return that;
120                         IImmutableSet<T> smaller;
121                         IImmutableSet<T> larger;
122                         if (Count < that.Count) {
123                                 smaller = this;
124                                 larger = that;
125                         } else {
126                                 if (that.Count == 0)
127                                         return this;
128                                 smaller = that;
129                                 larger = this;
130                         }
131                         IImmutableSet<T> result = larger;
132                         smaller.Visit (e => { result = result.Add (e); });
133                         return result;
134                 }
135
136                 public void Visit (Action<T> visitor)
137                 {
138                         this.underlying.Visit ((elem, dummy) => {
139                                                 visitor (elem);
140                                                 return VisitStatus.ContinueVisit;
141                                                });
142                 }
143
144                 public void Dump (TextWriter tw)
145                 {
146                         tw.Write ("{");
147                         bool first = true;
148                         foreach (T key in this.underlying.Keys) {
149                                 if (!first)
150                                         tw.Write (", ");
151                                 else
152                                         first = false;
153                                 tw.Write ("{0}", key);
154                         }
155                         tw.WriteLine ("}");
156                 }
157
158                 public static IImmutableSet<T> Empty ()
159                 {
160                         return new ImmutableSet<T> (ImmutableMap<T, Dummy>.Empty);
161                 }
162
163                 public static IImmutableSet<T> Empty (Func<T, int> keyConverter)
164                 {
165                         return new ImmutableSet<T> (ImmutableIntKeyMap<T, Dummy>.Empty (keyConverter));
166                 }
167                 #endregion
168         }
169 }