#ifndef _listwrappers_h_
#define _listwrappers_h_
class ListEventSource
{
TRef<EventSourceImpl> m_peventSource;
public:
ListEventSource()
: m_peventSource(new EventSourceImpl()) {};
ListEventSource(const ListEventSource& les)
: m_peventSource(les.m_peventSource) {};
void operator () ()
{ m_peventSource->Trigger(); };
virtual IEventSource* GetEvent()
{
return m_peventSource;
}
};
template <class T>
class Slist_utlListWrapper : public List, public Slist_utl<T, ListEventSource> {
public:
typedef Slink_utl<T, ListEventSource> Link;
virtual int GetCount()
{
int nCount = 0;
#if _MSC_VER >= 1310
for (Slink_utl<T, ListEventSource>* link = first(); link != NULL; link = (link->next)())
#else
for (Slink_utl<T, ListEventSource>* link = first(); link != NULL; link = link->next)
#endif
nCount++;
return nCount;
}
virtual ItemID GetItem(int index)
{
return (*this)[index];
}
virtual int GetIndex(ItemID pitem)
{
int nIndex = 0;
#if _MSC_VER >= 1310
for (Link* link = first(); link != NULL; link = (link->next)())
#else
for (Link* link = first(); link != NULL; link = link->next)
#endif
{
if ((ItemID)link == pitem)
return nIndex;
nIndex++;
}
return -1;
}
virtual ItemID GetNext(ItemID pitem)
{
return ((Link*)pitem)->next();
}
virtual IEventSource* GetChangedEvent()
{
return sink.GetEvent();
}
};
template <class T>
class IntItemIDWrapper
{
T m_t;
enum { ZeroValue = ~(1 << (sizeof(T)*8 - 2)) };
public:
IntItemIDWrapper() {}
IntItemIDWrapper(T t) : m_t(t) {}
IntItemIDWrapper(ItemID pitem) { m_t = ((int)pitem == ZeroValue) ? 0 : (T)pitem; }
int operator = (T t) { m_t = t; }
operator T () { return m_t; }
operator ItemID () { return (ItemID)((m_t == 0) ? (T)ZeroValue : m_t); };
bool operator == (IntItemIDWrapper<T> t) const { return m_t == t; }
bool operator <= (IntItemIDWrapper<T> t) const { return m_t <= t; }
bool operator >= (IntItemIDWrapper<T> t) const { return m_t >= t; }
bool operator < (IntItemIDWrapper<T> t) const { return m_t < t; }
bool operator > (IntItemIDWrapper<T> t) const { return m_t > t; }
};
template <
class T,
class EqualsType = DefaultEquals,
class CompareType = DefaultNoCompare
>
class TListListWrapper : public List, public TList<T, EqualsType, CompareType, ListEventSource> {
public:
TListListWrapper()
{
}
TListListWrapper(EqualsType equals, CompareType compare)
: TList<T, EqualsType, CompareType, ListEventSource>(equals, compare)
{
}
virtual int GetCount()
{
return TList<T, EqualsType, CompareType, ListEventSource>::GetCount();
}
virtual ItemID GetItem(int index)
{
if (index < 0 || index >= GetCount())
return NULL;
else
return (ItemID)((*this)[index]);
}
virtual int GetIndex(ItemID pitem)
{
int nIndex = 0;
for (Iterator iter(*this); !iter.End(); iter.Next())
{
if ((ItemID)iter.Value() == pitem)
return nIndex;
nIndex++;
}
return -1;
}
virtual ItemID GetNext(ItemID pitem)
{
for (Iterator iter(*this); !iter.End(); iter.Next())
{
if ((ItemID)iter.Value() == pitem)
{
iter.Next();
if (iter.End())
return NULL;
else
return (ItemID)iter.Value();
}
}
return NULL;
}
virtual IEventSource* GetChangedEvent()
{
return GetSink().GetEvent();
}
};
template <class T, class U>
class TMapListWrapper : public List, public TMap<T, U, ListEventSource> {
public:
virtual int GetCount()
{
return Count();
}
virtual ItemID GetItem(int index)
{
Iterator iter(*this);
for (int currentIndex = 0; !iter.End() && currentIndex < index; currentIndex++)
{
iter.Next();
}
if (iter.End())
return NULL;
else
return (ItemID)iter.Value();
}
virtual int GetIndex(ItemID pitem)
{
int nIndex = 0;
for (Iterator iter(*this); !iter.End(); iter.Next())
{
if ((ItemID)iter.Value() == pitem)
return nIndex;
nIndex++;
}
return -1;
}
virtual ItemID GetNext(ItemID pitem)
{
for (Iterator iter(*this); !iter.End(); iter.Next())
{
if ((ItemID)iter.Value() == pitem)
{
iter.Next();
if (iter.End())
return NULL;
else
return (ItemID)iter.Value();
}
}
return NULL;
}
virtual IEventSource* GetChangedEvent()
{
return GetSink().GetEvent();
}
};
template <class Filter>
class FilteredList : public List
{
TRef<List> m_list;
Filter m_filter;
public:
FilteredList(List* list)
: m_list(list) {};
FilteredList(List* list, Filter filter)
: m_list(list), m_filter(filter) {};
void SetFilter(Filter filter)
{
m_filter = filter;
}
virtual int GetCount()
{
int nCount = 0;
ItemID currentItem = m_list->GetItem(0);
while (currentItem != NULL)
{
if (m_filter(currentItem))
nCount++;
currentItem = m_list->GetNext(currentItem);
}
return nCount;
}
virtual ItemID GetItem(int index)
{
int nCurrentIndex = 0;
ItemID currentItem = m_list->GetItem(0);
while (currentItem != NULL)
{
if (m_filter(currentItem))
{
if (nCurrentIndex == index)
break;
else
nCurrentIndex++;
}
currentItem = m_list->GetNext(currentItem);
}
return currentItem;
}
virtual int GetIndex(ItemID pitem)
{
int nIndex = 0;
ItemID currentItem = m_list->GetItem(0);
while (currentItem != NULL)
{
if (m_filter(currentItem))
{
if (currentItem == pitem)
return nIndex;
else
nIndex++;
}
currentItem = m_list->GetNext(currentItem);
}
return -1;
}
virtual ItemID GetNext(ItemID pitem)
{
ItemID currentItem = m_list->GetNext(pitem);
while (currentItem != NULL)
{
if (m_filter(currentItem))
{
return currentItem;
}
currentItem = m_list->GetNext(currentItem);
}
return NULL;
}
virtual IEventSource* GetChangedEvent()
{
return m_list->GetChangedEvent();
}
};
class ListDelegate : public List
{
private:
List* m_plist;
TRef<IObject> m_pcontainer;
public:
ListDelegate(List* plist, IObject* pcontainer = NULL)
: m_plist(plist), m_pcontainer(pcontainer) {}
virtual int GetCount()
{
return m_plist->GetCount();
}
virtual ItemID GetItem(int index)
{
return m_plist->GetItem(index);
}
virtual int GetIndex(ItemID pitem)
{
return m_plist->GetIndex(pitem);
}
virtual ItemID GetNext(ItemID pitem)
{
return m_plist->GetNext(pitem);
}
virtual IEventSource* GetChangedEvent()
{
return m_plist->GetChangedEvent();
}
};
class ConcatinatedList : public List, public IEventSink
{
TRef<List> m_list1;
TRef<List> m_list2;
ListEventSource m_pfnChanged;
TRef<IEventSink> m_sinkDelegate;
public:
ConcatinatedList(List* list1, List* list2)
: m_list1(list1), m_list2(list2)
{
m_sinkDelegate = IEventSink::CreateDelegate(this);
m_list1->GetChangedEvent()->AddSink(m_sinkDelegate);
m_list2->GetChangedEvent()->AddSink(m_sinkDelegate);
};
~ConcatinatedList()
{
m_list1->GetChangedEvent()->RemoveSink(m_sinkDelegate);
m_list2->GetChangedEvent()->RemoveSink(m_sinkDelegate);
}
virtual int GetCount()
{
return m_list1->GetCount() + m_list2->GetCount();
}
virtual ItemID GetItem(int index)
{
int nList1Count = m_list1->GetCount();
if (index < nList1Count)
return m_list1->GetItem(index);
else
return m_list2->GetItem(index - nList1Count);
}
virtual int GetIndex(ItemID pitem)
{
int index = m_list1->GetIndex(pitem);
if (index == -1)
{
index = m_list2->GetIndex(pitem);
if (index != -1)
index += m_list1->GetCount();
}
return index;
}
virtual ItemID GetNext(ItemID pitem)
{
ItemID next = m_list1->GetNext(pitem);
if (next == NULL)
{
next = m_list2->GetNext(pitem);
if ((next == NULL) && (m_list1->GetIndex(pitem) != -1))
{
next = m_list2->GetItem(0);
}
}
return next;
}
virtual IEventSource* GetChangedEvent()
{
return m_pfnChanged.GetEvent();
}
virtual bool OnEvent(IEventSource* pevent)
{
m_pfnChanged();
return true;
}
};
typedef bool (*ItemIDCompareFunction)(ItemID id1, ItemID id2);
template <class CompareFunctionType>
class SortedList : public List, public IEventSink
{
typedef TList<ItemID, DefaultEquals, CompareFunctionType> SortedListType;
SortedListType m_listSorted;
TRef<List> m_list;
bool m_fNeedsSort;
ListEventSource m_pfnChanged;
TRef<IEventSink> m_sinkDelegate;
void CheckSorting()
{
if (m_fNeedsSort)
{
m_listSorted.SetEmpty();
ItemID pitem = m_list->GetItem(0);
while (pitem) {
m_listSorted.InsertSorted(pitem);
pitem = m_list->GetNext(pitem);
}
m_fNeedsSort = false;
}
}
public:
SortedList(List* list, CompareFunctionType fnCompare)
: m_list(list), m_listSorted(DefaultEquals(), fnCompare), m_fNeedsSort(true)
{
m_sinkDelegate = IEventSink::CreateDelegate(this);
m_list->GetChangedEvent()->AddSink(m_sinkDelegate);
};
~SortedList()
{
m_list->GetChangedEvent()->RemoveSink(m_sinkDelegate);
}
virtual int GetCount()
{
return m_list->GetCount();
}
virtual ItemID GetItem(int index)
{
CheckSorting();
SortedListType::Iterator iter(m_listSorted);
for (int currentIndex = 0; !iter.End() && currentIndex < index; currentIndex++)
{
iter.Next();
}
if (iter.End())
return NULL;
else
return (ItemID)iter.Value();
}
virtual int GetIndex(ItemID pitem)
{
CheckSorting();
int nIndex = 0;
for (SortedListType::Iterator iter(m_listSorted); !iter.End(); iter.Next())
{
if ((ItemID)iter.Value() == pitem)
return nIndex;
nIndex++;
}
return -1;
}
virtual ItemID GetNext(ItemID pitem)
{
CheckSorting();
for (SortedListType::Iterator iter(m_listSorted); !iter.End(); iter.Next())
{
if ((ItemID)iter.Value() == pitem)
{
iter.Next();
if (iter.End())
return NULL;
else
return (ItemID)iter.Value();
}
}
return NULL;
}
virtual IEventSource* GetChangedEvent()
{
return m_pfnChanged.GetEvent();
}
virtual bool OnEvent(IEventSource* pevent)
{
m_fNeedsSort = true;
m_pfnChanged();
return true;
}
};
class SingletonList : public List
{
ListEventSource m_pfnChanged;
ItemID m_itemID;
public:
SingletonList(ItemID itemID = NULL)
: m_itemID(itemID)
{
}
void SetItem(ItemID itemID)
{
m_itemID = itemID;
m_pfnChanged();
}
virtual int GetCount()
{
return 1;
}
virtual ItemID GetItem(int index)
{
if (index == 0)
return m_itemID;
else
return NULL;
}
virtual int GetIndex(ItemID pitem)
{
if (pitem = m_itemID)
return 0;
else
return -1;
}
virtual ItemID GetNext(ItemID pitem)
{
return NULL;
}
virtual IEventSource* GetChangedEvent()
{
return m_pfnChanged.GetEvent();
}
};
#endif