1 #region (c)2009 Lokad - New BSD license
2 
3 // Copyright (c) Lokad 2009
4 // Company: http://www.lokad.com
5 // This code is released under the terms of the new BSD licence
6 
7 #endregion
8 
9 #if !NET_4_0 && !SILVERLIGHT && !MONOTOUCH && !XBOX
10 
11 using System;
12 using System.Collections.Generic;
13 using System.Diagnostics;
14 
15 namespace ServiceStack.Net30
16 {
17     public static class SystemUtil
18     {
GetHashCode(params object[] args)19         internal static int GetHashCode(params object[] args)
20         {
21             unchecked
22             {
23                 int result = 0;
24                 foreach (var o in args)
25                 {
26                     result = (result * 397) ^ (o != null ? o.GetHashCode() : 0);
27                 }
28                 return result;
29             }
30         }
31     }
32 
33     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
34     public sealed class ImmutableAttribute : Attribute
35     {
36     }
37 
38     /// <summary>
39     /// Helper extensions for tuples
40     /// </summary>
41     public static class ExtendTuple
42     {
Append(this Tuple<T1, T2> tuple, T3 item)43         public static Triple<T1, T2, T3> Append<T1, T2, T3>(this Tuple<T1, T2> tuple, T3 item)
44         {
45             return Tuple.From(tuple.Item1, tuple.Item2, item);
46         }
47 
Append(this Tuple<T1, T2, T3> tuple, T4 item)48         public static Quad<T1, T2, T3, T4> Append<T1, T2, T3, T4>(this Tuple<T1, T2, T3> tuple, T4 item)
49         {
50             return Tuple.From(tuple.Item1, tuple.Item2, tuple.Item3, item);
51         }
52 
AddTuple(this ICollection<Tuple<T1, T2>> collection, T1 first, T2 second)53         public static void AddTuple<T1, T2>(this ICollection<Tuple<T1, T2>> collection, T1 first, T2 second)
54         {
55             collection.Add(Tuple.From(first, second));
56         }
57 
AddTuple(this ICollection<Pair<T1, T2>> collection, T1 first, T2 second)58         public static void AddTuple<T1, T2>(this ICollection<Pair<T1, T2>> collection, T1 first, T2 second)
59         {
60             collection.Add(Tuple.From(first, second));
61         }
62 
AddTuple(this ICollection<Tuple<T1, T2, T3>> collection, T1 first, T2 second, T3 third)63         public static void AddTuple<T1, T2, T3>(this ICollection<Tuple<T1, T2, T3>> collection, T1 first, T2 second, T3 third)
64         {
65             collection.Add(Tuple.From(first, second, third));
66         }
67 
AddTuple(this ICollection<Tuple<T1, T2, T3, T4>> collection, T1 first, T2 second, T3 third, T4 fourth)68         public static void AddTuple<T1, T2, T3, T4>(this ICollection<Tuple<T1, T2, T3, T4>> collection, T1 first, T2 second,
69                                                     T3 third, T4 fourth)
70         {
71             collection.Add(Tuple.From(first, second, third, fourth));
72         }
73 
74     }
75 
76     [Serializable]
77     [Immutable]
78     public sealed class Pair<TKey, TValue> : Tuple<TKey, TValue>
79     {
Pair(TKey first, TValue second)80         public Pair(TKey first, TValue second) : base(first, second) {}
81 
82         public TKey Key
83         {
84             get { return Item1; }
85         }
86 
87         public TValue Value
88         {
89             get { return Item2; }
90         }
91     }
92 
93     [Serializable]
94     [Immutable]
95     public sealed class Quad<T1, T2, T3, T4> : Tuple<T1, T2, T3, T4>
96     {
Quad(T1 first, T2 second, T3 third, T4 fourth)97         public Quad(T1 first, T2 second, T3 third, T4 fourth) : base(first, second, third, fourth)
98         {
99         }
100     }
101 
102     [Serializable]
103     [Immutable]
104     public sealed class Triple<T1, T2, T3> : Tuple<T1, T2, T3>
105     {
Triple(T1 first, T2 second, T3 third)106         public Triple(T1 first, T2 second, T3 third)
107             : base(first, second, third)
108         {
109         }
110     }
111 
112     [Serializable]
113     [Immutable]
114     [DebuggerDisplay("({Item1},{Item2})")]
115     public class Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
116     {
117         readonly T1 _item1;
118 
119         public T1 Item1
120         {
121             get { return _item1; }
122         }
123 
124         readonly T2 _item2;
125 
126         public T2 Item2
127         {
128             get { return _item2; }
129         }
130 
Tuple(T1 first, T2 second)131         public Tuple(T1 first, T2 second)
132         {
133             _item1 = first;
134             _item2 = second;
135         }
136 
Equals(object obj)137         public override bool Equals(object obj)
138         {
139             if (ReferenceEquals(null, obj))
140                 throw new NullReferenceException("obj is null");
141             if (ReferenceEquals(this, obj)) return true;
142             if (!(obj is Tuple<T1, T2>)) return false;
143             return Equals((Tuple<T1, T2>)obj);
144         }
145 
ToString()146         public override string ToString()
147         {
148             return string.Format("({0},{1})", Item1, Item2);
149         }
150 
Equals(Tuple<T1, T2> obj)151         public bool Equals(Tuple<T1, T2> obj)
152         {
153             if (ReferenceEquals(null, obj)) return false;
154             if (ReferenceEquals(this, obj)) return true;
155             return Equals(obj.Item1, Item1) && Equals(obj.Item2, Item2);
156         }
157 
GetHashCode()158         public override int GetHashCode()
159         {
160             return SystemUtil.GetHashCode(Item1, Item2);
161         }
162 
operator ==(Tuple<T1, T2> left, Tuple<T1, T2> right)163         public static bool operator ==(Tuple<T1, T2> left, Tuple<T1, T2> right)
164         {
165             return Equals(left, right);
166         }
167 
operator !=(Tuple<T1, T2> left, Tuple<T1, T2> right)168         public static bool operator !=(Tuple<T1, T2> left, Tuple<T1, T2> right)
169         {
170             return !Equals(left, right);
171         }
172     }
173 
174     [Serializable]
175     [DebuggerDisplay("({Item1},{Item2},{Item3})")]
176     public class Tuple<T1, T2, T3> : IEquatable<Tuple<T1, T2, T3>>
177     {
178         readonly T1 _item1;
179 
180         public T1 Item1
181         {
182             get { return _item1; }
183         }
184 
185         readonly T2 _item2;
186 
187         public T2 Item2
188         {
189             get { return _item2; }
190         }
191 
192         readonly T3 _item3;
193 
194         public T3 Item3
195         {
196             get { return _item3; }
197         }
198 
Tuple(T1 first, T2 second, T3 third)199         public Tuple(T1 first, T2 second, T3 third)
200         {
201             _item1 = first;
202             _item2 = second;
203             _item3 = third;
204         }
205 
ToString()206         public override string ToString()
207         {
208             return string.Format("({0},{1},{2})", Item1, Item2, Item3);
209         }
210 
Equals(object obj)211         public override bool Equals(object obj)
212         {
213             if (ReferenceEquals(null, obj))
214                 throw new NullReferenceException("obj is null");
215             if (ReferenceEquals(this, obj)) return true;
216             if (!(obj is Tuple<T1, T2, T3>)) return false;
217             return Equals((Tuple<T1, T2, T3>)obj);
218         }
219 
Equals(Tuple<T1, T2, T3> obj)220         public bool Equals(Tuple<T1, T2, T3> obj)
221         {
222             if (ReferenceEquals(null, obj)) return false;
223             if (ReferenceEquals(this, obj)) return true;
224             return Equals(obj.Item1, Item1) && Equals(obj.Item2, Item2) && Equals(obj.Item3, Item3);
225         }
226 
GetHashCode()227         public override int GetHashCode()
228         {
229             return SystemUtil.GetHashCode(Item1, Item2, Item3);
230         }
231 
operator ==(Tuple<T1, T2, T3> left, Tuple<T1, T2, T3> right)232         public static bool operator ==(Tuple<T1, T2, T3> left, Tuple<T1, T2, T3> right)
233         {
234             return Equals(left, right);
235         }
236 
operator !=(Tuple<T1, T2, T3> left, Tuple<T1, T2, T3> right)237         public static bool operator !=(Tuple<T1, T2, T3> left, Tuple<T1, T2, T3> right)
238         {
239             return !Equals(left, right);
240         }
241     }
242 
243     [Serializable]
244     [DebuggerDisplay("({Item1},{Item2},{Item3},{Item4})")]
245     [Immutable]
246     public class Tuple<T1, T2, T3, T4> : IEquatable<Tuple<T1, T2, T3, T4>>
247     {
248         readonly T1 _item1;
249 
250         public T1 Item1
251         {
252             get { return _item1; }
253         }
254 
255         readonly T2 _item2;
256 
257         public T2 Item2
258         {
259             get { return _item2; }
260         }
261 
262         readonly T3 _item3;
263 
264         public T3 Item3
265         {
266             get { return _item3; }
267         }
268 
269         readonly T4 _item4;
270 
271         public T4 Item4
272         {
273             get { return _item4; }
274         }
275 
Tuple(T1 first, T2 second, T3 third, T4 fourth)276         public Tuple(T1 first, T2 second, T3 third, T4 fourth)
277         {
278             _item1 = first;
279             _item2 = second;
280             _item3 = third;
281             _item4 = fourth;
282         }
283 
ToString()284         public override string ToString()
285         {
286             return string.Format("({0},{1},{2},{3})", Item1, Item2, Item3, Item4);
287         }
288 
Equals(object obj)289         public override bool Equals(object obj)
290         {
291             if (ReferenceEquals(null, obj))
292                 throw new NullReferenceException("obj is null");
293             if (ReferenceEquals(this, obj)) return true;
294             if (!(obj is Tuple<T1, T2, T3, T4>)) return false;
295             return Equals((Tuple<T1, T2, T3, T4>)obj);
296         }
297 
Equals(Tuple<T1, T2, T3, T4> obj)298         public bool Equals(Tuple<T1, T2, T3, T4> obj)
299         {
300             if (ReferenceEquals(null, obj)) return false;
301             if (ReferenceEquals(this, obj)) return true;
302             return Equals(obj.Item1, Item1)
303                 && Equals(obj.Item2, Item2)
304                     && Equals(obj.Item3, Item3)
305                         && Equals(obj.Item4, Item4);
306         }
307 
GetHashCode()308         public override int GetHashCode()
309         {
310             return SystemUtil.GetHashCode(Item1, Item2, Item3, Item4);
311         }
312 
operator ==(Tuple<T1, T2, T3, T4> left, Tuple<T1, T2, T3, T4> right)313         public static bool operator ==(Tuple<T1, T2, T3, T4> left, Tuple<T1, T2, T3, T4> right)
314         {
315             return Equals(left, right);
316         }
317 
operator !=(Tuple<T1, T2, T3, T4> left, Tuple<T1, T2, T3, T4> right)318         public static bool operator !=(Tuple<T1, T2, T3, T4> left, Tuple<T1, T2, T3, T4> right)
319         {
320             return !Equals(left, right);
321         }
322     }
323 
324     public static class Tuple
325     {
From(T1 first, T2 second)326         public static Pair<T1, T2> From<T1, T2>(T1 first, T2 second)
327         {
328             return new Pair<T1, T2>(first, second);
329         }
330 
Create(T1 first, T2 second)331         public static Tuple<T1, T2> Create<T1, T2>(T1 first, T2 second)
332         {
333             return new Pair<T1, T2>(first, second);
334         }
335 
From(T1 first, T2 second, T3 third)336         public static Triple<T1, T2, T3> From<T1, T2, T3>(T1 first, T2 second, T3 third)
337         {
338             return new Triple<T1, T2, T3>(first, second, third);
339         }
340 
Create(T1 first, T2 second, T3 third)341         public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 first, T2 second, T3 third)
342         {
343             return new Triple<T1, T2, T3>(first, second, third);
344         }
345 
From(T1 first, T2 second, T3 third, T4 fourth)346         public static Quad<T1, T2, T3, T4> From<T1, T2, T3, T4>(T1 first, T2 second, T3 third, T4 fourth)
347         {
348             return new Quad<T1, T2, T3, T4>(first, second, third, fourth);
349         }
350 
Create(T1 first, T2 second, T3 third, T4 fourth)351         public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 first, T2 second, T3 third, T4 fourth)
352         {
353             return new Quad<T1, T2, T3, T4>(first, second, third, fourth);
354         }
355     }
356 
357 }
358 
359 
360 #endif
361 
362