1// Copyright (c) 2012 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.
4
5#ifndef CHROME_COMMON_EXTENSIONS_VALUE_COUNTER_H_
6#define CHROME_COMMON_EXTENSIONS_VALUE_COUNTER_H_
7
8#include "base/memory/linked_ptr.h"
9
10#include <vector>
11
12namespace base {
13class Value;
14}
15
16namespace extensions {
17
18// Keeps a running count of Values, like map<Value, int>. Adding / removing
19// values increments / decrements the count associated with a given Value.
20//
21// Add() and Remove() are linear in the number of Values in the ValueCounter,
22// because there is no operator<() defined on Value, so we must iterate to find
23// whether a Value is equal to an existing one.
24class ValueCounter {
25 public:
26  ValueCounter();
27  ~ValueCounter();
28
29  // Adds |value| to the set and returns how many equal values are in the set
30  // after. Does not take ownership of |value|. In the case where a Value equal
31  // to |value| doesn't already exist in this map, this function makes a
32  // DeepCopy() of |value|.
33  int Add(const base::Value& value);
34
35  // Removes |value| from the set and returns how many equal values are in
36  // the set after.
37  int Remove(const base::Value& value);
38
39  // Same as Add() but only performs the add if the value isn't present.
40  int AddIfMissing(const base::Value& value);
41
42 private:
43  class Entry {
44   public:
45    explicit Entry(const base::Value& value);
46    ~Entry();
47
48    int Increment();
49    int Decrement();
50
51    const base::Value* value() const { return value_.get(); }
52    int count() const { return count_; }
53
54   private:
55    linked_ptr<base::Value> value_;
56    int count_;
57
58    DISALLOW_COPY_AND_ASSIGN(Entry);
59  };
60  typedef std::vector<linked_ptr<Entry> > EntryList;
61
62  int AddImpl(const base::Value& value, bool increment);
63
64  EntryList entries_;
65
66  DISALLOW_COPY_AND_ASSIGN(ValueCounter);
67};
68
69}  // namespace extensions
70
71#endif  // CHROME_COMMON_EXTENSIONS_VALUE_COUNTER_H_
72