1 //===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by Reid Spencer and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements a set that has insertion order iteration
11 // characteristics. This is useful for keeping a set of things that need to be
12 // visited later but in a deterministic order (insertion order). The interface
13 // is purposefully minimal.
15 // This file defines SetVector and SmallSetVector, which performs no allocations
16 // if the SetVector has less than a certain number of elements.
18 //===----------------------------------------------------------------------===//
20 #ifndef LLVM_ADT_SETVECTOR_H
21 #define LLVM_ADT_SETVECTOR_H
23 #include "llvm/ADT/SmallSet.h"
30 /// This adapter class provides a way to keep a set of things that also has the
31 /// property of a deterministic iteration order. The order of iteration is the
32 /// order of insertion.
33 /// @brief A vector that has set insertion semantics.
34 template <typename T, typename Vector = std::vector<T>,
35 typename Set = SmallSet<T, 16> >
41 typedef const T& const_reference;
43 typedef Vector vector_type;
44 typedef typename vector_type::const_iterator iterator;
45 typedef typename vector_type::const_iterator const_iterator;
46 typedef typename vector_type::size_type size_type;
48 /// @brief Construct an empty SetVector
51 /// @brief Initialize a SetVector with a range of elements
53 SetVector(It Start, It End) {
57 /// @brief Determine if the SetVector is empty or not.
59 return vector_.empty();
62 /// @brief Determine the number of elements in the SetVector.
63 size_type size() const {
64 return vector_.size();
67 /// @brief Get an iterator to the beginning of the SetVector.
69 return vector_.begin();
72 /// @brief Get a const_iterator to the beginning of the SetVector.
73 const_iterator begin() const {
74 return vector_.begin();
77 /// @brief Get an iterator to the end of the SetVector.
82 /// @brief Get a const_iterator to the end of the SetVector.
83 const_iterator end() const {
87 /// @brief Return the last element of the SetVector.
88 const T &back() const {
89 assert(!empty() && "Cannot call back() on empty SetVector!");
90 return vector_.back();
93 /// @brief Index into the SetVector.
94 const_reference operator[](size_type n) const {
95 assert(n < vector_.size() && "SetVector access out of range!");
99 /// @returns true iff the element was inserted into the SetVector.
100 /// @brief Insert a new element into the SetVector.
101 bool insert(const value_type &X) {
102 bool result = set_.insert(X);
104 vector_.push_back(X);
108 /// @brief Insert a range of elements into the SetVector.
109 template<typename It>
110 void insert(It Start, It End) {
111 for (; Start != End; ++Start)
112 if (set_.insert(*Start))
113 vector_.push_back(*Start);
116 /// @brief Remove an item from the set vector.
117 void remove(const value_type& X) {
119 typename vector_type::iterator I =
120 std::find(vector_.begin(), vector_.end(), X);
121 assert(I != vector_.end() && "Corrupted SetVector instances!");
127 /// @returns 0 if the element is not in the SetVector, 1 if it is.
128 /// @brief Count the number of elements of a given key in the SetVector.
129 size_type count(const key_type &key) const {
130 return set_.count(key);
133 /// @brief Completely clear the SetVector
139 /// @brief Remove the last element of the SetVector.
141 assert(!empty() && "Cannot remove an element from an empty SetVector!");
147 set_type set_; ///< The set.
148 vector_type vector_; ///< The vector.
151 /// SmallSetVector - A SetVector that performs no allocations if smaller than
153 template <typename T, unsigned N>
154 class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
158 /// @brief Initialize a SmallSetVector with a range of elements
159 template<typename It>
160 SmallSetVector(It Start, It End) {
161 this->insert(Start, End);
165 } // End llvm namespace