1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef EXTENSIONS_COMMON_PERMISSIONS_BASE_SET_OPERATORS_H_
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define EXTENSIONS_COMMON_PERMISSIONS_BASE_SET_OPERATORS_H_
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <iterator>
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <map>
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/linked_ptr.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/template_util.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions {
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Traits for template paramater of |BaseSetOperators<T>|. Specializations
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// should define |ElementType| for the type of elements to store in the set,
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// and |EmementIDType| for the type of element identifiers.
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template <typename T>
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct BaseSetOperatorsTraits {};
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Set operations shared by |APIPermissionSet| and |ManifestPermissionSet|.
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TODO(rpaquay): It would be nice to remove the need for the sub-classes and
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// instead directly use this class where needed.
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template <typename T>
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class BaseSetOperators {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef typename BaseSetOperatorsTraits<T>::ElementType ElementType;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef typename BaseSetOperatorsTraits<T>::ElementIDType ElementIDType;
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef std::map<ElementIDType, linked_ptr<ElementType> > Map;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  class const_iterator :
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public std::iterator<std::input_iterator_tag, const ElementType*> {
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   public:
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator(const typename Map::const_iterator& it) : it_(it) {}
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator(const const_iterator& ids_it) : it_(ids_it.it_) {}
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator& operator++() {
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ++it_;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return *this;
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator operator++(int) {
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const_iterator tmp(it_++);
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return tmp;
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool operator==(const const_iterator& rhs) const {
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return it_ == rhs.it_;
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool operator!=(const const_iterator& rhs) const {
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return it_ != rhs.it_;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const ElementType* operator*() const {
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return it_->second.get();
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const ElementType* operator->() const {
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return it_->second.get();
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   private:
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    typename Map::const_iterator it_;
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  BaseSetOperators() {
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Ensure |T| is convertible to us, so we can safely downcast when calling
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // methods that must exist in |T|.
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    COMPILE_ASSERT((base::is_convertible<T*, BaseSetOperators<T>*>::value),
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   U_ptr_must_implicitly_convert_to_T_ptr);
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  BaseSetOperators(const T& set) {
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this->operator=(set);
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ~BaseSetOperators() {}
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  T& operator=(const T& rhs) {
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return Assign(rhs);
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool operator==(const T& rhs) const {
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return Equal(rhs);
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool operator!=(const T& rhs) const {
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return !operator==(rhs);
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  T& Assign(const T& rhs) {
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it = rhs.begin();
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const const_iterator end = rhs.end();
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (it != end) {
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      insert(it->Clone());
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ++it;
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return *static_cast<T*>(this);
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool Equal(const T& rhs) const {
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it = begin();
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator rhs_it = rhs.begin();
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it_end = end();
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator rhs_it_end = rhs.end();
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (it != it_end && rhs_it != rhs_it_end) {
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (it->id() > rhs_it->id())
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return false;
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      else if (it->id() < rhs_it->id())
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return false;
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      else if (!it->Equal(*rhs_it))
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return false;
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ++it;
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ++rhs_it;
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return it == it_end && rhs_it == rhs_it_end;
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool Contains(const T& rhs) const {
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it1 = begin();
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it2 = rhs.begin();
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator end1 = end();
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator end2 = rhs.end();
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (it1 != end1 && it2 != end2) {
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (it1->id() > it2->id()) {
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return false;
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else if (it1->id() < it2->id()) {
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it1;
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else {
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          if (!it1->Contains(*it2))
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            return false;
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it1;
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it2;
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return it2 == end2;
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static void Difference(const T& set1, const T& set2, T* set3) {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CHECK(set3);
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    set3->clear();
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it1 = set1.begin();
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it2 = set2.begin();
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const const_iterator end1 = set1.end();
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const const_iterator end2 = set2.end();
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (it1 != end1 && it2 != end2) {
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (it1->id() < it2->id()) {
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        set3->insert(it1->Clone());
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it1;
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else if (it1->id() > it2->id()) {
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it2;
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else {
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ElementType* p = it1->Diff(*it2);
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (p)
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          set3->insert(p);
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it1;
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it2;
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (it1 != end1) {
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      set3->insert(it1->Clone());
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ++it1;
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static void Intersection(const T& set1, const T& set2, T* set3) {
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(set3);
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    set3->clear();
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it1 = set1.begin();
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it2 = set2.begin();
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const const_iterator end1 = set1.end();
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const const_iterator end2 = set2.end();
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (it1 != end1 && it2 != end2) {
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (it1->id() < it2->id()) {
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it1;
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else if (it1->id() > it2->id()) {
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it2;
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else {
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ElementType* p = it1->Intersect(*it2);
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (p)
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          set3->insert(p);
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it1;
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it2;
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static void Union(const T& set1, const T& set2, T* set3) {
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(set3);
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    set3->clear();
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it1 = set1.begin();
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const_iterator it2 = set2.begin();
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const const_iterator end1 = set1.end();
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const const_iterator end2 = set2.end();
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (true) {
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (it1 == end1) {
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        while (it2 != end2) {
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          set3->insert(it2->Clone());
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          ++it2;
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        break;
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (it2 == end2) {
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        while (it1 != end1) {
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          set3->insert(it1->Clone());
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          ++it1;
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        break;
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (it1->id() < it2->id()) {
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        set3->insert(it1->Clone());
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it1;
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else if (it1->id() > it2->id()) {
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        set3->insert(it2->Clone());
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it2;
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else {
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        set3->insert(it1->Union(*it2));
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it1;
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++it2;
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const_iterator begin() const {
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return const_iterator(map().begin());
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const_iterator end() const {
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map().end();
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const_iterator find(ElementIDType id) const {
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map().find(id);
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t count(ElementIDType id) const {
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map().count(id);
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool empty() const {
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map().empty();
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t erase(ElementIDType id) {
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map().erase(id);
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Take ownership and insert |item| into the set.
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void insert(ElementType* item) {
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    map_[item->id()].reset(item);
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t size() const {
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map().size();
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const Map& map() const {
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map_;
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Map& map() {
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map_;
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void clear() {
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    map_.clear();
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Map map_;
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace extensions
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // EXTENSIONS_COMMON_PERMISSIONS_BASE_SET_OPERATORS_H_
289