| 863 | */ |
| 864 | template <typename SourceAllocator> |
| 865 | bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const { |
| 866 | typedef GenericValue<Encoding, SourceAllocator> RhsType; |
| 867 | if (GetType() != rhs.GetType()) |
| 868 | return false; |
| 869 | |
| 870 | switch (GetType()) { |
| 871 | case kObjectType: // Warning: O(n^2) inner-loop |
| 872 | if (data_.o.size != rhs.data_.o.size) |
| 873 | return false; |
| 874 | for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { |
| 875 | typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); |
| 876 | if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) |
| 877 | return false; |
| 878 | } |
| 879 | return true; |
| 880 | |
| 881 | case kArrayType: |
| 882 | if (data_.a.size != rhs.data_.a.size) |
| 883 | return false; |
| 884 | for (SizeType i = 0; i < data_.a.size; i++) |
| 885 | if ((*this)[i] != rhs[i]) |
| 886 | return false; |
| 887 | return true; |
| 888 | |
| 889 | case kStringType: |
| 890 | return StringEqual(rhs); |
| 891 | |
| 892 | case kNumberType: |
| 893 | if (IsDouble() || rhs.IsDouble()) { |
| 894 | double a = GetDouble(); // May convert from integer to double. |
| 895 | double b = rhs.GetDouble(); // Ditto |
| 896 | return a >= b && a <= b; // Prevent -Wfloat-equal |
| 897 | } |
| 898 | else |
| 899 | return data_.n.u64 == rhs.data_.n.u64; |
| 900 | |
| 901 | default: |
| 902 | return true; |
| 903 | } |
| 904 | } |
| 905 | |
| 906 | //! Equal-to operator with const C-string pointer |
| 907 | bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } |
nothing calls this directly
no test coverage detected