blob: b386c37b6c4fa526991c4862be1255a46765a4d2 [file] [log] [blame]
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001// Licensed to the Apache Software Foundation(ASF) under one
2// or more contributor license agreements.See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18using System.Collections;
Jens Geyeraffea7b2020-05-22 17:28:30 +020019using System.Collections.Generic;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010020
21namespace Thrift.Collections
22{
23 // ReSharper disable once InconsistentNaming
Jens Geyeraffea7b2020-05-22 17:28:30 +020024 public static class TCollections
Jens Geyeraa0c8b32019-01-28 23:27:45 +010025 {
26 /// <summary>
27 /// This will return true if the two collections are value-wise the same.
28 /// If the collection contains a collection, the collections will be compared using this method.
29 /// </summary>
30 public static bool Equals(IEnumerable first, IEnumerable second)
31 {
32 if (first == null && second == null)
33 {
34 return true;
35 }
36
37 if (first == null || second == null)
38 {
39 return false;
40 }
41
Jens Geyeraffea7b2020-05-22 17:28:30 +020042 // for dictionaries, we need to compare keys and values separately
43 // because KeyValuePair<K,V>.Equals() will not do what we want
44 var fdict = first as IDictionary;
45 var sdict = second as IDictionary;
46 if ((fdict != null) || (sdict != null))
47 {
48 if ((fdict == null) || (sdict == null))
49 return false;
50 return TCollections.Equals(fdict.Keys, sdict.Keys)
51 && TCollections.Equals(fdict.Values, sdict.Values);
52 }
53
Jens Geyeraa0c8b32019-01-28 23:27:45 +010054 var fiter = first.GetEnumerator();
55 var siter = second.GetEnumerator();
56
57 var fnext = fiter.MoveNext();
58 var snext = siter.MoveNext();
59
60 while (fnext && snext)
61 {
62 var fenum = fiter.Current as IEnumerable;
63 var senum = siter.Current as IEnumerable;
64
65 if (fenum != null && senum != null)
66 {
67 if (!Equals(fenum, senum))
68 {
69 return false;
70 }
71 }
72 else if (fenum == null ^ senum == null)
73 {
74 return false;
75 }
76 else if (!Equals(fiter.Current, siter.Current))
77 {
78 return false;
79 }
80
81 fnext = fiter.MoveNext();
82 snext = siter.MoveNext();
83 }
84
85 return fnext == snext;
86 }
87
88 /// <summary>
89 /// This returns a hashcode based on the value of the enumerable.
90 /// </summary>
91 public static int GetHashCode(IEnumerable enumerable)
92 {
93 if (enumerable == null)
94 {
95 return 0;
96 }
97
98 var hashcode = 0;
99
100 foreach (var obj in enumerable)
101 {
102 var enum2 = obj as IEnumerable;
103 var objHash = enum2 == null ? obj.GetHashCode() : GetHashCode(enum2);
104
105 unchecked
106 {
Jens Geyeraffea7b2020-05-22 17:28:30 +0200107 hashcode = (hashcode * 397) ^ (objHash);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100108 }
109 }
110
111 return hashcode;
112 }
Jens Geyeraffea7b2020-05-22 17:28:30 +0200113
114
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100115 }
Jens Geyeraffea7b2020-05-22 17:28:30 +0200116}