Dryad/GraphManager/shared/DrArrayList.h

470 lines
10 KiB
C++

/*
Copyright (c) Microsoft Corporation
All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License
at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions and
limitations under the License.
*/
#pragma once
#ifdef _MANAGED
template <class T> DRBASECLASS(DrArrayList), public System::Collections::Generic::List<T>
{
public:
DrArrayList() : System::Collections::Generic::List<T>()
{
}
DrArrayList(int initialSize) : System::Collections::Generic::List<T>(initialSize)
{
}
int Allocated()
{
return Capacity;
}
int Size()
{
return Count;
}
};
template <class T> DRBASECLASS(DrValueWrapperArrayList)
{
public:
DrValueWrapperArrayList()
{
m_list = DrNew System::Collections::Generic::List< DrValueWrapper<T> >();
}
DrValueWrapperArrayList(int initialSize)
{
m_list = DrNew System::Collections::Generic::List< DrValueWrapper<T> >(initialSize);
}
void Add(T t)
{
DrValueWrapper<T> tt;
tt.T() = t;
m_list->Add(tt);
}
void RemoveAt(int i)
{
m_list->RemoveAt(i);
}
T% operator[](int index)
{
return m_list[index].T();
}
T% Get(int index)
{
return m_list[index].T();
}
int Allocated()
{
return m_list->Capacity;
}
int Size()
{
return m_list->Count;
}
private:
System::Collections::Generic::List< DrValueWrapper<T> >^ m_list;
};
#define DRMAKEARRAYLIST(T_) typedef DrArrayList<T_> T_##List; \
typedef T_##List^ T_##ListRef; typedef T_##List^ T_##ListPtr; typedef T_##List% T_##ListR; \
template ref class DrArrayList<T_>
#define DRMAKEVWARRAYLIST(T_) typedef DrValueWrapperArrayList<T_> T_##List; \
typedef T_##List^ T_##ListRef; typedef T_##List^ T_##ListPtr; typedef T_##List% T_##ListR; \
template ref class DrValueWrapperArrayList<T_>
#else
#include <vector>
#include <algorithm>
#include <functional>
template <class T> DRBASECLASS(DrArrayList)
{
public:
DrArrayList()
{
Initialize(1);
}
DrArrayList(int initialSize)
{
Initialize(initialSize);
}
~DrArrayList()
{
#ifdef _DEBUG_DRREF
EnterCriticalSection(&DrRefCounter::s_debugCS);
if (m_vector.size() > 0)
{
size_t nRemoved = DrRefCounter::s_arrayStorage.erase(&(m_vector[0]));
DrAssert(nRemoved == 1);
}
LeaveCriticalSection(&DrRefCounter::s_debugCS);
#endif
}
void Add(T t)
{
#ifdef _DEBUG_DRREF
EnterCriticalSection(&DrRefCounter::s_debugCS);
if (m_vector.size() > 0)
{
size_t nRemoved = DrRefCounter::s_arrayStorage.erase(&(m_vector[0]));
DrAssert(nRemoved == 1);
}
LeaveCriticalSection(&DrRefCounter::s_debugCS);
#endif
m_vector.push_back(t);
#ifdef _DEBUG_DRREF
EnterCriticalSection(&DrRefCounter::s_debugCS);
bool inserted = DrRefCounter::s_arrayStorage.insert(std::make_pair(&(m_vector[0]),this)).second;
DrAssert(inserted);
LeaveCriticalSection(&DrRefCounter::s_debugCS);
#endif
}
void RemoveAt(int element)
{
#ifdef _DEBUG_DRREF
EnterCriticalSection(&DrRefCounter::s_debugCS);
size_t nRemoved = DrRefCounter::s_arrayStorage.erase(&(m_vector[0]));
DrAssert(nRemoved == 1);
LeaveCriticalSection(&DrRefCounter::s_debugCS);
#endif
m_vector.erase(m_vector.begin() + element);
#ifdef _DEBUG_DRREF
EnterCriticalSection(&DrRefCounter::s_debugCS);
if (m_vector.size() > 0)
{
bool inserted = DrRefCounter::s_arrayStorage.insert(std::make_pair(&(m_vector[0]),this)).second;
DrAssert(inserted);
}
LeaveCriticalSection(&DrRefCounter::s_debugCS);
#endif
}
bool Remove(T t)
{
std::vector<T>::iterator i;
for (i=m_vector.begin(); i!=m_vector.end(); ++i)
{
if (*i == t)
{
m_vector.erase(i);
return true;
}
}
return false;
}
T& operator[](int element)
{
return m_vector[element];
}
T& Get(int element)
{
return m_vector[element];
}
int Size()
{
return (int) m_vector.size();
}
int Allocated()
{
return (int) m_vector.capacity();
}
void Sort(DrComparer<T>* comparer)
{
Comparer c(comparer);
std::sort(m_vector.begin(), m_vector.end(), c);
}
private:
class Comparer : std::binary_function<T,T,bool>
{
public:
Comparer(DrComparer<T>* comparer)
{
m_comparer = comparer;
}
bool operator() (T& a, T& b)
{
return (m_comparer->Compare(a, b) < 0);
}
private:
DrComparer<T>* m_comparer;
};
void Initialize(int initialSize)
{
if (initialSize == 0)
{
initialSize = 1;
}
m_vector.reserve(initialSize);
#ifdef _DEBUG_DRREF
DrAssert(m_vector.size() == 0);
#endif
}
protected:
std::vector<T> m_vector;
};
#if 0
template <class T> DRBASECLASS(DrArrayList)
{
public:
DrArrayList()
{
Initialize(1);
}
DrArrayList(int initialSize)
{
Initialize(initialSize);
}
~DrArrayList()
{
delete [] m_array;
}
void Add(T t)
{
if (m_used == m_allocated)
{
m_allocated *= 2;
T* newArray = new T[m_allocated];
int i;
for (i=0; i<m_used; ++i)
{
newArray[i] = m_array[i];
}
delete [] m_array;
m_array = newArray;
}
DrAssert(m_used < m_allocated);
m_array[m_used] = t;
++m_used;
}
void RemoveAt(int element)
{
DrAssert(element < m_used);
int i;
for (i=element+1; i<m_used; ++i)
{
m_array[i-1] = m_array[i];
}
--m_used;
m_array[m_used] = T();
}
T& operator[](int element)
{
DrAssert(element < m_used);
return m_array[element];
}
int Size()
{
return m_used;
}
int Allocated()
{
return m_allocated;
}
void Sort(DrComparer<T>* comparer)
{
::qsort_s(m_array, m_used, sizeof(T), DrComparer<T>::CompareUntyped, comparer);
}
private:
void Initialize(int initialSize)
{
if (initialSize == 0)
{
initialSize = 1;
}
m_allocated = initialSize;
m_used = 0;
m_array = new T[m_allocated];
}
protected:
int m_allocated;
int m_used;
T* m_array;
};
template <class T> DRBASECLASS(DrArrayList)
{
public:
DrArrayList()
{
Initialize(1);
}
DrArrayList(int initialSize)
{
Initialize(initialSize);
}
~DrArrayList()
{
Clear();
delete [] m_array;
}
void Add(T t)
{
if (m_used == m_allocated)
{
m_allocated *= 2;
unsigned char* newArray = new unsigned char[m_allocated * (int) sizeof(T)];
memcpy(newArray, m_array, m_used * (int) sizeof(T));
delete [] m_array;
m_array = newArray;
}
DrAssert(m_used < m_allocated);
void* insertLocation = &(m_array[m_used * (int) sizeof(T)]);
::new (insertLocation) T(t);
++m_used;
}
void RemoveAt(int element)
{
DrAssert(element < m_used);
int i;
for (i=element+1; i<m_used; ++i)
{
unsigned char* srcLocation = &(m_array[i * (int) sizeof(T)]);
unsigned char* dstLocation = &(m_array[(i-1) * (int) sizeof(T)]);
T* srcPtr = (T*) srcLocation;
T* dstPtr = (T*) dstLocation;
(*dstPtr) = (*srcPtr);
}
--m_used;
unsigned char* removeLocation = &(m_array[m_used * (int) sizeof(T)]);
T* removePtr = (T*) removeLocation;
(*removePtr).T::~T();
}
T& operator[](int element)
{
DrAssert(element < m_used);
unsigned char* location = &(m_array[element * (int) sizeof(T)]);
T* ptr = (T*) location;
return *ptr;
}
void Clear()
{
while (m_used > 0)
{
RemoveAt(m_used - 1);
}
}
int Size()
{
return m_used;
}
void Sort(DrComparer<T>* comparer)
{
::qsort_s(m_array, m_used, sizeof(T), DrComparer<T>::CompareUntyped, comparer);
}
private:
void Initialize(int initialSize)
{
if (initialSize == 0)
{
initialSize = 1;
}
m_allocated = initialSize;
m_used = 0;
m_array = new unsigned char[m_allocated * (int) sizeof(T)];
}
protected:
int m_allocated;
int m_used;
unsigned char* m_array;
};
#endif
#define DRMAKEARRAYLIST(T_) typedef DrArrayList<T_> T_##List; \
typedef DrArrayRef<T_##List,T_> T_##ListRef; typedef T_##List* T_##ListPtr; typedef T_##List& T_##ListR; \
template class DrArrayList<T_>
#define DRMAKEVWARRAYLIST(T_) typedef DrArrayList<T_> T_##List; \
typedef DrArrayRef<T_##List,T_> T_##ListRef; typedef T_##List* T_##ListPtr; typedef T_##List& T_##ListR; \
template class DrArrayList<T_>
#endif
typedef DrArrayList<BYTE> DrByteArrayList;
DRAREF(DrByteArrayList,BYTE);
template DRDECLARECLASS(DrArrayList<BYTE>);
typedef DrArrayList<int> DrIntArrayList;
DRAREF(DrIntArrayList,int);
template DRDECLARECLASS(DrArrayList<int>);
DRMAKEVWARRAYLIST(DrString);