673 lines
24 KiB
MQL5
673 lines
24 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| 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);
| |||
}
| |||
//+------------------------------------------------------------------+
|