Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
6.5 KiB

  1. //===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  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.
  14. //
  15. // This file defines SetVector and SmallSetVector, which performs no allocations
  16. // if the SetVector has less than a certain number of elements.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_ADT_SETVECTOR_H
  20. #define LLVM_ADT_SETVECTOR_H
  21. #include "llvm/ADT/SmallSet.h"
  22. #include <algorithm>
  23. #include <cassert>
  24. #include <vector>
  25. namespace llvm {
  26. /// \brief A vector that has set insertion semantics.
  27. ///
  28. /// This adapter class provides a way to keep a set of things that also has the
  29. /// property of a deterministic iteration order. The order of iteration is the
  30. /// order of insertion.
  31. template <typename T, typename Vector = std::vector<T>,
  32. typename Set = SmallSet<T, 16> >
  33. class SetVector {
  34. public:
  35. typedef T value_type;
  36. typedef T key_type;
  37. typedef T& reference;
  38. typedef const T& const_reference;
  39. typedef Set set_type;
  40. typedef Vector vector_type;
  41. typedef typename vector_type::const_iterator iterator;
  42. typedef typename vector_type::const_iterator const_iterator;
  43. typedef typename vector_type::size_type size_type;
  44. /// \brief Construct an empty SetVector
  45. SetVector() {}
  46. /// \brief Initialize a SetVector with a range of elements
  47. template<typename It>
  48. SetVector(It Start, It End) {
  49. insert(Start, End);
  50. }
  51. /// \brief Determine if the SetVector is empty or not.
  52. bool empty() const {
  53. return vector_.empty();
  54. }
  55. /// \brief Determine the number of elements in the SetVector.
  56. size_type size() const {
  57. return vector_.size();
  58. }
  59. /// \brief Get an iterator to the beginning of the SetVector.
  60. iterator begin() {
  61. return vector_.begin();
  62. }
  63. /// \brief Get a const_iterator to the beginning of the SetVector.
  64. const_iterator begin() const {
  65. return vector_.begin();
  66. }
  67. /// \brief Get an iterator to the end of the SetVector.
  68. iterator end() {
  69. return vector_.end();
  70. }
  71. /// \brief Get a const_iterator to the end of the SetVector.
  72. const_iterator end() const {
  73. return vector_.end();
  74. }
  75. /// \brief Return the last element of the SetVector.
  76. const T &back() const {
  77. assert(!empty() && "Cannot call back() on empty SetVector!");
  78. return vector_.back();
  79. }
  80. /// \brief Index into the SetVector.
  81. const_reference operator[](size_type n) const {
  82. assert(n < vector_.size() && "SetVector access out of range!");
  83. return vector_[n];
  84. }
  85. /// \brief Insert a new element into the SetVector.
  86. /// \returns true iff the element was inserted into the SetVector.
  87. bool insert(const value_type &X) {
  88. bool result = set_.insert(X);
  89. if (result)
  90. vector_.push_back(X);
  91. return result;
  92. }
  93. /// \brief Insert a range of elements into the SetVector.
  94. template<typename It>
  95. void insert(It Start, It End) {
  96. for (; Start != End; ++Start)
  97. if (set_.insert(*Start))
  98. vector_.push_back(*Start);
  99. }
  100. /// \brief Remove an item from the set vector.
  101. bool remove(const value_type& X) {
  102. if (set_.erase(X)) {
  103. typename vector_type::iterator I =
  104. std::find(vector_.begin(), vector_.end(), X);
  105. assert(I != vector_.end() && "Corrupted SetVector instances!");
  106. vector_.erase(I);
  107. return true;
  108. }
  109. return false;
  110. }
  111. /// \brief Remove items from the set vector based on a predicate function.
  112. ///
  113. /// This is intended to be equivalent to the following code, if we could
  114. /// write it:
  115. ///
  116. /// \code
  117. /// V.erase(std::remove_if(V.begin(), V.end(), P), V.end());
  118. /// \endcode
  119. ///
  120. /// However, SetVector doesn't expose non-const iterators, making any
  121. /// algorithm like remove_if impossible to use.
  122. ///
  123. /// \returns true if any element is removed.
  124. template <typename UnaryPredicate>
  125. bool remove_if(UnaryPredicate P) {
  126. typename vector_type::iterator I
  127. = std::remove_if(vector_.begin(), vector_.end(),
  128. TestAndEraseFromSet<UnaryPredicate>(P, set_));
  129. if (I == vector_.end())
  130. return false;
  131. vector_.erase(I, vector_.end());
  132. return true;
  133. }
  134. /// \brief Count the number of elements of a given key in the SetVector.
  135. /// \returns 0 if the element is not in the SetVector, 1 if it is.
  136. size_type count(const key_type &key) const {
  137. return set_.count(key);
  138. }
  139. /// \brief Completely clear the SetVector
  140. void clear() {
  141. set_.clear();
  142. vector_.clear();
  143. }
  144. /// \brief Remove the last element of the SetVector.
  145. void pop_back() {
  146. assert(!empty() && "Cannot remove an element from an empty SetVector!");
  147. set_.erase(back());
  148. vector_.pop_back();
  149. }
  150. T pop_back_val() {
  151. T Ret = back();
  152. pop_back();
  153. return Ret;
  154. }
  155. bool operator==(const SetVector &that) const {
  156. return vector_ == that.vector_;
  157. }
  158. bool operator!=(const SetVector &that) const {
  159. return vector_ != that.vector_;
  160. }
  161. private:
  162. /// \brief A wrapper predicate designed for use with std::remove_if.
  163. ///
  164. /// This predicate wraps a predicate suitable for use with std::remove_if to
  165. /// call set_.erase(x) on each element which is slated for removal.
  166. template <typename UnaryPredicate>
  167. class TestAndEraseFromSet {
  168. UnaryPredicate P;
  169. set_type &set_;
  170. public:
  171. typedef typename UnaryPredicate::argument_type argument_type;
  172. TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {}
  173. bool operator()(argument_type Arg) {
  174. if (P(Arg)) {
  175. set_.erase(Arg);
  176. return true;
  177. }
  178. return false;
  179. }
  180. };
  181. set_type set_; ///< The set.
  182. vector_type vector_; ///< The vector.
  183. };
  184. /// \brief A SetVector that performs no allocations if smaller than
  185. /// a certain size.
  186. template <typename T, unsigned N>
  187. class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
  188. public:
  189. SmallSetVector() {}
  190. /// \brief Initialize a SmallSetVector with a range of elements
  191. template<typename It>
  192. SmallSetVector(It Start, It End) {
  193. this->insert(Start, End);
  194. }
  195. };
  196. } // End llvm namespace
  197. // vim: sw=2 ai
  198. #endif