diff options
| author | Chandler Carruth <chandlerc@gmail.com> | 2012-10-03 01:04:07 +0000 |
|---|---|---|
| committer | Chandler Carruth <chandlerc@gmail.com> | 2012-10-03 01:04:07 +0000 |
| commit | c7b2aeebb707da53075188bdf71bac6072d18127 (patch) | |
| tree | 384622903d73376756d9458e4b7aa1d2e331e9de | |
| parent | 0f6e8bb5e03428becb1f17a5b381475652aa3425 (diff) | |
| download | bcm5719-llvm-c7b2aeebb707da53075188bdf71bac6072d18127.tar.gz bcm5719-llvm-c7b2aeebb707da53075188bdf71bac6072d18127.zip | |
Third try at fixing this. ;] Go back to using std::remove_if, which has
most of the behavior we want, but wrap the predicate in one which erases
elements from the set if they pass the predicate. Oh what I wouldn't
give for a lambda here.
Let me know if the predicate wrapping is too much magic. ;]
llvm-svn: 165076
| -rw-r--r-- | llvm/include/llvm/ADT/SetVector.h | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/llvm/include/llvm/ADT/SetVector.h b/llvm/include/llvm/ADT/SetVector.h index 0ff0f46f88d..d2f7286c259 100644 --- a/llvm/include/llvm/ADT/SetVector.h +++ b/llvm/include/llvm/ADT/SetVector.h @@ -141,15 +141,12 @@ public: /// \returns true if any element is removed. template <typename UnaryPredicate> bool remove_if(UnaryPredicate P) { - typename vector_type::iterator B = std::partition(vector_.begin(), - vector_.end(), - std::not1(P)), - E = vector_.end(); - if (B == E) + typename vector_type::iterator I + = std::remove_if(vector_.begin(), vector_.end(), + TestAndEraseFromSet<UnaryPredicate>(P, set_)); + if (I == vector_.end()) return false; - for (typename vector_type::iterator I = B; I != E; ++I) - set_.erase(*I); - vector_.erase(B, E); + vector_.erase(I, vector_.end()); return true; } @@ -188,6 +185,29 @@ public: } private: + /// \brief A wrapper predicate designed for use with std::remove_if. + /// + /// This predicate wraps a predicate suitable for use with std::remove_if to + /// call set_.erase(x) on each element which is slated for removal. + template <typename UnaryPredicate> + class TestAndEraseFromSet { + UnaryPredicate P; + set_type &set_; + + public: + typedef typename UnaryPredicate::argument_type argument_type; + + TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {} + + bool operator()(argument_type Arg) { + if (P(Arg)) { + set_.erase(Arg); + return true; + } + return false; + } + }; + set_type set_; ///< The set. vector_type vector_; ///< The vector. }; |

