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

265 lines
5.5 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, Microsoft Corp. All rights reserved.
//
// FILE
//
// iasobj.h
//
// SYNOPSIS
//
// Declares the classes ObjectPointer and ObjectVector for manipulating
// reference counted objects.
//
// MODIFICATION HISTORY
//
// 02/08/2000 Original version.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef IASOBJ_H
#define IASOBJ_H
#if _MSC_VER >= 1000
#pragma once
#endif
#include <iaswin32.h>
///////////////////////////////////////////////////////////////////////////////
//
// CLASS
//
// ObjectPointer<T>
//
// DESCRIPTION
//
// Smart pointer to a reference counted object. This is useful because it
// doesn't require the object to derive from IUnknown like the ATL or VC
// smart pointers.
//
///////////////////////////////////////////////////////////////////////////////
template <class T>
class ObjectPointer
{
public:
ObjectPointer() throw ()
: p(NULL)
{ }
ObjectPointer(T* lp, bool addRef = true) throw ()
: p(lp)
{ if (addRef) _addref(); }
ObjectPointer(const ObjectPointer& lp) throw ()
: p(lp.p)
{ _addref(); }
T* operator=(T* lp) throw ()
{
attach(lp);
return p;
}
ObjectPointer& operator=(const ObjectPointer& lp) throw ()
{
if (this != &lp) attach(lp.p);
return *this;
}
~ObjectPointer() throw ()
{ _release(); }
operator T*() const throw ()
{ return p; }
T* operator->() const throw ()
{ return p; }
T& operator*() const throw ()
{ return *p; }
bool operator!() const throw ()
{ return p == NULL; }
void attach(T* lp) throw ()
{
_release();
p = lp;
_addref();
}
void release() throw ()
{
_release();
p = NULL;
}
private:
// Safe versions of AddRef and Release.
void _addref() throw ()
{ if (p) { p->AddRef(); } }
void _release() throw ()
{ if (p) { p->Release(); } }
T* p;
};
///////////////////////////////////////////////////////////////////////////////
//
// CLASS
//
// ObjectVector<T>
//
// DESCRIPTION
//
// Maintains an array of reference counted objects.
//
///////////////////////////////////////////////////////////////////////////////
template <class T>
class ObjectVector
{
public:
typedef T* const* iterator;
typedef int (__cdecl *SortFn)(
const T* const* t1,
const T* const* t2
) throw ();
typedef int (__cdecl *SearchFn)(
const void* key,
const T* const* t
) throw ();
ObjectVector() throw ()
: first(NULL), last(NULL), cap(NULL)
{ }
ObjectVector(const ObjectVector& v)
: first(NULL), last(NULL), cap(NULL)
{ assign(v.begin(), v.end()); }
ObjectVector(iterator first, iterator last)
: first(NULL), last(NULL), cap(NULL)
{ assign(first, last); }
ObjectVector(size_t nelem)
: first(NULL), last(NULL), cap(NULL)
{ reserve(nelem); }
ObjectVector& operator=(const ObjectVector& v)
{
if (this != &v) { assign(v.begin(), v.end()); }
return *this;
}
~ObjectVector() throw ()
{
clear();
delete[] first;
}
void assign(iterator i1, iterator i2)
{
reserve(i2 - i1);
clear();
for (iterator i = i1; i != i2; ++i)
{ (*last++ = *i)->AddRef(); }
}
// Returns the capacity of the array.
size_t capacity() const throw ()
{ return cap - first; }
void clear() throw ()
{ while (last > first) (*--last)->Release(); }
bool contains(T* elem) throw ()
{ return find(elem) != last; }
bool empty() const throw ()
{ return last == first; }
iterator erase(iterator i) throw ()
{
memmove((void*)i, (void*)(i + 1), (--last - i) * sizeof(T*));
return i;
}
iterator find(T* elem) throw ()
{
for (iterator i = first; i != last && *i != elem; ++i) { }
return i;
}
void push_back(T* elem) throw ()
{
if (last == cap) { reserve(empty() ? 1 : capacity() * 2); }
(*last++ = elem)->AddRef();
}
bool remove(T* elem) throw ()
{
iterator i = find(elem);
if (i == last) { return false; }
(*i)->Release();
return true;
}
void reserve(size_t nelem)
{
if (nelem > capacity())
{
T** t = new T*[nelem];
memcpy(t, first, size() * sizeof(T*));
last = t + size();
cap = t + nelem;
delete[] first;
first = t;
}
}
T* search(const void* key, SearchFn pfn) const throw ()
{
T** t = (T**)bsearch(key, begin(), size(), sizeof(T*), (CompFn)pfn);
return t ? *t : NULL;
}
size_t size() const throw ()
{ return last - first; }
void sort(SortFn pfn) throw ()
{ qsort((void*)begin(), size(), sizeof(T*), (CompFn)pfn); }
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;
}
// 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;
T** last;
T** cap;
};
#endif // IASOBJ_H