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