|
/**
* Common template classes
*
* This source code is free and anyone can copy, pirate or distribute
* the code without prior written or vocal permission.
*
* This software is provided "AS IS" and without any express or implied
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose are disclaimed.
*
* Written By: Pradeep Chulliyan
* Dated: June 07 2006
*/
#ifndef __STDTMPL_H__
#define __STDTMPL_H__
// Pointer wrapper class
//
template <typename T> class CPtr
{
// Constructors and destructor
//
public:
CPtr() : m_len (0), m_ptr (0) {}
virtual ~CPtr() {}
// Public methods
//
public:
// Return the internal pointer
//
operator T*() {return m_ptr;}
operator const T*() {return m_ptr;}
// Return the current size
//
int GetSize() const {return m_len;}
// Return the pointer
//
T* GetPtr() {return m_ptr;}
// Shared attributes
//
protected:
int m_len;
T* m_ptr;
};
// Automatic pointer
//
template <typename T> class CAutoPtr : public CPtr<T>
{
// Constructors and destructor
//
public:
CAutoPtr (int l) : CPtr<T>() {GetPtr (l);}
virtual ~CAutoPtr() {if (this->m_ptr) ::free (this->m_ptr);}
// Public methods
//
public:
// Return a pointer to the item in the array
//
T* operator[] (int d) {return (d < 0 ? 0 : &this->m_ptr[d]);}
// Return a buffer of at least 'len' size. Re-allocate the pointer
// if the previous size is less than 'len'.
//
T* GetPtr (int len)
{
if (len > this->m_len)
{
// Allocate a new buffer
//
T* ptr = (T*)::malloc (len * sizeof (T));
// Copy the old buffer to the new one
//
if (this->m_ptr)
{
if (ptr)
memcpy (ptr, this->m_ptr, this->m_len * sizeof (T));
::free (this->m_ptr);
}
this->m_ptr = ptr;
this->m_len = len;
}
return this->m_ptr;
}
};
// Sorted list that supports binary search. This list cannot hold duplicate
// entries.
//
template <typename T> class CSortedList : public CAutoPtr<T>
{
// Constructors and destructor
//
public:
CSortedList (int l) : CAutoPtr<T> (l), m_cnt (0), m_off (0), m_grn (32) {}
virtual ~CSortedList() {}
// Public methods
//
public:
// Set the number of items in the list
//
void SetCount (int cnt) {m_cnt = cnt;}
// Set an offset for the list
//
void SetOffset (int off) {m_off = off;}
// Set growth granularity
//
void SetGrowBy (int val) {m_grn = val;}
// Return the number of items in the list
//
int GetCount() {return m_cnt;}
// Clear the list
//
void Clear() {m_cnt = 0;}
// Locate a value in the list
//
int Locate (const T* v)
{
int idx = 0;
return Locate (v, true, idx);
}
// Locate an item in the list. If the value of 'exact' is true, then
// return value will be -1 if an exact match is not found.
//
int Locate (const T* v, bool exact, int& idx)
{
int tst = -1;
if (m_cnt > 0)
{
int fst = m_off;
int lst = m_off + m_cnt;
idx = (fst + lst) / 2;
tst = Compare (v, &this->m_ptr[idx]);
do
{
if (tst < 0)
lst = idx;
else if (tst > 0)
fst = idx;
else
break;
idx = (fst + lst) / 2;
tst = Compare (v, &this->m_ptr[idx]);
}
while (tst && idx > fst);
}
else
idx = m_off;
// Return the index
//
return ((tst && exact) ? -1 : idx);
}
// Insert a value into the sorted list. If the 'idx' has a valid value,
// then the item will be inserted at that index
//
void Insert (const T* v, int idx = -1)
{
if (idx < 0)
Locate (v, false, idx);
if (idx < (m_off + m_cnt))
{
int tst = Compare (v, &this->m_ptr[idx]);
if (tst == 0)
return;
if (tst > 0)
idx++;
// Expand array
//
if ((m_off + m_cnt) == this->m_len)
{
Expand();
}
// Move data
//
tst = m_off + m_cnt;
while (idx < tst)
{
memcpy (&this->m_ptr[tst], &this->m_ptr[tst-1], sizeof (T));
tst--;
}
}
if (idx >= this->m_len)
Expand();
memcpy (&this->m_ptr[idx], v, sizeof (T));
m_cnt++;
}
// Remove an element from the list. If the value of 'idx' is valid,
// this method will remove the element from the given index.
//
bool Remove (const T* v, int idx = -1)
{
if (idx < 0)
idx = Locate (v);
if (idx >= 0 && idx < (m_off + m_cnt))
{
int l = (m_cnt + m_off - idx - 1) * sizeof (T);
if (l > 0)
memcpy (&this->m_ptr[idx], &this->m_ptr[idx + 1], l);
m_cnt--;
return true;
}
return false;
}
// Shared attributes
//
protected:
int m_cnt; // Number of elements
int m_off; // Offset of the list
int m_grn; // Growth granularity
protected:
// Comparison function
//
virtual int Compare (const T* v1, const T* v2) = 0;
private:
// Expand array
//
void Expand()
{
int g = m_grn - 1;
g = (max (m_grn, (this->m_len / 8)) + g) & ~g;
GetPtr (this->m_len + g);
}
};
// Handle encapsulation class
//
class CHandle
{
public:
CHandle (HANDLE h = INVALID_HANDLE_VALUE) : m_hdl (h) {}
virtual ~CHandle() {Close();}
// Close handle
//
void Close()
{
if (IsValid())
{
::CloseHandle (m_hdl);
m_hdl = 0;
}
}
// Cast operator
//
operator HANDLE() const {return m_hdl;}
// Assign a handle
//
void operator = (HANDLE h) {m_hdl = h;}
// Check if the handle is a valid handle or not
//
bool IsValid() {return (m_hdl && m_hdl != INVALID_HANDLE_VALUE);}
protected:
HANDLE m_hdl;
};
// This class encapsulates a contiguous block of memory
//
class CMemory : public CPtr<BYTE>
{
public:
// Convert OFFSET to pointer
//
inline void* ToPtr (DWORD off) const
{
if (off < (DWORD)this->m_len)
return &this->m_ptr[off];
return 0;
}
// Convert a pointer to offset
//
inline DWORD ToOffset (const void* ptr) const
{
if (IsPtr (ptr))
return (DWORD)(((BYTE*)ptr) - this->m_ptr);
return (DWORD)-1;
}
// Check if the pointer is a valid pointer within the memory block
//
inline bool IsPtr (const void* ptr) const
{
return (this->m_ptr <= ptr &&
ptr < &this->m_ptr[this->m_len]);
}
// Commit a block of memory
//
virtual bool Commit (void* ptr, int len) {return true;}
};
#endif // __STDTMPL_H__
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I have been writing code for a living for last three hundred years! I have written code in almost all the languages- C/C++, JAVA, C#, VB, Pascal, Delphi, JScript and so on.