Bug 15572. Lookup KnownTypeCollection element types in MSSimpleNamespace
[mono.git] / mcs / class / Mono.C5 / Test / SupportClasses.cs
1 /*
2  Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft
3  Permission is hereby granted, free of charge, to any person obtaining a copy
4  of this software and associated documentation files (the "Software"), to deal
5  in the Software without restriction, including without limitation the rights
6  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  copies of the Software, and to permit persons to whom the Software is
8  furnished to do so, subject to the following conditions:
9  
10  The above copyright notice and this permission notice shall be included in
11  all copies or substantial portions of the Software.
12  
13  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19  SOFTWARE.
20 */
21
22 using System;
23 using C5;
24 using NUnit.Framework;
25 using SCG = System.Collections.Generic;
26
27
28 namespace C5UnitTests
29 {
30   class SC : SCG.IComparer<string>
31   {
32     public int Compare(string a, string b)
33     {
34       return a.CompareTo(b);
35     }
36
37
38     public void appl(String s)
39     {
40       System.Console.WriteLine("--{0}", s);
41     }
42   }
43
44   class TenEqualityComparer : SCG.IEqualityComparer<int>, SCG.IComparer<int>
45   {
46     TenEqualityComparer() { }
47     public static TenEqualityComparer Default { get { return new TenEqualityComparer(); } }
48     public int GetHashCode(int item) { return (item / 10).GetHashCode(); }
49     public bool Equals(int item1, int item2) { return item1 / 10 == item2 / 10; }
50     public int Compare(int a, int b) { return (a / 10).CompareTo(b / 10); }
51   }
52
53   class IC : SCG.IComparer<int>, IComparable<int>, SCG.IComparer<IC>, IComparable<IC>
54   {
55     public int Compare(int a, int b)
56     {
57       return a > b ? 1 : a < b ? -1 : 0;
58     }
59
60
61     public int Compare(IC a, IC b)
62     {
63       return a._i > b._i ? 1 : a._i < b._i ? -1 : 0;
64     }
65
66
67     private int _i;
68
69
70     public int i
71     {
72       get { return _i; }
73       set { _i = value; }
74     }
75
76
77     public IC() { }
78
79
80     public IC(int i) { _i = i; }
81
82
83     public int CompareTo(int that) { return _i > that ? 1 : _i < that ? -1 : 0; }
84
85     public bool Equals(int that) { return _i == that; }
86
87
88     public int CompareTo(IC that) { return _i > that._i ? 1 : _i < that._i ? -1 : 0; }
89     public bool Equals(IC that) { return _i == that._i; }
90
91
92     public static bool eq(SCG.IEnumerable<int> me, params int[] that)
93     {
94       int i = 0, maxind = that.Length - 1;
95
96       foreach (int item in me)
97         if (i > maxind || item != that[i++])
98           return false;
99
100       return i == maxind + 1;
101     }
102     public static bool seteq(ICollectionValue<int> me, params int[] that)
103     {
104       int[] me2 = me.ToArray();
105
106       Array.Sort(me2);
107
108       int i = 0, maxind = that.Length - 1;
109
110       foreach (int item in me2)
111         if (i > maxind || item != that[i++])
112           return false;
113
114       return i == maxind + 1;
115     }
116     public static bool seteq(ICollectionValue<KeyValuePair<int, int>> me, params int[] that)
117     {
118       ArrayList<KeyValuePair<int, int>> first = new ArrayList<KeyValuePair<int, int>>();
119       first.AddAll(me);
120       ArrayList<KeyValuePair<int, int>> other = new ArrayList<KeyValuePair<int, int>>();
121       for (int i = 0; i < that.Length; i += 2)
122       {
123         other.Add(new KeyValuePair<int, int>(that[i], that[i + 1]));
124       }
125       return other.UnsequencedEquals(first);
126     }
127   }
128
129   class RevIC : SCG.IComparer<int>
130   {
131     public int Compare(int a, int b)
132     {
133       return a > b ? -1 : a < b ? 1 : 0;
134     }
135   }
136
137   public class FunEnumerable : SCG.IEnumerable<int>
138   {
139     int size;
140     Fun<int, int> f;
141
142     public FunEnumerable(int size, Fun<int, int> f)
143     {
144       this.size = size; this.f = f;
145     }
146
147     public SCG.IEnumerator<int> GetEnumerator()
148     {
149       for (int i = 0; i < size; i++)
150         yield return f(i);
151     }
152
153
154     #region IEnumerable Members
155
156     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
157     {
158       throw new Exception("The method or operation is not implemented.");
159     }
160
161     #endregion
162   }
163
164   public class BadEnumerableException : Exception { }
165
166   public class BadEnumerable<T> : CollectionValueBase<T>, ICollectionValue<T>
167   {
168     T[] contents;
169     Exception exception;
170
171     public BadEnumerable(Exception exception, params T[] contents)
172     {
173       this.contents = (T[])contents.Clone();
174       this.exception = exception;
175     }
176
177     public override SCG.IEnumerator<T> GetEnumerator()
178     {
179       for (int i = 0; i < contents.Length; i++)
180         yield return contents[i];
181       throw exception;
182     }
183
184     public override bool IsEmpty { get { return false; } }
185
186     public override int Count { get { return contents.Length + 1; } }
187
188     public override Speed CountSpeed { get { return Speed.Constant; } }
189
190     public override T Choose() { throw exception; }
191   }
192
193   public class CollectionEventList<T>
194   {
195     ArrayList<CollectionEvent<T>> happened;
196     EventTypeEnum listenTo;
197     SCG.IEqualityComparer<T> itemequalityComparer;
198     public CollectionEventList(SCG.IEqualityComparer<T> itemequalityComparer)
199     {
200       happened = new ArrayList<CollectionEvent<T>>();
201       this.itemequalityComparer = itemequalityComparer;
202     }
203     public void Listen(ICollectionValue<T> list, EventTypeEnum listenTo)
204     {
205       this.listenTo = listenTo;
206       if ((listenTo & EventTypeEnum.Changed) != 0)
207         list.CollectionChanged += new CollectionChangedHandler<T>(changed);
208       if ((listenTo & EventTypeEnum.Cleared) != 0)
209         list.CollectionCleared += new CollectionClearedHandler<T>(cleared);
210       if ((listenTo & EventTypeEnum.Removed) != 0)
211         list.ItemsRemoved += new ItemsRemovedHandler<T>(removed);
212       if ((listenTo & EventTypeEnum.Added) != 0)
213         list.ItemsAdded += new ItemsAddedHandler<T>(added);
214       if ((listenTo & EventTypeEnum.Inserted) != 0)
215         list.ItemInserted += new ItemInsertedHandler<T>(inserted);
216       if ((listenTo & EventTypeEnum.RemovedAt) != 0)
217         list.ItemRemovedAt += new ItemRemovedAtHandler<T>(removedAt);
218     }
219     public void Add(CollectionEvent<T> e) { happened.Add(e); }
220     /// <summary>
221     /// Check that we have seen exactly the events in expected that match listenTo.
222     /// </summary>
223     /// <param name="expected"></param>
224     public void Check(SCG.IEnumerable<CollectionEvent<T>> expected)
225     {
226       int i = 0;
227       foreach (CollectionEvent<T> expectedEvent in expected)
228       {
229         if ((expectedEvent.Act & listenTo) == 0)
230           continue;
231         if (i >= happened.Count)
232           Assert.Fail(string.Format("Event number {0} did not happen:\n expected {1}", i, expectedEvent));
233         if (!expectedEvent.Equals(happened[i], itemequalityComparer))
234           Assert.Fail(string.Format("Event number {0}:\n expected {1}\n but saw {2}", i, expectedEvent, happened[i]));
235         i++;
236       }
237       if (i < happened.Count)
238         Assert.Fail(string.Format("Event number {0} seen but no event expected:\n {1}", i, happened[i]));
239       happened.Clear();
240     }
241     public void Clear() { happened.Clear(); }
242     public void Print(System.IO.TextWriter writer)
243     {
244       happened.Apply(delegate(CollectionEvent<T> e) { writer.WriteLine(e); });
245     }
246     void changed(object sender)
247     {
248       happened.Add(new CollectionEvent<T>(EventTypeEnum.Changed, new EventArgs(), sender));
249     }
250     void cleared(object sender, ClearedEventArgs eventArgs)
251     {
252       happened.Add(new CollectionEvent<T>(EventTypeEnum.Cleared, eventArgs, sender));
253     }
254     void added(object sender, ItemCountEventArgs<T> eventArgs)
255     {
256       happened.Add(new CollectionEvent<T>(EventTypeEnum.Added, eventArgs, sender));
257     }
258     void removed(object sender, ItemCountEventArgs<T> eventArgs)
259     {
260       happened.Add(new CollectionEvent<T>(EventTypeEnum.Removed, eventArgs, sender));
261     }
262     void inserted(object sender, ItemAtEventArgs<T> eventArgs)
263     {
264       happened.Add(new CollectionEvent<T>(EventTypeEnum.Inserted, eventArgs, sender));
265     }
266     void removedAt(object sender, ItemAtEventArgs<T> eventArgs)
267     {
268       happened.Add(new CollectionEvent<T>(EventTypeEnum.RemovedAt, eventArgs, sender));
269     }
270   }
271
272   public sealed class CollectionEvent<T>
273   {
274     public readonly EventTypeEnum Act;
275     public readonly EventArgs Args;
276     public readonly object Sender;
277
278     public CollectionEvent(EventTypeEnum act, EventArgs args, object sender)
279     {
280       this.Act = act;
281       this.Args = args;
282       this.Sender = sender;
283     }
284
285     public bool Equals(CollectionEvent<T> otherEvent, SCG.IEqualityComparer<T> itemequalityComparer)
286     {
287       if (otherEvent == null || Act != otherEvent.Act || !object.ReferenceEquals(Sender, otherEvent.Sender))
288         return false;
289       switch (Act)
290       {
291         case EventTypeEnum.None:
292           break;
293         case EventTypeEnum.Changed:
294           return true;
295         case EventTypeEnum.Cleared:
296           if (Args is ClearedRangeEventArgs)
297           {
298             ClearedRangeEventArgs a = Args as ClearedRangeEventArgs, o = otherEvent.Args as ClearedRangeEventArgs;
299             if (o == null)
300               return false;
301             return a.Full == o.Full && a.Start == o.Start && a.Count == o.Count;
302           }
303           else
304           {
305             if (otherEvent.Args is ClearedRangeEventArgs)
306               return false;
307             ClearedEventArgs a = Args as ClearedEventArgs, o = otherEvent.Args as ClearedEventArgs;
308             return a.Full == o.Full && a.Count == o.Count;
309           }
310         case EventTypeEnum.Added:
311           {
312             ItemCountEventArgs<T> a = Args as ItemCountEventArgs<T>, o = otherEvent.Args as ItemCountEventArgs<T>;
313             return itemequalityComparer.Equals(a.Item, o.Item) && a.Count == o.Count;
314           }
315         case EventTypeEnum.Removed:
316           {
317             ItemCountEventArgs<T> a = Args as ItemCountEventArgs<T>, o = otherEvent.Args as ItemCountEventArgs<T>;
318             return itemequalityComparer.Equals(a.Item, o.Item) && a.Count == o.Count;
319           }
320         case EventTypeEnum.Inserted:
321           {
322             ItemAtEventArgs<T> a = Args as ItemAtEventArgs<T>, o = otherEvent.Args as ItemAtEventArgs<T>;
323             return a.Index == o.Index && itemequalityComparer.Equals(a.Item, o.Item);
324           }
325         case EventTypeEnum.RemovedAt:
326           {
327             ItemAtEventArgs<T> a = Args as ItemAtEventArgs<T>, o = otherEvent.Args as ItemAtEventArgs<T>;
328             return a.Index == o.Index && itemequalityComparer.Equals(a.Item, o.Item);
329           }
330       }
331       throw new ApplicationException("Illegal Act: " + Act);
332     }
333
334     public override string ToString()
335     {
336       return string.Format("Act: {0}, Args : {1}, Source : {2}", Act, Args, Sender);
337     }
338
339   }
340
341   public class CHC
342   {
343     static public int unsequencedhashcode(params int[] a)
344     {
345       int h = 0;
346       foreach (int i in a)
347       {
348         h += (int)(((uint)i * 1529784657 + 1) ^ ((uint)i * 2912831877) ^ ((uint)i * 1118771817 + 2));
349       }
350       return h;
351     }
352     static public int sequencedhashcode(params int[] a)
353     {
354       int h = 0;
355       foreach (int i in a) { h = h * 31 + i; }
356       return h;
357     }
358   }
359
360   //This class is a modified sample from VS2005 beta1 documentation
361   public class RadixFormatProvider : IFormatProvider
362   {
363     RadixFormatter _radixformatter;
364     public RadixFormatProvider(int radix)
365     {
366       if (radix < 2 || radix > 36)
367         throw new ArgumentException(String.Format(
368             "The radix \"{0}\" is not in the range 2..36.",
369             radix));
370       _radixformatter = new RadixFormatter(radix);
371     }
372     public object GetFormat(Type argType)
373     {
374       if (argType == typeof(ICustomFormatter))
375         return _radixformatter;
376       else
377         return null;
378     }
379   }
380
381   //This class is a modified sample from VS2005 beta1 documentation
382   public class RadixFormatter : ICustomFormatter
383   {
384     int radix;
385     public RadixFormatter(int radix)
386     {
387       if (radix < 2 || radix > 36)
388         throw new ArgumentException(String.Format(
389             "The radix \"{0}\" is not in the range 2..36.",
390             radix));
391       this.radix = radix;
392     }
393
394     // The value to be formatted is returned as a signed string 
395     // of digits from the rDigits array. 
396     private static char[] rDigits = {
397         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
398         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 
399         'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 
400         'U', 'V', 'W', 'X', 'Y', 'Z' };
401
402     public string Format(string formatString,
403         object argToBeFormatted, IFormatProvider provider)
404     {
405       /*switch (Type.GetTypeCode(argToBeFormatted.GetType()))
406       {
407         case TypeCode.Boolean:
408           break;
409         case TypeCode.Byte:
410           break;
411         case TypeCode.Char:
412           break;
413         case TypeCode.DBNull:
414           break;
415         case TypeCode.DateTime:
416           break;
417         case TypeCode.Decimal:
418           break;
419         case TypeCode.Double:
420           break;
421         case TypeCode.Empty:
422           break;
423         case TypeCode.Int16:
424           break;
425         case TypeCode.Int32:
426           break;
427         case TypeCode.Int64:
428           break;
429         case TypeCode.Object:
430           break;
431         case TypeCode.SByte:
432           break;
433         case TypeCode.Single:
434           break;
435         case TypeCode.String:
436           break;
437         case TypeCode.UInt16:
438           break;
439         case TypeCode.UInt32:
440           break;
441         case TypeCode.UInt64:
442           break;
443       }*/
444       int intToBeFormatted;
445       try
446       {
447         intToBeFormatted = (int)argToBeFormatted;
448       }
449       catch (Exception)
450       {
451         if (argToBeFormatted is IFormattable)
452           return ((IFormattable)argToBeFormatted).
453               ToString(formatString, provider);
454         else
455           return argToBeFormatted.ToString();
456       }
457       return formatInt(intToBeFormatted);
458     }
459
460     private string formatInt(int intToBeFormatted)
461     {
462       // The formatting is handled here.
463       if (intToBeFormatted == 0)
464         return "0";
465       int digitIndex = 0;
466       int intPositive;
467       char[] outDigits = new char[31];
468
469       // Verify that the argument can be converted to a int integer.
470       // Extract the magnitude for conversion.
471       intPositive = Math.Abs(intToBeFormatted);
472
473       // Convert the magnitude to a digit string.
474       for (digitIndex = 0; digitIndex <= 32; digitIndex++)
475       {
476         if (intPositive == 0) break;
477
478         outDigits[outDigits.Length - digitIndex - 1] =
479             rDigits[intPositive % radix];
480         intPositive /= radix;
481       }
482
483       // Add a minus sign if the argument is negative.
484       if (intToBeFormatted < 0)
485         outDigits[outDigits.Length - digitIndex++ - 1] =
486             '-';
487
488       return new string(outDigits,
489           outDigits.Length - digitIndex, digitIndex);
490     }
491   }
492
493 }