| //+------------------------------------------------------------------+
|
| //| SortedList.mqh |
|
| //| Copyright 2000-2025, MetaQuotes Ltd. |
|
| //| https://www.mql5.com |
|
| //+------------------------------------------------------------------+
|
| #include <Generic\Interfaces\ISet.mqh>
|
| #include <Generic\Internal\Introsort.mqh>
|
| #include "RedBlackTree.mqh"
|
| #include "HashSet.mqh"
|
| //+------------------------------------------------------------------+
|
| //| Class CSortedSet<T>. |
|
| //| Usage: Represents a collection of objects that is maintained in |
|
| //| sorted order. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| class CSortedSet: public ISet<T>
|
| {
|
| protected:
|
| CRedBlackTree<T>*m_tree;
|
|
|
| public:
|
| CSortedSet(void);
|
| CSortedSet(IComparer<T>*comparer);
|
| CSortedSet(ICollection<T>*collection);
|
| CSortedSet(ICollection<T>*collection,IComparer<T>*comparer);
|
| CSortedSet(T &array[]);
|
| CSortedSet(T &array[],IComparer<T>*comparer);
|
| ~CSortedSet(void);
|
| //--- methods of filling data
|
| bool Add(T value) { return(m_tree.Add(value)); }
|
| //--- methods of access to protected data
|
| int Count(void) { return(m_tree.Count()); }
|
| bool Contains(T item) { return(m_tree.Contains(item)); }
|
| IComparer<T> *Comparer(void) const { return(m_tree.Comparer()); }
|
| bool TryGetMin(T &min) { return(m_tree.TryGetMin(min)); }
|
| bool TryGetMax(T &max) { return(m_tree.TryGetMax(max)); }
|
| //--- methods of copy data from collection
|
| int CopyTo(T &dst_array[],const int dst_start=0);
|
| //--- methods of cleaning and deleting
|
| void Clear(void) { m_tree.Clear(); }
|
| bool Remove(T item) { return(m_tree.Remove(item)); }
|
| //--- methods of changing sets
|
| void ExceptWith(ICollection<T>*collection);
|
| void ExceptWith(T &array[]);
|
| void IntersectWith(ICollection<T>*collection);
|
| void IntersectWith(T &array[]);
|
| void SymmetricExceptWith(ICollection<T>*collection);
|
| void SymmetricExceptWith(T &array[]);
|
| void UnionWith(ICollection<T>*collection);
|
| void UnionWith(T &array[]);
|
| //--- methods for determining the relationship between sets
|
| bool IsProperSubsetOf(ICollection<T>*collection);
|
| bool IsProperSubsetOf(T &array[]);
|
| bool IsProperSupersetOf(ICollection<T>*collection);
|
| bool IsProperSupersetOf(T &array[]);
|
| bool IsSubsetOf(ICollection<T>*collection);
|
| bool IsSubsetOf(T &array[]);
|
| bool IsSupersetOf(ICollection<T>*collection);
|
| bool IsSupersetOf(T &array[]);
|
| bool Overlaps(ICollection<T>*collection);
|
| bool Overlaps(T &array[]);
|
| bool SetEquals(ICollection<T>*collection);
|
| bool SetEquals(T &array[]);
|
| //--- methods for working with an ordered set
|
| bool GetViewBetween(T &array[],T lower_value,T upper_value);
|
| bool GetReverse(T &array[]);
|
| };
|
| //+------------------------------------------------------------------+
|
| //| Initializes a new instance of the CSortedSet<T> class that is |
|
| //| empty and uses the default equality comparer for the set type. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| CSortedSet::CSortedSet(void)
|
| {
|
| m_tree=new CRedBlackTree<T>();
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Initializes a new instance of the CSortedSet<T> class that is |
|
| //| empty and uses the specified equality comparer for the set type. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| CSortedSet::CSortedSet(IComparer<T>*comparer)
|
| {
|
| m_tree=new CRedBlackTree<T>(comparer);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Initializes a new instance of the CSortedSet<T> class that uses |
|
| //| the default equality comparer for the set type, contains elements|
|
| //| copied from the specified collection, and has sufficient capacity|
|
| //| to accommodate the number of elements copied. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| CSortedSet::CSortedSet(ICollection<T>*collection)
|
| {
|
| m_tree=new CRedBlackTree<T>(collection);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Initializes a new instance of the CSortedSet<T> class that uses |
|
| //| the specified equality comparer for the set type, contains |
|
| //| elements copied from the specified collection, and has sufficient|
|
| //| capacity to accommodate the number of elements copied. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| CSortedSet::CSortedSet(ICollection<T>*collection,IComparer<T>*comparer)
|
| {
|
| m_tree=new CRedBlackTree<T>(collection,comparer);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Initializes a new instance of the CSortedSet<T> class that uses |
|
| //| the default equality comparer for the set type, contains |
|
| //| elements copied from the specified array, and has sufficient |
|
| //| capacity to accommodate the number of elements copied. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| CSortedSet::CSortedSet(T &array[])
|
| {
|
| m_tree=new CRedBlackTree<T>(array);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Initializes a new instance of the CSortedSet<T> class that uses |
|
| //| the specified equality comparer for the set type, contains |
|
| //| elements copied from the specified array, and has sufficient |
|
| //| capacity to accommodate the number of elements copied. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| CSortedSet::CSortedSet(T &array[],IComparer<T>*comparer)
|
| {
|
| m_tree=new CRedBlackTree<T>(array,comparer);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Destructor. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| CSortedSet::~CSortedSet(void)
|
| {
|
| delete m_tree;
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Copies a range of elements from the set to a compatible |
|
| //| one-dimensional array. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| int CSortedSet::CopyTo(T &dst_array[],const int dst_start=0)
|
| {
|
| return(m_tree.CopyTo(dst_array, dst_start));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Removes all elements in the specified collection from the current|
|
| //| set. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| void CSortedSet::ExceptWith(ICollection<T>*collection)
|
| {
|
| //--- check collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return;
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return;
|
| //--- special case if collection is this
|
| //--- a set minus itself is the empty set
|
| if(collection==GetPointer(this))
|
| {
|
| Clear();
|
| return;
|
| }
|
| //--- copy collection to array
|
| T array[];
|
| int size=collection.CopyTo(array);
|
| //--- find max and min value
|
| T max;
|
| T min;
|
| //--- get comaprer
|
| IComparer<T>*comparer=Comparer();
|
| if(!m_tree.TryGetMax(max))
|
| return;
|
| if(!m_tree.TryGetMin(min))
|
| return;
|
| //--- remove elements
|
| for(int i=0; i<size; i++)
|
| {
|
| T item=array[i];
|
| if(!(comparer.Compare(item,min)<0 || comparer.Compare(item,max)>0) && Contains(item))
|
| m_tree.Remove(item);
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Removes all elements in the specified array from the current set.|
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| void CSortedSet::ExceptWith(T &array[])
|
| {
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return;
|
| //--- get array size
|
| int size=ArraySize(array);
|
| //--- find max and min value
|
| T max;
|
| T min;
|
| //--- get comparer
|
| IComparer<T>*comparer=Comparer();
|
| if(!m_tree.TryGetMax(max))
|
| return;
|
| if(!m_tree.TryGetMin(min))
|
| return;
|
| //--- remove elements
|
| for(int i=0; i<size; i++)
|
| {
|
| T item=array[i];
|
| if(!(comparer.Compare(item,min)<0 || comparer.Compare(item,max)>0) && Contains(item))
|
| m_tree.Remove(item);
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Modifies the current set to contain only elements that are |
|
| //| present in that object and in the specified collection. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| void CSortedSet::IntersectWith(ICollection<T>*collection)
|
| {
|
| //--- check collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return;
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return;
|
| //--- special case if collection is this
|
| //--- a set minus itself is the empty set
|
| if(collection==GetPointer(this))
|
| return;
|
| //--- copy collection to array
|
| T array[];
|
| int size=collection.CopyTo(array);
|
| //--- create emty tree
|
| CRedBlackTree<T>*tree=new CRedBlackTree<T>();
|
| //--- store values conatin in tree and array
|
| for(int i=0; i<size; i++)
|
| if(m_tree.Contains(array[i]))
|
| tree.Add(array[i]);
|
| //--- overwrite tree
|
| delete m_tree;
|
| m_tree=tree;
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Modifies the current set to contain only elements that are |
|
| //| present in that object and in the specified array. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| void CSortedSet::IntersectWith(T &array[])
|
| {
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return;
|
| //--- get array size
|
| int size=ArraySize(array);
|
| //--- create emty tree
|
| CRedBlackTree<T>*tree=new CRedBlackTree<T>();
|
| //--- store values conatin in tree and array
|
| for(int i=0; i<size; i++)
|
| if(m_tree.Contains(array[i]))
|
| tree.Add(array[i]);
|
| //--- overwrite tree
|
| delete m_tree;
|
| m_tree=tree;
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Modifies the current set to contain only elements that are |
|
| //| present either in that set or in the specified collection, but |
|
| //| not both. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| void CSortedSet::SymmetricExceptWith(ICollection<T>*collection)
|
| {
|
| //--- check collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return;
|
| //--- check collection count
|
| if(collection.Count()==0)
|
| return;
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| {
|
| UnionWith(collection);
|
| return;
|
| }
|
| //--- special case if collection is this
|
| //--- a set minus itself is the empty set
|
| if(collection==GetPointer(this))
|
| {
|
| Clear();
|
| return;
|
| }
|
| //--- copy colleaction to array
|
| T array[];
|
| int size=collection.CopyTo(array);
|
| //--- get comparer
|
| IComparer<T>*comparer=m_tree.Comparer();
|
| //--- sort array
|
| Introsort<T,T>sort;
|
| ArrayCopy(sort.keys,array);
|
| sort.comparer=comparer;
|
| sort.Sort(0, size);
|
| ArrayCopy(array,sort.keys);
|
| //--- modify tree
|
| T last=array[0];
|
| for(int i=0; i<size; i++)
|
| {
|
| while(i<size && i!=0 && comparer.Compare(array[i],last)==0)
|
| i++;
|
| if(i>=size)
|
| break;
|
|
|
| if(m_tree.Contains(array[i]))
|
| m_tree.Remove(array[i]);
|
| else
|
| m_tree.Add(array[i]);
|
|
|
| last=array[i];
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Modifies the current set to contain only elements that are |
|
| //| present either in that set or in the specified array, but not |
|
| //| both. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| void CSortedSet::SymmetricExceptWith(T &array[])
|
| {
|
| //--- check array size
|
| if(ArraySize(array)==0)
|
| return;
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| {
|
| UnionWith(array);
|
| return;
|
| }
|
| //--- get size
|
| int size=ArraySize(array);
|
| //--- get comparer
|
| IComparer<T>*comparer=m_tree.Comparer();
|
| //--- sort array
|
| Introsort<T,T>sort;
|
| ArrayCopy(sort.keys,array);
|
| sort.comparer=comparer;
|
| sort.Sort(0, size);
|
| ArrayReverse(sort.keys,0,ArraySize(sort.keys));
|
| //--- modify tree
|
| T last=sort.keys[0];
|
| for(int i=0; i<size; i++)
|
| {
|
| while(i<size && i!=0 && comparer.Compare(sort.keys[i],last)==0)
|
| i++;
|
| if(i>=size)
|
| break;
|
|
|
| if(m_tree.Contains(sort.keys[i]))
|
| m_tree.Remove(sort.keys[i]);
|
| else
|
| m_tree.Add(sort.keys[i]);
|
|
|
| last=sort.keys[i];
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Modifies the current set to contain all elements that are present|
|
| //| in itself, the specified collection, or both. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| void CSortedSet::UnionWith(ICollection<T>*collection)
|
| {
|
| //--- check collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return;
|
| //--- copy all elements from collecton to array
|
| T array[];
|
| int size=collection.CopyTo(array);
|
| //--- add all elemets from array to set
|
| for(int i=0; i<size; i++)
|
| m_tree.Add(array[i]);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Modifies the current set to contain all elements that are present|
|
| //| in itself, the specified array, or both. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| void CSortedSet::UnionWith(T &array[])
|
| {
|
| //--- get array size
|
| int size=ArraySize(array);
|
| //--- add all elemets from array to set
|
| for(int i=0; i<size; i++)
|
| m_tree.Add(array[i]);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set is a proper subset of the specified |
|
| //| collection. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::IsProperSubsetOf(ICollection<T>*collection)
|
| {
|
| //--- check collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return(false);
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return(collection.Count() > 0);
|
| //--- check collection is set
|
| CHashSet<T>*ptr_set=dynamic_cast<CHashSet<T>*>(collection);
|
| if(CheckPointer(ptr_set)!=POINTER_INVALID)
|
| {
|
| return(ptr_set.IsProperSupersetOf(m_tree));
|
| }
|
| else
|
| {
|
| //--- create a set based on a specified collection
|
| CHashSet<T>set(collection);
|
| return(set.IsProperSupersetOf(m_tree));
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set is a proper subset of the specified |
|
| //| array. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::IsProperSubsetOf(T &array[])
|
| {
|
| if(m_tree.Count()==0)
|
| return(ArraySize(array) > 0);
|
| //--- create a set based on a specified array
|
| CHashSet<T>set(array);
|
| if(m_tree.Count()>=set.Count())
|
| return(false);
|
| return(set.IsProperSupersetOf(m_tree));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set is a proper superset of the specified |
|
| //| collection. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::IsProperSupersetOf(ICollection<T>*collection)
|
| {
|
| //--- check collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return(m_tree.Count()>0);
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return(false);
|
| //--- check collection count
|
| if(collection.Count()==0)
|
| return(true);
|
| //--- check collection is set
|
| CHashSet<T>*ptr_set=dynamic_cast<CHashSet<T>*>(collection);
|
| if(CheckPointer(ptr_set)!=POINTER_INVALID)
|
| {
|
| return(ptr_set.IsProperSubsetOf(m_tree));
|
| }
|
| else
|
| {
|
| //--- create a set based on a specified collection
|
| CHashSet<T>set(collection);
|
| return(set.IsProperSubsetOf(m_tree));
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set is a proper superset of the specified |
|
| //| array. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::IsProperSupersetOf(T &array[])
|
| {
|
| if(m_tree.Count()==0)
|
| return(false);
|
| if(ArraySize(array)==0)
|
| return(true);
|
| //--- create a set based on a specified array
|
| CHashSet<T>set(array);
|
| return(set.IsProperSubsetOf(m_tree));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set is a subset of the specified collection.|
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::IsSubsetOf(ICollection<T>*collection)
|
| {
|
| //--- cehck collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return(m_tree.Count()==0);
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return(true);
|
| //--- check collection is set
|
| CHashSet<T>*ptr_set=dynamic_cast<CHashSet<T>*>(collection);
|
| if(CheckPointer(ptr_set)==POINTER_DYNAMIC)
|
| {
|
| return(ptr_set.IsProperSupersetOf(m_tree));
|
| }
|
| else
|
| {
|
| //--- create a set based on a specified collection
|
| CHashSet<T>set(collection);
|
| return(set.IsProperSupersetOf(m_tree));
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set is a subset of the specified array. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::IsSubsetOf(T &array[])
|
| {
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return(true);
|
| //--- create a set based on a specified array
|
| CHashSet<T>set(array);
|
| if(m_tree.Count()>set.Count())
|
| return(false);
|
| return(set.IsProperSupersetOf(m_tree));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set is a superset of the specified |
|
| //| collection. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::IsSupersetOf(ICollection<T>*collection)
|
| {
|
| //--- check collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return(m_tree.Count()>=0);
|
| //--- check collection count
|
| if(collection.Count()==0)
|
| return(true);
|
| //--- check collection is set
|
| CHashSet<T>*ptr_set=dynamic_cast<CHashSet<T>*>(collection);
|
| if(CheckPointer(ptr_set)!=POINTER_INVALID)
|
| {
|
| return(ptr_set.IsSupersetOf(m_tree));
|
| }
|
| else
|
| {
|
| //--- create a set based on a specified collection
|
| CHashSet<T>set(collection);
|
| return(set.IsSupersetOf(m_tree));
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set is a superset of the specified array. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::IsSupersetOf(T &array[])
|
| {
|
| //--- check array size
|
| if(ArraySize(array)==0)
|
| return(true);
|
| //--- create a set based on a specified array
|
| CHashSet<T>set(array);
|
| return(set.IsSupersetOf(m_tree));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether the current set and a specified collection |
|
| //| share common elements. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::Overlaps(ICollection<T>*collection)
|
| {
|
| //--- check collection
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return(false);
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return(false);
|
| //--- check collection count
|
| if(collection.Count()==0)
|
| return(false);
|
| //--- check collection is set
|
| CHashSet<T>*ptr_set=dynamic_cast<CHashSet<T>*>(collection);
|
| if(CheckPointer(ptr_set)!=POINTER_INVALID)
|
| {
|
| return(ptr_set.Overlaps(m_tree));
|
| }
|
| else
|
| {
|
| //--- create a set based on a specified collection
|
| CHashSet<T>set(collection);
|
| return(set.Overlaps(m_tree));
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether the current set and a specified array share |
|
| //| common elements. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::Overlaps(T &array[])
|
| {
|
| //--- check tree count
|
| if(m_tree.Count()==0)
|
| return(false);
|
| //--- check array size
|
| if(ArraySize(array)==0)
|
| return(false);
|
| //--- convert array to set
|
| CHashSet<T>set(array);
|
| return(set.Overlaps(m_tree));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set and the specified collection contain the|
|
| //| same elements. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::SetEquals(ICollection<T>*collection)
|
| {
|
| if(CheckPointer(collection)==POINTER_INVALID)
|
| return(false);
|
| //--- get array from collection
|
| T array[];
|
| collection.CopyTo(array);
|
| //--- check current set is equal specified array
|
| return SetEquals(array);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Determines whether a set and the specified array contain the same|
|
| //| elements. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::SetEquals(T &array[])
|
| {
|
| //--- try find all elements in the tree
|
| for(int i=0; i<ArraySize(array); i++)
|
| if(!m_tree.Contains(array[i]))
|
| return(false);
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Copy a view of a subset in a CSortedSet<T> to array. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::GetViewBetween(T &array[],T lower_value,T upper_value)
|
| {
|
| //--- get comparer
|
| IComparer<T>*comparer=m_tree.Comparer();
|
| if(comparer.Compare(lower_value,upper_value)>0)
|
| return(false);
|
| //--- copy all element from tree to array
|
| T buff[];
|
| int size=m_tree.CopyTo(buff);
|
| //--- check range
|
| if(size==0 || comparer.Compare(buff[0],upper_value)>0 || comparer.Compare(buff[size-1],lower_value)<0)
|
| return(false);
|
| //--- find first element greater than lower_value
|
| int index_lower=0;
|
| while(index_lower<size && comparer.Compare(buff[index_lower],lower_value)<0)
|
| index_lower++;
|
| //--- find first element less than upper_value
|
| int index_upper=size-1;
|
| while(index_upper>0 && comparer.Compare(buff[index_upper],upper_value)>0)
|
| index_upper--;
|
| //--- check indices
|
| if(index_lower>index_upper)
|
| return(false);
|
| //--- copy view between lower_value and upper_value to array
|
| return(ArrayCopy(array,buff,0,index_lower,index_upper-index_lower+1)>=0);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Copy the CSortedSet<T> in reverse order to array. |
|
| //+------------------------------------------------------------------+
|
| template<typename T>
|
| bool CSortedSet::GetReverse(T &array[])
|
| {
|
| int size=m_tree.CopyTo(array);
|
| return ArrayReverse(array,0,size);
|
| }
|
| //+------------------------------------------------------------------+
|