windows-nt/Source/XPSP1/NT/net/ias/mmc/proxy/objvec.h
2020-09-26 16:20:57 +08:00

163 lines
3.7 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, Microsoft Corp. All rights reserved.
//
// FILE
//
// objvec.h
//
// SYNOPSIS
//
// Declares the class ObjectVector.
//
// MODIFICATION HISTORY
//
// 02/08/2000 Original version.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef OBJVEC_H
#define OBJVEC_H
#if _MSC_VER >= 1000
#pragma once
#endif
///////////////////////////////////////////////////////////////////////////////
//
// CLASS
//
// ObjectVector<T>
//
// DESCRIPTION
//
// Maintains an array of reference counted objects.
//
///////////////////////////////////////////////////////////////////////////////
template <class T>
class ObjectVector
{
public:
typedef int (__cdecl *SortFn)(
const T* const* t1,
const T* const* t2
) throw ();
ObjectVector() throw ()
: first(NULL), last(NULL), cap(NULL)
{ }
~ObjectVector() throw ()
{
clear();
delete[] first;
}
// Removes and releases all the objects in the array, but doesn't release
// the array itself, i.e., after this call size() will return zero but
// capacity() is unchanged.
void clear() throw ()
{
while (last > first) (*--last)->Release();
}
bool contains(T* elem) throw ()
{
for (T** i = first; i != last; ++i)
{
if (*i == elem) { return true; }
}
return false;
}
// Returns true if the array is empty.
bool empty() const throw ()
{ return first == last; }
bool erase(T* elem) throw ()
{
for (T** i = first; i != last; ++i)
{
if (*i == elem)
{
--last;
memmove(i, i + 1, (last - i) * sizeof(T*));
return true;
}
}
return false;
}
// Add 'elem' to the end of the array, resizing if necessary.
void push_back(T* elem)
{
if (last == cap) { reserve(empty() ? 1 : capacity() * 2); }
(*last++ = elem)->AddRef();
}
// Reserve space for at least 'nelem' items in the array. Useful to avoid
// lots of resizing when you know in advance how many items you're planning
// to store.
void reserve(size_t nelem)
{
if (nelem > capacity())
{
T** t = new (AfxThrow) T*[nelem];
memcpy(t, first, size() * sizeof(T*));
last = t + size();
cap = t + nelem;
delete[] first;
first = t;
}
}
void sort(SortFn pfn) throw ()
{ qsort((void*)begin(), size(), sizeof(T*), (CompFn)pfn); }
// Swap the contents of this with v.
void swap(ObjectVector& v) throw ()
{
T** firstTmp = first;
T** lastTmp = last;
T** capTmp = cap;
first = v.first;
last = v.last;
cap = v.cap;
v.first = firstTmp;
v.last = lastTmp;
v.cap = capTmp;
}
// Returns the capacity of the array.
size_t capacity() const throw ()
{ return cap - first; }
// Returns the number of objects stored in the array.
size_t size() const throw ()
{ return last - first; }
typedef T* const* iterator;
// Methods to iterate the array elements.
iterator begin() const throw ()
{ return first; }
iterator end() const throw ()
{ return last; }
T* operator[](size_t index) const throw ()
{ return first[index]; }
private:
typedef int (__cdecl *CompFn)(const void*, const void*);
T** first; // Begining of the array.
T** last; // End of the elements.
T** cap; // End of allocated storage.
// Not implemented.
ObjectVector(const ObjectVector&);
ObjectVector& operator=(const ObjectVector&);
};
#endif // OBJVEC_H