17 #ifndef INC_KY_Kernel_Range_H
18 #define INC_KY_Kernel_Range_H
34 enum BoundsType { Min, Max };
36 Range():Index(0), Length(0) {}
37 explicit Range(UPInt count) { SetRange(count); }
38 Range(SPInt index, UPInt length) { SetRange(index, length); }
39 Range(
const Range &r) { SetRange(r); }
40 Range(BoundsType bt) { SetRange(bt); }
44 void SetRange(UPInt count) { Index = 0; Length = count; }
46 void SetRange(SPInt index, UPInt length)
51 void SetRange(
const Range &r) { SetRange(r.Index, r.Length); }
52 void SetRange(BoundsType bt)
56 case Min: SetRange(0, 0);
break;
57 case Max: SetRange(0, KY_MAX_UPINT);
break;
63 SPInt MoveIndex(SPInt delta)
65 delta = (delta > SPInt(Length)) ? SPInt(Length) : delta;
67 Length = (UPInt)(Length - delta);
71 SPInt MoveRange(SPInt delta)
78 UPInt ShrinkRange(UPInt lengthDelta)
80 if (lengthDelta > Length)
83 Length -= lengthDelta;
86 UPInt ExpandRange(UPInt lengthDelta)
88 Length += lengthDelta;
93 SPInt NextIndex()
const {
return Index + Length; }
95 SPInt LastIndex()
const {
return Index + Length - 1; }
96 SPInt FirstIndex()
const {
return Index; }
97 bool IsEmpty()
const {
return Length == 0; }
100 void Clear() { SetRange(Min); }
105 bool Contains(SPInt index)
const {
return (index >= Index && index <= LastIndex()); }
107 bool Contains(
const Range &r)
const {
return (r.Index >= Index && r.LastIndex() <= LastIndex()); }
110 bool Intersects(
const Range &r)
const {
return (r.LastIndex() >= FirstIndex()) && (LastIndex() >= r.FirstIndex()); }
112 int CompareTo(SPInt index)
const
117 return int(Index - index);
119 return int(LastIndex() - index);
124 class RangePrimData :
public Range
128 RangePrimData():Range() {}
131 RangePrimData(SPInt index, UPInt length,
const T data):Range(index, length),Data(data) {}
133 T GetData()
const {
return Data; }
134 void SetData(T data) { Data = data; }
135 bool IsDataEqual(T data)
const {
return Data == data; }
139 class RangeData :
public Range
143 RangeData():Range() {}
144 RangeData(SPInt index, UPInt length,
const T& data):Range(index, length),Data(data) {}
146 T& GetData() {
return Data; }
147 const T& GetData()
const {
return Data; }
148 T& operator->() {
return Data; }
149 const T& operator->()
const {
return Data; }
151 const T&
operator*()
const {
return Data; }
152 void SetData(
const T& data) { Data = data; }
153 bool IsDataEqual(
const T& data)
const {
return Data == data; }
156 template <
class T,
class Array = Kaim::Array<RangeData<T> > >
159 UPInt FindRangeIndex(SPInt index)
const;
160 UPInt FindNearestRangeIndex(SPInt index)
const;
162 typedef RangeData<T> TypedRangeData;
163 typedef Array RangeArrayType;
165 RangeArrayType Ranges;
168 TypedRangeData& operator[](UPInt position) {
return Ranges[position]; }
169 const TypedRangeData& operator[](UPInt position)
const {
return Ranges[position]; }
170 UPInt Count()
const {
return Ranges.GetSize(); }
172 void SetRange(SPInt index, UPInt length,
const T& data)
174 SetRange(TypedRangeData(index, length, data));
176 void SetRange(
const TypedRangeData& range);
178 void ClearRange(SPInt index, UPInt length);
180 TypedRangeData& Append(UPInt length,
const T& data);
181 void InsertRange(SPInt startPos, UPInt length,
const T& pdata);
182 void ExpandRange(SPInt startPos, UPInt length);
184 void RemoveRange(SPInt startPos, UPInt length);
185 void RemoveAll() { Ranges.Resize(0); }
189 friend class RangeDataArray<T, Array>;
190 RangeDataArray<T, Array>* pArray;
193 explicit Iterator(RangeDataArray<T, Array>& arr) : pArray(&arr), Index(0) {}
194 Iterator(RangeDataArray<T, Array>& arr,
bool) : pArray(&arr), Index(pArray->Count() - 1) {}
197 void InsertBefore(
const TypedRangeData& range);
198 void InsertAfter(
const TypedRangeData& range);
203 Iterator(
const Iterator& it) : pArray(it.pArray), Index(it.Index) {}
204 Iterator():pArray(0), Index(-1) {}
206 Iterator& operator++()
208 if (Index < (SPInt)pArray->Count())
212 Iterator operator++(
int)
215 if (Index < (SPInt)pArray->Count())
219 Iterator& operator--()
225 Iterator operator--(
int)
232 TypedRangeData&
operator*() {
return (*pArray)[Index]; }
233 TypedRangeData* operator->() {
return &(*pArray)[Index]; }
234 TypedRangeData* GetPtr() {
return (Index < (SPInt)pArray->Count()) ? &(*pArray)[Index] : NULL; }
235 bool operator==(
const Iterator& it)
const
237 return (pArray == it.pArray && Index == it.Index);
239 Iterator operator+(SPInt delta)
const
242 if (Index + delta < 0)
244 else if (UPInt(Index + delta) >= pArray->Count())
245 it.Index = pArray->Count() - 1;
251 bool IsFinished()
const {
return Index < 0 || UPInt(Index) >= pArray->Count(); }
253 Iterator Begin() {
return Iterator(*
this); }
254 Iterator Last() {
return Iterator(*
this,
true); }
255 Iterator GetIteratorAt(SPInt index);
256 Iterator GetIteratorByNearestIndex(SPInt index);
260 friend class RangeDataArray<T, Array>;
261 const RangeDataArray<T, Array>* pArray;
264 explicit ConstIterator(
const RangeDataArray<T, Array>& arr) : pArray(&arr), Index(0) {}
265 ConstIterator(
const RangeDataArray<T, Array>& arr,
bool) : pArray(&arr), Index(pArray->Count() - 1) {}
268 ConstIterator(
const ConstIterator& it) : pArray(it.pArray), Index(it.Index) {}
269 ConstIterator():pArray(0), Index(-1) {}
271 ConstIterator& operator++()
273 if (Index < (SPInt)pArray->Count())
277 ConstIterator operator++(
int)
279 ConstIterator it(*
this);
280 if (Index < (SPInt)pArray->Count())
284 ConstIterator& operator--()
290 ConstIterator operator--(
int)
292 ConstIterator it(*
this);
297 const TypedRangeData&
operator*()
const {
return (*pArray)[Index]; }
298 const TypedRangeData* operator->()
const {
return &(*pArray)[Index]; }
299 const TypedRangeData* GetPtr()
const {
return (Index < (SPInt)pArray->Count()) ? &(*pArray)[Index] : NULL; }
300 bool operator==(
const ConstIterator& it)
const
302 return (pArray == it.pArray && Index == it.Index);
304 ConstIterator operator+(SPInt delta)
const
306 ConstIterator it(*
this);
307 if (Index + delta < 0)
309 else if (UPInt(Index + delta) >= pArray->Count())
310 it.Index = pArray->Count() - 1;
316 bool IsFinished()
const {
return Index < 0 || UPInt(Index) >= pArray->Count(); }
318 ConstIterator Begin()
const {
return ConstIterator(*
this); }
319 ConstIterator Last()
const {
return ConstIterator(*
this,
true); }
320 ConstIterator GetIteratorAt(SPInt index)
const;
321 ConstIterator GetIteratorByNearestIndex(SPInt index)
const;
323 class ConstPositionIterator
325 friend class RangeDataArray<T, Array>;
327 const TypedRangeData* pCurrentRange;
331 ConstPositionIterator(
const RangeDataArray<T, Array>& rangeArray) : Iter(rangeArray.Begin())
333 if (!Iter.IsFinished())
335 CurrentPos = Iter->FirstIndex();
336 pCurrentRange = Iter.GetPtr();
337 EndPos = rangeArray[rangeArray.Count() - 1].LastIndex();
342 pCurrentRange = NULL;
346 ConstPositionIterator(
const RangeDataArray<T, Array>& rangeArray, SPInt startIndex, UPInt length) :
347 Iter(rangeArray.GetIteratorByNearestIndex(startIndex)), CurrentPos(startIndex),
348 EndPos(CurrentPos + length - 1)
350 if (!Iter.IsFinished())
352 pCurrentRange = Iter.GetPtr();
356 pCurrentRange = NULL;
360 bool IsFinished()
const {
return CurrentPos > EndPos; }
362 const TypedRangeData*
operator*()
const {
return GetPtr(); }
363 const TypedRangeData* operator->()
const
367 const TypedRangeData* GetPtr()
const
371 if (pCurrentRange->Contains(CurrentPos))
372 return pCurrentRange;
377 ConstPositionIterator& operator++()
379 if (CurrentPos <= EndPos)
381 SPInt oldPos = CurrentPos++;
384 if (pCurrentRange->Contains(oldPos) && !pCurrentRange->Contains(CurrentPos))
387 if (!Iter.IsFinished())
388 pCurrentRange = Iter.GetPtr();
390 pCurrentRange = NULL;
396 ConstPositionIterator operator++(
int)
398 ConstIterator it(*
this);
413 #ifdef KY_CONFIG_DEBUG
414 void CheckIntegrity();
416 void CheckIntegrity() {}
423 template <
class T,
class Array>
424 void RangeDataArray<T, Array>::Iterator::InsertBefore(
const TypedRangeData& range)
426 pArray->Ranges.InsertAt(Index, range);
429 template <
class T,
class Array>
430 void RangeDataArray<T, Array>::Iterator::InsertAfter(
const TypedRangeData& range)
432 pArray->Ranges.InsertAt(Index+1, range);
436 template <
class T,
class Array>
437 void RangeDataArray<T, Array>::Iterator::Remove()
439 if (Index >= 0 && UPInt(Index) < pArray->Count())
440 pArray->Ranges.RemoveAt(Index);
443 template <
class T,
class Array>
444 UPInt RangeDataArray<T, Array>::FindRangeIndex(SPInt index)
const
447 const UPInt count = Count();
450 UPInt upper = count - 1;
452 while (lower < upper && upper != (UPInt)-1)
454 UPInt middle = (lower + upper)/2;
455 int cmpRes = Ranges[middle].CompareTo(index);
465 if (lower == upper && Ranges[lower].CompareTo(index) == 0)
471 template <
class T,
class Array>
472 typename RangeDataArray<T, Array>::Iterator RangeDataArray<T, Array>::GetIteratorAt(SPInt index)
474 UPInt rangeIndex = FindRangeIndex(index);
475 if (rangeIndex != KY_MAX_UPINT)
476 return Begin() + rangeIndex;
480 template <
class T,
class Array>
481 typename RangeDataArray<T, Array>::ConstIterator RangeDataArray<T, Array>::GetIteratorAt(SPInt index)
const
483 UPInt rangeIndex = FindRangeIndex(index);
484 if (rangeIndex != KY_MAX_UPINT)
485 return Begin() + rangeIndex;
486 return ConstIterator();
489 template <
class T,
class Array>
490 UPInt RangeDataArray<T, Array>::FindNearestRangeIndex(SPInt index)
const
493 const UPInt count = Count();
500 UPInt upper = count - 1;
503 while (lower < upper && upper != (UPInt)-1) {
504 UPInt middle = (lower + upper)/2;
505 int cmpRes = Ranges[middle].CompareTo(index);
518 if (lower == upper && Ranges[lower].CompareTo(index) == 0)
520 while(lowest < upper && Ranges[lowest + 1].CompareTo(index) < 0)
525 template <
class T,
class Array>
526 typename RangeDataArray<T, Array>::Iterator RangeDataArray<T, Array>::GetIteratorByNearestIndex(SPInt index)
528 return Begin() + FindNearestRangeIndex(index);
531 template <
class T,
class Array>
532 typename RangeDataArray<T, Array>::ConstIterator RangeDataArray<T, Array>::GetIteratorByNearestIndex(SPInt index)
const
534 return Begin() + FindNearestRangeIndex(index);
537 template <
class T,
class Array>
538 void RangeDataArray<T, Array>::SetRange(
const TypedRangeData& range)
542 Iterator it = GetIteratorByNearestIndex(range.Index);
543 Iterator insertionPoint;
546 if (it->Contains(range))
549 if (it->Index == range.Index)
555 it->MoveIndex(range.Length);
562 it.InsertBefore(range);
566 else if (it->NextIndex() > range.NextIndex())
573 TypedRangeData r = *it;
574 SPInt endIndex = it->NextIndex();
575 it->ShrinkRange(endIndex - range.Index);
576 r.MoveIndex(it->Length + range.Length);
577 it.InsertAfter(range);
589 it->ShrinkRange(range.Length);
590 insertionPoint = ++it;
591 it.InsertBefore(range);
595 else if (it->Contains(range.Index))
601 it->ShrinkRange(it->NextIndex() - range.Index);
602 insertionPoint = ++it;
603 it.InsertBefore(range);
617 if (it->CompareTo(range.Index) > 0)
619 it.InsertBefore(range);
624 it.InsertAfter(range);
625 insertionPoint = ++it;
630 while(!it.IsFinished() && range.Contains(*it))
635 if (!it.IsFinished() && it->Contains(range.NextIndex() - 1))
640 it->MoveIndex(range.NextIndex() - it->Index);
643 Iterator firstRangeIt = insertionPoint;
646 if (!firstRangeIt.IsFinished())
648 if (firstRangeIt->IsEmpty())
649 firstRangeIt.Remove();
650 else if (firstRangeIt->NextIndex() == range.Index && firstRangeIt->IsDataEqual(insertionPoint->GetData()))
653 firstRangeIt->ExpandRange(range.Length);
654 insertionPoint.Remove();
655 insertionPoint = firstRangeIt;
659 Iterator nextIt = insertionPoint;
661 if (!nextIt.IsFinished())
663 if (nextIt->IsEmpty())
665 else if (insertionPoint->NextIndex() == nextIt->Index && insertionPoint->IsDataEqual(nextIt->GetData()))
668 insertionPoint->ExpandRange(nextIt->Length);
675 Begin().InsertBefore(range);
680 template <
class T,
class Array>
681 typename RangeDataArray<T, Array>::TypedRangeData& RangeDataArray<T, Array>::Append(UPInt length,
const T& data)
684 UPInt count = Count();
685 TypedRangeData* pLastRange = NULL;
688 pLastRange = &Ranges[count - 1];
689 if (count > 0 && pLastRange->IsDataEqual(data))
691 pLastRange->Length += length;
696 Ranges.Resize(count + 1);
697 TypedRangeData& newRange = Ranges[count];
700 newRange.Index = pLastRange->Index + pLastRange->Length;
707 newRange.Length = length;
708 newRange.SetData(data);
713 template <
class T,
class Array>
714 void RangeDataArray<T, Array>::InsertRange(SPInt startPos, UPInt length,
const T& data)
716 ExpandRange(startPos, length);
717 SetRange(startPos, length, data);
721 template <
class T,
class Array>
722 void RangeDataArray<T, Array>::ExpandRange(SPInt startPos, UPInt length)
726 Iterator it = GetIteratorByNearestIndex(startPos);
727 TypedRangeData* pnearest = it.GetPtr();
730 if (pnearest->Contains(startPos) || pnearest->NextIndex() == startPos)
731 pnearest->Length += length;
734 for(++it; !it.IsFinished(); ++it)
736 it->MoveRange((SPInt)length);
742 template <
class T,
class Array>
743 void RangeDataArray<T, Array>::RemoveRange(SPInt startPos, UPInt length)
748 Iterator it = GetIteratorByNearestIndex(startPos);
749 Iterator removalPoint;
751 if (length == KY_MAX_UPINT)
752 length = KY_MAX_SPINT - startPos;
754 TypedRangeData range(startPos, length, T());
755 TypedRangeData& r = *it;
757 if (r.Contains(range))
760 if (r.Index == range.Index)
766 r.MoveIndex(range.Length);
772 else if (r.NextIndex() > range.NextIndex())
779 r.ShrinkRange(range.Length);
792 r.ShrinkRange(range.Length);
797 else if (r.Contains(range.Index))
803 r.ShrinkRange(r.NextIndex() - range.Index);
821 if (r.CompareTo(range.Index) > 0)
831 while(!it.IsFinished() && range.Contains(*it))
836 if (!it.IsFinished() && it->Contains(range.NextIndex() - 1))
841 it->MoveIndex(range.NextIndex() - it->Index);
844 Iterator firstRangeIt = removalPoint;
847 if (!firstRangeIt.IsFinished() && !removalPoint.IsFinished() &&
848 firstRangeIt->NextIndex() == removalPoint->Index - SPInt(length) &&
849 firstRangeIt->IsDataEqual(removalPoint->GetData()))
852 firstRangeIt->ExpandRange(removalPoint->Length);
853 removalPoint.Remove();
857 for(; !removalPoint.IsFinished(); ++removalPoint)
859 removalPoint->MoveRange(-((SPInt)length));
866 template <
class T,
class Array>
867 void RangeDataArray<T, Array>::ClearRange(SPInt startPos, UPInt length)
872 Iterator it = GetIteratorByNearestIndex(startPos);
873 Iterator removalPoint;
875 if (length == KY_MAX_UPINT)
876 length = KY_MAX_SPINT - startPos;
878 TypedRangeData range(startPos, length, T());
880 if (it->Contains(range))
883 if (it->Index == range.Index)
889 it->MoveIndex(range.Length);
897 else if (it->NextIndex() > range.NextIndex())
904 TypedRangeData r = *it;
905 SPInt endIndex = it->NextIndex();
906 it->ShrinkRange(endIndex - range.Index);
907 r.MoveIndex(it->Length + range.Length);
919 it->ShrinkRange(range.Length);
924 else if (it->Contains(range.Index))
930 it->ShrinkRange(it->NextIndex() - range.Index);
945 if (it->CompareTo(range.Index) > 0)
956 while(!it.IsFinished() && range.Contains(*it))
961 if (!it.IsFinished() && it->Contains(range.NextIndex() - 1))
966 it->MoveIndex(range.NextIndex() - it->Index);
972 #ifdef KY_CONFIG_DEBUG
973 template <
class T,
class Array>
974 void RangeDataArray<T, Array>::CheckIntegrity()
976 SPInt curIndex = KY_MIN_SPINT;
977 TypedRangeData* pprev = NULL;
978 for (UPInt i = 0, n = Ranges.GetSize(); i < n; ++i)
980 TypedRangeData& r = Ranges[i];
983 if (pprev->Index + (SPInt)pprev->Length == r.Index)
984 KY_ASSERT(pprev->GetData() != r.GetData());
987 KY_ASSERT(curIndex <= r.FirstIndex());
988 curIndex = r.NextIndex();
996 #endif // INC_KY_Kernel_Range_H
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
Vec2f operator*(KyFloat32 s, const Vec2f &v)
scalar * vec operator
Definition: vec2f.h:120