LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Deep equality test via reflection | 5 // Deep equality test via reflection |
6 | 6 |
7 package reflect | 7 package reflect |
8 | 8 |
9 // During deepValueEqual, must keep track of checks that are | 9 // During deepValueEqual, must keep track of checks that are |
10 // in progress. The comparison algorithm assumes that all | 10 // in progress. The comparison algorithm assumes that all |
11 // checks in progress are true when it reencounters them. | 11 // checks in progress are true when it reencounters them. |
12 // Visited are stored in a map indexed by 17 * a1 + a2; | 12 // Visited comparisons are stored in a map indexed by visit. |
13 type visit struct { | 13 type visit struct { |
14 a1 uintptr | 14 a1 uintptr |
15 a2 uintptr | 15 a2 uintptr |
16 typ Type | 16 typ Type |
17 } | 17 } |
18 | 18 |
19 // Tests for deep equality using reflected types. The map argument tracks | 19 // Tests for deep equality using reflected types. The map argument tracks |
20 // comparisons that have already been seen, which allows short circuiting on | 20 // comparisons that have already been seen, which allows short circuiting on |
21 // recursive types. | 21 // recursive types. |
22 func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) (b bool) { | 22 func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool { |
23 if !v1.IsValid() || !v2.IsValid() { | 23 if !v1.IsValid() || !v2.IsValid() { |
24 return v1.IsValid() == v2.IsValid() | 24 return v1.IsValid() == v2.IsValid() |
25 } | 25 } |
26 if v1.Type() != v2.Type() { | 26 if v1.Type() != v2.Type() { |
27 return false | 27 return false |
28 } | 28 } |
29 | 29 |
30 // if depth > 10 { panic("deepValueEqual") } // for debugging | 30 // if depth > 10 { panic("deepValueEqual") } // for debugging |
31 | 31 |
32 if v1.CanAddr() && v2.CanAddr() { | 32 if v1.CanAddr() && v2.CanAddr() { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 if a1 == nil || a2 == nil { | 126 if a1 == nil || a2 == nil { |
127 return a1 == a2 | 127 return a1 == a2 |
128 } | 128 } |
129 v1 := ValueOf(a1) | 129 v1 := ValueOf(a1) |
130 v2 := ValueOf(a2) | 130 v2 := ValueOf(a2) |
131 if v1.Type() != v2.Type() { | 131 if v1.Type() != v2.Type() { |
132 return false | 132 return false |
133 } | 133 } |
134 return deepValueEqual(v1, v2, make(map[visit]bool), 0) | 134 return deepValueEqual(v1, v2, make(map[visit]bool), 0) |
135 } | 135 } |
LEFT | RIGHT |