tint: Misc hash / container contract improvements

Add a hash implementation to tint::Number.
Add a utils::Hasher specialization for std::variant.
Add an operator!= for Vector. Needed for std::variants.
Drop the need for explicit on Vector constructors from refs.

These all help general usage with STL and util containers.

Change-Id: I1e594edf532e78f531062c534dacaee7616cded5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/100905
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/number.h b/src/tint/number.h
index a36ccfb..4635051 100644
--- a/src/tint/number.h
+++ b/src/tint/number.h
@@ -496,4 +496,19 @@
 
 }  // namespace tint::number_suffixes
 
+namespace std {
+
+/// Custom std::hash specialization for tint::Number<T>
+template <typename T>
+class hash<tint::Number<T>> {
+  public:
+    /// @param n the Number
+    /// @return the hash value
+    inline std::size_t operator()(const tint::Number<T>& n) const {
+        return std::hash<decltype(n.value)>()(n.value);
+    }
+};
+
+}  // namespace std
+
 #endif  // SRC_TINT_NUMBER_H_
diff --git a/src/tint/utils/hash.h b/src/tint/utils/hash.h
index ad53841..717b35f 100644
--- a/src/tint/utils/hash.h
+++ b/src/tint/utils/hash.h
@@ -20,6 +20,7 @@
 #include <functional>
 #include <tuple>
 #include <utility>
+#include <variant>
 #include <vector>
 
 #include "src/tint/utils/vector.h"
@@ -117,6 +118,16 @@
     }
 };
 
+/// Hasher specialization for std::tuple
+template <typename... TYPES>
+struct Hasher<std::variant<TYPES...>> {
+    /// @param variant the variant to hash
+    /// @returns a hash of the tuple
+    size_t operator()(const std::variant<TYPES...>& variant) const {
+        return std::visit([](auto&& val) { return Hash(val); }, variant);
+    }
+};
+
 /// @returns a hash of the variadic list of arguments.
 ///          The returned hash is dependent on the order of the arguments.
 template <typename... ARGS>
diff --git a/src/tint/utils/vector.h b/src/tint/utils/vector.h
index b718840..f0cbf58 100644
--- a/src/tint/utils/vector.h
+++ b/src/tint/utils/vector.h
@@ -243,11 +243,11 @@
 
     /// Move constructor from a mutable vector reference
     /// @param other the vector reference to move
-    explicit Vector(VectorRef<T>&& other) { MoveOrCopy(std::move(other)); }
+    Vector(VectorRef<T>&& other) { MoveOrCopy(std::move(other)); }  // NOLINT(runtime/explicit)
 
     /// Copy constructor from an immutable vector reference
     /// @param other the vector reference to copy
-    explicit Vector(const VectorRef<T>& other) { Copy(other.slice_); }
+    Vector(const VectorRef<T>& other) { Copy(other.slice_); }  // NOLINT(runtime/explicit)
 
     /// Destructor
     ~Vector() { ClearAndFree(); }
@@ -475,6 +475,12 @@
         return true;
     }
 
+    /// Inequality operator
+    /// @param other the other vector
+    /// @returns true if this vector is not the same length as `other`, or all elements are not
+    ///          equal.
+    bool operator!=(const Vector& other) const { return !(*this == other); }
+
   private:
     /// Friend class (differing specializations of this class)
     template <typename, size_t>