blob: fda4e121f5c43c32efc5838ad12987d78e87db1c [file] [log] [blame]
// Copyright (c) 2013 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.
#ifndef TOOLS_GN_ORDERED_SET_H_
#define TOOLS_GN_ORDERED_SET_H_
#include <stddef.h>
#include <set>
// An ordered set of items. Only appending is supported. Iteration is designed
// to be by index.
template <typename T>
class OrderedSet {
private:
using set_type = std::set<T>;
using set_iterator = typename set_type::const_iterator;
using vector_type = std::vector<set_iterator>;
public:
static const size_t npos = static_cast<size_t>(-1);
OrderedSet() {}
~OrderedSet() {}
const T& operator[](size_t index) const { return *ordering_[index]; }
size_t size() const { return ordering_.size(); }
bool empty() const { return ordering_.empty(); }
bool has_item(const T& t) const { return set_.find(t) != set_.end(); }
// Returns true if the item was inserted. False if it was already in the
// set.
bool push_back(const T& t) {
std::pair<set_iterator, bool> result = set_.insert(t);
if (result.second)
ordering_.push_back(result.first);
return true;
}
// Appends a range of items, skipping ones that already exist.
template <class InputIterator>
void append(const InputIterator& insert_begin,
const InputIterator& insert_end) {
for (InputIterator i = insert_begin; i != insert_end; ++i) {
const T& t = *i;
push_back(t);
}
}
// Appends all items from the given other set.
void append(const OrderedSet<T>& other) {
for (size_t i = 0; i < other.size(); i++)
push_back(other[i]);
}
private:
set_type set_;
vector_type ordering_;
};
#endif // TOOLS_GN_ORDERED_SET_H_