Add Contains(), at(), and a constructor with raw addresses to UniqueSet<T> and Unique<T>.
authortitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 13 Sep 2013 12:35:36 +0000 (12:35 +0000)
committertitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 13 Sep 2013 12:35:36 +0000 (12:35 +0000)
BUG=
R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/23872027

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16716 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/unique.h
test/cctest/test-unique.cc

index 7ae704a..38cc336 100644 (file)
@@ -64,6 +64,10 @@ class Unique V8_FINAL {
     handle_ = handle;
   }
 
+  // TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
+  Unique(Address raw_address, Handle<T> handle)
+    : raw_address_(raw_address), handle_(handle) { }
+
   // Constructor for handling automatic up casting.
   // Ex. Unique<JSFunction> can be passed when Unique<Object> is expected.
   template <class S> Unique(Unique<S> uniq) {
@@ -138,7 +142,7 @@ class UniqueSet V8_FINAL : public ZoneObject {
   }
 
   // Compare this set against another set. O(|this|).
-  bool Equals(UniqueSet<T>* that) {
+  bool Equals(UniqueSet<T>* that) const {
     if (that->size_ != this->size_) return false;
     for (int i = 0; i < this->size_; i++) {
       if (this->array_[i] != that->array_[i]) return false;
@@ -146,8 +150,17 @@ class UniqueSet V8_FINAL : public ZoneObject {
     return true;
   }
 
+  template <typename U>
+  bool Contains(Unique<U> elem) const {
+    // TODO(titzer): use binary search for larger sets.
+    for (int i = 0; i < size_; i++) {
+      if (this->array_[i] == elem) return true;
+    }
+    return false;
+  }
+
   // Check if this set is a subset of the given set. O(|this| + |that|).
-  bool IsSubset(UniqueSet<T>* that) {
+  bool IsSubset(UniqueSet<T>* that) const {
     if (that->size_ < this->size_) return false;
     int j = 0;
     for (int i = 0; i < this->size_; i++) {
@@ -163,7 +176,7 @@ class UniqueSet V8_FINAL : public ZoneObject {
 
   // Returns a new set representing the intersection of this set and the other.
   // O(|this| + |that|).
-  UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) {
+  UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) const {
     if (that->size_ == 0 || this->size_ == 0) return new(zone) UniqueSet<T>();
 
     UniqueSet<T>* out = new(zone) UniqueSet<T>();
@@ -190,7 +203,7 @@ class UniqueSet V8_FINAL : public ZoneObject {
 
   // Returns a new set representing the union of this set and the other.
   // O(|this| + |that|).
-  UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) {
+  UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) const {
     if (that->size_ == 0) return this->Copy(zone);
     if (this->size_ == 0) return that->Copy(zone);
 
@@ -222,7 +235,7 @@ class UniqueSet V8_FINAL : public ZoneObject {
   }
 
   // Makes an exact copy of this set. O(|this| + |that|).
-  UniqueSet<T>* Copy(Zone* zone) {
+  UniqueSet<T>* Copy(Zone* zone) const {
     UniqueSet<T>* copy = new(zone) UniqueSet<T>();
     copy->size_ = this->size_;
     copy->capacity_ = this->size_;
@@ -231,10 +244,15 @@ class UniqueSet V8_FINAL : public ZoneObject {
     return copy;
   }
 
-  inline int size() {
+  inline int size() const {
     return size_;
   }
 
+  inline Unique<T> at(int index) const {
+    ASSERT(index >= 0 && index < size_);
+    return array_[index];
+  }
+
  private:
   // These sets should be small, since operations are implemented with simple
   // linear algorithms. Enforce a maximum size.
index 1d26858..d482a33 100644 (file)
@@ -146,6 +146,74 @@ TEST(UniqueSet_Add) {
 }
 
 
+TEST(UniqueSet_Contains) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set = new(&zone) UniqueSet<String>();
+
+  CHECK_EQ(0, set->size());
+  set->Add(A, &zone);
+  CHECK(set->Contains(A));
+  CHECK(!set->Contains(B));
+  CHECK(!set->Contains(C));
+
+  set->Add(A, &zone);
+  CHECK(set->Contains(A));
+  CHECK(!set->Contains(B));
+  CHECK(!set->Contains(C));
+
+  set->Add(B, &zone);
+  CHECK(set->Contains(A));
+  CHECK(set->Contains(B));
+
+  set->Add(C, &zone);
+  CHECK(set->Contains(A));
+  CHECK(set->Contains(B));
+  CHECK(set->Contains(C));
+}
+
+
+TEST(UniqueSet_At) {
+  CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  HandleScope sc(isolate);
+
+  Unique<String> A(factory->InternalizeUtf8String("A"));
+  Unique<String> B(factory->InternalizeUtf8String("B"));
+  Unique<String> C(factory->InternalizeUtf8String("C"));
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set = new(&zone) UniqueSet<String>();
+
+  CHECK_EQ(0, set->size());
+  set->Add(A, &zone);
+  CHECK(A == set->at(0));
+
+  set->Add(A, &zone);
+  CHECK(A == set->at(0));
+
+  set->Add(B, &zone);
+  CHECK(A == set->at(0) || B == set->at(0));
+  CHECK(A == set->at(1) || B == set->at(1));
+
+  set->Add(C, &zone);
+  CHECK(A == set->at(0) || B == set->at(0) || C == set->at(0));
+  CHECK(A == set->at(1) || B == set->at(1) || C == set->at(1));
+  CHECK(A == set->at(2) || B == set->at(2) || C == set->at(2));
+}
+
+
 template <class T>
 static void CHECK_SETS(
     UniqueSet<T>* set1, UniqueSet<T>* set2, bool expected) {