From 44d599832cce2975fbe3f6a5f0b7ef5f36d53faf Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 11 Feb 2013 10:49:47 +0000 Subject: [PATCH] Core: SortedIndex git-svn-id: svn://ultimatepp.org/upp/trunk@5791 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/InVector.h | 60 ++++++++++++++++++++++++++++++++++++++++ uppsrc/Core/InVector.hpp | 37 +++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/uppsrc/Core/InVector.h b/uppsrc/Core/InVector.h index 1717b90a4..d6faf6b66 100644 --- a/uppsrc/Core/InVector.h +++ b/uppsrc/Core/InVector.h @@ -109,6 +109,8 @@ public: InVector(const InVector& v, int); void Swap(InVector& b); + + friend void Swap(InVector& a, InVector& b) { a.Swap(b); } STL_VECTOR_COMPATIBILITY(InVector) @@ -301,6 +303,8 @@ public: void Swap(InArray& b) { iv.Swap(b.iv); } + friend void Swap(InArray& a, InArray& b) { a.Swap(b); } + STL_VECTOR_COMPATIBILITY(InArray) #ifdef _DEBUG @@ -372,6 +376,62 @@ public: const T& operator[](int i) const { Iterator h = *this; h += i; return *h; } }; +template > +class SortedIndex : MoveableAndDeepCopyOption< SortedIndex >{ + InVector iv; + Less less; + +public: + int Add(const T& x) { return iv.InsertUpperBound(x, less); } + int FindAdd(const T& key); + SortedIndex& operator<<(const T& x) { Add(x); return *this; } + + int FindLowerBound(const T& x) const { return iv.FindLowerBound(x, less); } + int FindUpperBound(const T& x) const { return iv.FindUpperBound(x, less); } + + int Find(const T& x) const { return iv.Find(x, less); } + int FindNext(int i) const; + int FindLast(const T& x) const; + int FindPrev(int i) const; + + void Remove(int i) { iv.Remove(i); } + void Remove(int i, int count) { iv.Remove(i, count); } + int RemoveKey(const T& x); + + const T& operator[](int i) const { return iv[i]; } + int GetCount() const { return iv.GetCount(); } + bool IsEmpty() const { return iv.IsEmpty(); } + void Clear() { iv.Clear(); } + + void Trim(int n) { return iv.Trim(n); } + void Drop(int n = 1) { iv.Drop(n); } + const T& Top() const { return iv.Top(); } + + void Shrink() { iv.Shrink(); } + + typedef typename InVector::Iterator Iterator; + typedef typename InVector::ConstIterator ConstIterator; + + typedef T ValueType; + + ConstIterator Begin() const { return iv.Begin(); } + ConstIterator End() const { return iv.End(); } + ConstIterator GetIter(int pos) const { return iv.GetIter(pos); } + + Iterator Begin() { return iv.Begin(); } + Iterator End() { return iv.End(); } + Iterator GetIter(int pos) { return iv.GetIter(pos); } + + SortedIndex() {} + SortedIndex(const SortedIndex& s, int) : iv(s.iv, 1) {} + + void Swap(SortedIndex& a) { iv.Swap(a.iv); } + + friend void Swap(SortedIndex& a, SortedIndex& b){ a.Swap(b); } + + STL_VECTOR_COMPATIBILITY(SortedIndex) +}; + #define LLOG(x) // DLOG(x) #include "InVector.hpp" #undef LLOG diff --git a/uppsrc/Core/InVector.hpp b/uppsrc/Core/InVector.hpp index 44dffb295..2e823ebb7 100644 --- a/uppsrc/Core/InVector.hpp +++ b/uppsrc/Core/InVector.hpp @@ -720,3 +720,40 @@ InArray::InArray(const InArray& v, int) while(n--) *it++ = new T(*s++); } + +template +int SortedIndex::FindAdd(const T& key) +{ + int i = FindLowerBound(key); + if(!less(key, iv[i])) + return i; + return Add(key); +} + +template +int SortedIndex::FindNext(int i) const +{ + return i + 1 < iv.GetCount() && !less(iv[i], iv[i + 1]) ? i + 1 : -1; +} + +template +int SortedIndex::FindLast(const T& x) const +{ + int i = iv.FindUpperBound(x, less); + return i > 0 && !less(iv[i - 1], x) ? i - 1 : -1; +} + +template +int SortedIndex::FindPrev(int i) const +{ + return i > 0 && !less(iv[i - 1], iv[i]) ? i - 1 : -1; +} + +template +int SortedIndex::RemoveKey(const T& x) +{ + int l = FindLowerBound(x); + int count = FindUpperBound(x) - l; + Remove(l, count); + return count; +}