Implement base::Value::operator== for various base::Value subtypes.

It should be possible to directly compare int, double, et cetera against
base::Value without first wrapping an operand in base::Value. While this
is not problematic for types like int which are inexpensive to copy, it
can be considerably more expensive for base::Value::Dict or std::string.

After this lands:
- existing base::Value::Equals() usage will be complete migrated over to
  use operator==.
- existing places that wrap the operands, e.g. write base::Value(x) == y
  or EXPECT_EQ(base::Value(x), y), will be migrated to the version that
  does not require wrapping.

Why not just implement operator== for base::ValueView?
- base::ValueView is only intended for limited usage, e.g. in generic
  JSON handling code.
- implementing it for base::ValueView does not allow a compile-time
  restriction against blobs (under the hope of eventual deprecation
  and/or removal of blob handling in base::Value itself).

Bug: 646113
Change-Id: Ie52c788e69315f2b85bd45a2f7ee0438c4c57e58
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3665235
Commit-Queue: Daniel Cheng <[email protected]>
Reviewed-by: Lei Zhang <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1007204}
diff --git a/base/values.h b/base/values.h
index ddb8aa10..50521aec 100644
--- a/base/values.h
+++ b/base/values.h
@@ -1050,6 +1050,51 @@
   BASE_EXPORT friend bool operator<=(const Value& lhs, const Value& rhs);
   BASE_EXPORT friend bool operator>=(const Value& lhs, const Value& rhs);
 
+  BASE_EXPORT friend bool operator==(const Value& lhs, bool rhs);
+  friend bool operator==(bool lhs, const Value& rhs) { return rhs == lhs; }
+  friend bool operator!=(const Value& lhs, bool rhs) { return !(lhs == rhs); }
+  friend bool operator!=(bool lhs, const Value& rhs) { return !(lhs == rhs); }
+  BASE_EXPORT friend bool operator==(const Value& lhs, int rhs);
+  friend bool operator==(int lhs, const Value& rhs) { return rhs == lhs; }
+  friend bool operator!=(const Value& lhs, int rhs) { return !(lhs == rhs); }
+  friend bool operator!=(int lhs, const Value& rhs) { return !(lhs == rhs); }
+  BASE_EXPORT friend bool operator==(const Value& lhs, double rhs);
+  friend bool operator==(double lhs, const Value& rhs) { return rhs == lhs; }
+  friend bool operator!=(const Value& lhs, double rhs) { return !(lhs == rhs); }
+  friend bool operator!=(double lhs, const Value& rhs) { return !(lhs == rhs); }
+  BASE_EXPORT friend bool operator==(const Value& lhs, StringPiece rhs);
+  friend bool operator==(StringPiece lhs, const Value& rhs) {
+    return rhs == lhs;
+  }
+  friend bool operator!=(const Value& lhs, StringPiece rhs) {
+    return !(lhs == rhs);
+  }
+  friend bool operator!=(StringPiece lhs, const Value& rhs) {
+    return !(lhs == rhs);
+  }
+  // Note: Blob support intentionally omitted as an experiment for potentially
+  // wholly removing Blob support from Value itself in the future.
+  BASE_EXPORT friend bool operator==(const Value& lhs, const Value::Dict& rhs);
+  friend bool operator==(const Value::Dict& lhs, const Value& rhs) {
+    return rhs == lhs;
+  }
+  friend bool operator!=(const Value& lhs, const Value::Dict& rhs) {
+    return !(lhs == rhs);
+  }
+  friend bool operator!=(const Value::Dict& lhs, const Value& rhs) {
+    return !(lhs == rhs);
+  }
+  BASE_EXPORT friend bool operator==(const Value& lhs, const Value::List& rhs);
+  friend bool operator==(const Value::List& lhs, const Value& rhs) {
+    return rhs == lhs;
+  }
+  friend bool operator!=(const Value& lhs, const Value::List& rhs) {
+    return !(lhs == rhs);
+  }
+  friend bool operator!=(const Value::List& lhs, const Value& rhs) {
+    return !(lhs == rhs);
+  }
+
   // Compares if two Value objects have equal contents.
   // DEPRECATED, use `operator==(const Value& lhs, const Value& rhs)` instead.
   // TODO(crbug.com/646113): Delete this and migrate callsites.