summaryrefslogtreecommitdiffstats
path: root/mojo
diff options
context:
space:
mode:
authoraa <aa@chromium.org>2014-10-14 18:18:00 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-15 01:18:15 +0000
commit6b5d1a9be85123b55109f92268a6bf31157f2b88 (patch)
tree8cf52182dd2e4738216fcf9ff178dec4fae1ccdb /mojo
parent204bacbab4ef7aae299f673705e31e51478332fa (diff)
downloadchromium_src-6b5d1a9be85123b55109f92268a6bf31157f2b88.zip
chromium_src-6b5d1a9be85123b55109f92268a6bf31157f2b88.tar.gz
chromium_src-6b5d1a9be85123b55109f92268a6bf31157f2b88.tar.bz2
Add Equals() to mojom structs and related types.
BUG= Review URL: https://codereview.chromium.org/649633003 Cr-Commit-Position: refs/heads/master@{#299614}
Diffstat (limited to 'mojo')
-rw-r--r--mojo/edk/mojo_edk.gyp1
-rw-r--r--mojo/public/cpp/bindings/array.h13
-rw-r--r--mojo/public/cpp/bindings/lib/bindings_internal.h29
-rw-r--r--mojo/public/cpp/bindings/lib/map_internal.h2
-rw-r--r--mojo/public/cpp/bindings/lib/template_util.h9
-rw-r--r--mojo/public/cpp/bindings/map.h18
-rw-r--r--mojo/public/cpp/bindings/struct_ptr.h11
-rw-r--r--mojo/public/cpp/bindings/tests/BUILD.gn1
-rw-r--r--mojo/public/cpp/bindings/tests/equals_unittest.cc120
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl2
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl9
11 files changed, 214 insertions, 1 deletions
diff --git a/mojo/edk/mojo_edk.gyp b/mojo/edk/mojo_edk.gyp
index 98c493b..58dae52 100644
--- a/mojo/edk/mojo_edk.gyp
+++ b/mojo/edk/mojo_edk.gyp
@@ -85,6 +85,7 @@
'../public/cpp/bindings/tests/buffer_unittest.cc',
'../public/cpp/bindings/tests/connector_unittest.cc',
'../public/cpp/bindings/tests/container_test_util.cc',
+ '../public/cpp/bindings/tests/equals_unittest.cc',
'../public/cpp/bindings/tests/handle_passing_unittest.cc',
'../public/cpp/bindings/tests/interface_ptr_unittest.cc',
'../public/cpp/bindings/tests/map_unittest.cc',
diff --git a/mojo/public/cpp/bindings/array.h b/mojo/public/cpp/bindings/array.h
index 966cf31..2544abb 100644
--- a/mojo/public/cpp/bindings/array.h
+++ b/mojo/public/cpp/bindings/array.h
@@ -12,6 +12,7 @@
#include <vector>
#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
#include "mojo/public/cpp/bindings/type_converter.h"
@@ -107,6 +108,18 @@ class Array {
return result.Pass();
}
+ bool Equals(const Array& other) const {
+ if (is_null() != other.is_null())
+ return false;
+ if (size() != other.size())
+ return false;
+ for (size_t i = 0; i < size(); ++i) {
+ if (!internal::ValueTraits<T>::Equals(at(i), other.at(i)))
+ return false;
+ }
+ return true;
+ }
+
private:
typedef std::vector<StorageType> Array::*Testable;
diff --git a/mojo/public/cpp/bindings/lib/bindings_internal.h b/mojo/public/cpp/bindings/lib/bindings_internal.h
index df3c620..ec70d37 100644
--- a/mojo/public/cpp/bindings/lib/bindings_internal.h
+++ b/mojo/public/cpp/bindings/lib/bindings_internal.h
@@ -12,6 +12,12 @@
namespace mojo {
class String;
+template <typename T>
+class Array;
+
+template <typename K, typename V>
+class Map;
+
namespace internal {
template <typename T>
class Array_Data;
@@ -94,6 +100,29 @@ struct WrapperTraits<S, true> {
typedef typename S::Data_* DataType;
};
+template <typename T, typename Enable = void>
+struct ValueTraits {
+ static bool Equals(const T& a, const T& b) { return a == b; }
+};
+
+template <typename T>
+struct ValueTraits<
+ T,
+ typename EnableIf<IsSpecializationOf<Array, T>::value ||
+ IsSpecializationOf<Map, T>::value ||
+ IsSpecializationOf<StructPtr, T>::value ||
+ IsSpecializationOf<InlinedStructPtr, T>::value>::type> {
+ static bool Equals(const T& a, const T& b) { return a.Equals(b); }
+};
+
+template <typename T>
+struct ValueTraits<ScopedHandleBase<T>> {
+ static bool Equals(const ScopedHandleBase<T>& a,
+ const ScopedHandleBase<T>& b) {
+ return a.get().value() == b.get().value();
+ }
+};
+
} // namespace internal
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/map_internal.h b/mojo/public/cpp/bindings/lib/map_internal.h
index ce6e9d6..aa0fe7e 100644
--- a/mojo/public/cpp/bindings/lib/map_internal.h
+++ b/mojo/public/cpp/bindings/lib/map_internal.h
@@ -8,7 +8,7 @@
#include <map>
#include "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+#include "mojo/public/cpp/bindings/lib/template_util.h"
namespace mojo {
namespace internal {
diff --git a/mojo/public/cpp/bindings/lib/template_util.h b/mojo/public/cpp/bindings/lib/template_util.h
index c4aeb43..6767acf 100644
--- a/mojo/public/cpp/bindings/lib/template_util.h
+++ b/mojo/public/cpp/bindings/lib/template_util.h
@@ -104,6 +104,15 @@ struct RemovePointer<T*> {
typedef T type;
};
+template <template <typename...> class Template, typename T>
+struct IsSpecializationOf : FalseType {};
+
+template <template <typename...> class Template, typename... Args>
+struct IsSpecializationOf<Template, Template<Args...>> : TrueType {};
+
+template <class A, class B>
+struct LogicalOr : IntegralConstant<bool, A::value || B::value> {};
+
} // namespace internal
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/map.h b/mojo/public/cpp/bindings/map.h
index 0ee66fb..f09937a 100644
--- a/mojo/public/cpp/bindings/map.h
+++ b/mojo/public/cpp/bindings/map.h
@@ -117,6 +117,24 @@ class Map {
return result.Pass();
}
+ bool Equals(const Map& other) const {
+ if (is_null() != other.is_null())
+ return false;
+ if (size() != other.size())
+ return false;
+ auto i = begin();
+ auto j = other.begin();
+ while (i != end()) {
+ if (i.GetKey() != j.GetKey())
+ return false;
+ if (!internal::ValueTraits<Value>::Equals(i.GetValue(), j.GetValue()))
+ return false;
+ ++i;
+ ++j;
+ }
+ return true;
+ }
+
class ConstMapIterator {
public:
ConstMapIterator(
diff --git a/mojo/public/cpp/bindings/struct_ptr.h b/mojo/public/cpp/bindings/struct_ptr.h
index 5d08364..efcf255 100644
--- a/mojo/public/cpp/bindings/struct_ptr.h
+++ b/mojo/public/cpp/bindings/struct_ptr.h
@@ -71,6 +71,12 @@ class StructPtr {
// that it contains Mojo handles).
StructPtr Clone() const { return is_null() ? StructPtr() : ptr_->Clone(); }
+ bool Equals(const StructPtr& other) const {
+ if (is_null() || other.is_null())
+ return is_null() && other.is_null();
+ return ptr_->Equals(*other.ptr_);
+ }
+
private:
typedef Struct* StructPtr::*Testable;
@@ -139,6 +145,11 @@ class InlinedStructPtr {
InlinedStructPtr Clone() const {
return is_null() ? InlinedStructPtr() : value_.Clone();
}
+ bool Equals(const InlinedStructPtr& other) const {
+ if (is_null() || other.is_null())
+ return is_null() && other.is_null();
+ return value_.Equals(other.value_);
+ }
private:
typedef Struct InlinedStructPtr::*Testable;
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn
index 918a3db..9e6deab 100644
--- a/mojo/public/cpp/bindings/tests/BUILD.gn
+++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -10,6 +10,7 @@ test("mojo_public_bindings_unittests") {
"buffer_unittest.cc",
"connector_unittest.cc",
"container_test_util.cc",
+ "equals_unittest.cc",
"handle_passing_unittest.cc",
"interface_ptr_unittest.cc",
"map_unittest.cc",
diff --git a/mojo/public/cpp/bindings/tests/equals_unittest.cc b/mojo/public/cpp/bindings/tests/equals_unittest.cc
new file mode 100644
index 0000000..38c78cb
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/equals_unittest.cc
@@ -0,0 +1,120 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+
+namespace {
+
+RectPtr CreateRect() {
+ RectPtr r = Rect::New();
+ r->x = 1;
+ r->y = 2;
+ r->width = 3;
+ r->height = 4;
+ return r.Pass();
+}
+
+class EqualsTest : public testing::Test {
+ public:
+ virtual ~EqualsTest() {}
+
+ private:
+ Environment env_;
+};
+}
+
+TEST_F(EqualsTest, Null) {
+ RectPtr r1;
+ RectPtr r2;
+ EXPECT_TRUE(r1.Equals(r2));
+ EXPECT_TRUE(r2.Equals(r1));
+
+ r1 = CreateRect();
+ EXPECT_FALSE(r1.Equals(r2));
+ EXPECT_FALSE(r2.Equals(r1));
+}
+
+TEST_F(EqualsTest, EqualsStruct) {
+ RectPtr r1(CreateRect());
+ RectPtr r2(r1.Clone());
+ EXPECT_TRUE(r1.Equals(r2));
+ r2->y = 1;
+ EXPECT_FALSE(r1.Equals(r2));
+ r2.reset();
+ EXPECT_FALSE(r1.Equals(r2));
+}
+
+TEST_F(EqualsTest, EqualsStructNested) {
+ RectPairPtr p1(RectPair::New());
+ p1->first = CreateRect();
+ p1->second = CreateRect();
+ RectPairPtr p2(p1.Clone());
+ EXPECT_TRUE(p1.Equals(p2));
+ p2->second->width = 0;
+ EXPECT_FALSE(p1.Equals(p2));
+ p2->second.reset();
+ EXPECT_FALSE(p1.Equals(p2));
+}
+
+TEST_F(EqualsTest, EqualsArray) {
+ NamedRegionPtr n1(NamedRegion::New());
+ n1->name = "n1";
+ n1->rects.push_back(CreateRect());
+ NamedRegionPtr n2(n1.Clone());
+ EXPECT_TRUE(n1.Equals(n2));
+
+ n2->rects.reset();
+ EXPECT_FALSE(n1.Equals(n2));
+ n2->rects.resize(0);
+ EXPECT_FALSE(n1.Equals(n2));
+
+ n2->rects.push_back(CreateRect());
+ n2->rects.push_back(CreateRect());
+ EXPECT_FALSE(n1.Equals(n2));
+
+ n2->rects.resize(1);
+ n2->rects[0]->width = 0;
+ EXPECT_FALSE(n1.Equals(n2));
+
+ n2->rects[0] = CreateRect();
+ EXPECT_TRUE(n1.Equals(n2));
+}
+
+TEST_F(EqualsTest, EqualsMap) {
+ auto n1(NamedRegion::New());
+ n1->name = "foo";
+ n1->rects.push_back(CreateRect());
+
+ Map<std::string, NamedRegionPtr> m1;
+ m1.insert("foo", n1.Pass());
+
+ decltype(m1) m2;
+ EXPECT_FALSE(m1.Equals(m2));
+
+ m2.insert("bar", m1.at("foo").Clone());
+ EXPECT_FALSE(m1.Equals(m2));
+
+ m2 = m1.Clone();
+ m2.at("foo")->name = "monkey";
+ EXPECT_FALSE(m1.Equals(m2));
+
+ m2 = m1.Clone();
+ m2.at("foo")->rects.push_back(Rect::New());
+ EXPECT_FALSE(m1.Equals(m2));
+
+ m2.at("foo")->rects.resize(1);
+ m2.at("foo")->rects[0]->width = 1;
+ EXPECT_FALSE(m1.Equals(m2));
+
+ m2 = m1.Clone();
+ EXPECT_TRUE(m1.Equals(m2));
+}
+
+} // test
+} // mojo
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
index 21f2968..f6bea2c 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
@@ -21,9 +21,11 @@ class {{struct.name}} {
{{struct.name}}();
~{{struct.name}}();
+
{% if struct|is_cloneable_kind %}
{{struct.name}}Ptr Clone() const;
{%- endif %}
+ bool Equals(const {{struct.name}}& other) const;
{#--- Getters #}
{% for field in struct.fields %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl
index 1ba7235..cb5a5fa 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl
@@ -13,6 +13,7 @@
{{struct.name}}::~{{struct.name}}() {
}
+
{% if struct|is_cloneable_kind %}
{{struct.name}}Ptr {{struct.name}}::Clone() const {
{{struct.name}}Ptr rv(New());
@@ -26,3 +27,11 @@
return rv.Pass();
}
{% endif %}
+
+bool {{struct.name}}::Equals(const {{struct.name}}& other) const {
+{%- for field in struct.fields %}
+ if (!mojo::internal::ValueTraits<{{field.kind|cpp_wrapper_type}}>::Equals({{field.name}}, other.{{field.name}}))
+ return false;
+{%- endfor %}
+ return true;
+}