1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CONTENT_BROWSER_INDEXED_DB_LIST_SET_H_
6 #define CONTENT_BROWSER_INDEXED_DB_LIST_SET_H_
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
16 // A container class that provides fast containment test (like a set)
17 // but maintains insertion order for iteration (like list).
19 // Member types of value (primitives and objects by value), raw pointers
20 // and scoped_refptr<> are supported.
26 list_set(const list_set
<T
>& other
) : list_(other
.list_
), set_(other
.set_
) {}
27 list_set
& operator=(const list_set
<T
>& other
) {
33 void insert(const T
& elem
) {
34 if (set_
.find(elem
) != set_
.end())
37 list_
.push_back(elem
);
40 void erase(const T
& elem
) {
41 if (set_
.find(elem
) == set_
.end())
44 typename
std::list
<T
>::iterator it
=
45 std::find(list_
.begin(), list_
.end(), elem
);
46 DCHECK(it
!= list_
.end());
50 size_t count(const T
& elem
) const {
51 return set_
.find(elem
) == set_
.end() ? 0 : 1;
55 DCHECK_EQ(list_
.size(), set_
.size());
60 DCHECK_EQ(list_
.empty(), set_
.empty());
68 typedef iterator self_type
;
72 typedef std::bidirectional_iterator_tag iterator_category
;
73 typedef std::ptrdiff_t difference_type
;
75 explicit inline iterator(typename
std::list
<T
>::iterator it
) : it_(it
) {}
76 inline self_type
& operator++() {
80 inline self_type
operator++(int /*ignored*/) {
81 self_type
result(*this);
85 inline self_type
& operator--() {
89 inline self_type
operator--(int /*ignored*/) {
90 self_type
result(*this);
94 inline value_type
& operator*() { return *it_
; }
95 inline value_type
* operator->() { return &(*it_
); }
96 inline bool operator==(const iterator
& rhs
) const { return it_
== rhs
.it_
; }
97 inline bool operator!=(const iterator
& rhs
) const { return it_
!= rhs
.it_
; }
99 inline operator const_iterator() const { return const_iterator(it_
); }
102 typename
std::list
<T
>::iterator it_
;
105 class const_iterator
{
107 typedef const_iterator self_type
;
108 typedef T value_type
;
109 typedef T
& reference
;
111 typedef std::bidirectional_iterator_tag iterator_category
;
112 typedef std::ptrdiff_t difference_type
;
114 explicit inline const_iterator(typename
std::list
<T
>::const_iterator it
)
116 inline self_type
& operator++() {
120 inline self_type
operator++(int ignored
) {
121 self_type
result(*this);
125 inline self_type
& operator--() {
129 inline self_type
operator--(int ignored
) {
130 self_type
result(*this);
134 inline const value_type
& operator*() { return *it_
; }
135 inline const value_type
* operator->() { return &(*it_
); }
136 inline bool operator==(const const_iterator
& rhs
) const {
137 return it_
== rhs
.it_
;
139 inline bool operator!=(const const_iterator
& rhs
) const {
140 return it_
!= rhs
.it_
;
144 typename
std::list
<T
>::const_iterator it_
;
147 iterator
begin() { return iterator(list_
.begin()); }
148 iterator
end() { return iterator(list_
.end()); }
149 const_iterator
begin() const { return const_iterator(list_
.begin()); }
150 const_iterator
end() const { return const_iterator(list_
.end()); }
157 // Prevent instantiation of list_set<scoped_ptr<T>> as the current
158 // implementation would fail.
159 // TODO(jsbell): Support scoped_ptr through specialization.
160 template <typename T
>
161 class list_set
<scoped_ptr
<T
> >;
163 #endif // CONTENT_BROWSER_INDEXED_DB_LIST_SET_H_