#include "stdafx.h"
#ifndef WIN32
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef pthread_mutex_t vmutex_t;
#else
#include <windows.h>
typedef CRITICAL_SECTION vmutex_t;
#endif
///////////////////////////////////////////////////////////
class Mutex
{
public:
Mutex(void);
virtual ~Mutex(void);
public:
virtual void lock();
virtual void unlock();
vmutex_t * getId() const;
protected:
mutable vmutex_t myId;
};
Mutex::Mutex(void)
{
#ifndef WIN32
pthread_mutex_init(&myId, NULL);
#else
InitializeCriticalSection(&myId);
#endif
}
Mutex::~Mutex(void)
{
#ifndef WIN32
pthread_mutex_destroy(&myId);
#else
DeleteCriticalSection(&myId);
#endif
}
void Mutex::lock()
{
#ifndef WIN32
pthread_mutex_lock(&myId);
#else
EnterCriticalSection(&myId);
#endif
}
void Mutex::unlock()
{
#ifndef WIN32
pthread_mutex_unlock(&myId);
#else
LeaveCriticalSection(&myId);
#endif
}
vmutex_t * Mutex::getId() const
{
return ( &myId );
}
///////////////////////////////////////////
#ifndef INLINE_
#define INLINE_ inline
#endif
#define VLOCK() mutex.lock()
#define VUNLOCK() mutex.unlock()
#define INC(x) ++x
#define DEC(x) --x
#define DEC_AND_CMP(x,r) --x,r = (x == 0)
#define EXCHANGE(ptr,val) void* tmp; tmp = *ptr,*ptr = val, val = tmp
class CountSemaphore
{
public:
/// constructor
INLINE_ explicit CountSemaphore(int value=0)
:mutex(),count(value)
{}
/** compares the current value in the reference count to
* value. returns true if equal.
* @param value integer to compare against.
*/
INLINE_ bool compare(int value)
{
bool retVal = false;
VLOCK();
if (value == count) retVal = true;
VUNLOCK();
return retVal;
}
/** increment the reference count by one. This operation is atomic.
*/
INLINE_ void increment()
{
VLOCK();
INC(count);
VUNLOCK();
}
/** decrement the reference count by one. This operation is
* atomic. If the reference count now equals 0, decrement
* returns true.
*/
INLINE_ bool decrement()
{
bool retVal;
VLOCK();
DEC_AND_CMP(count, retVal);
VUNLOCK();
return retVal;
}
INLINE_ void exchange(void** ptr, void** val)
{
VLOCK();
EXCHANGE(ptr, *val);
VUNLOCK();
}
INLINE_ int getCount() const
{
return count;
}
bool operator==(int value) const
{
return (value == count);
}
void lock()
{
VLOCK();
}
void unlock()
{
VUNLOCK();
}
private:
/// suppress copying
CountSemaphore(const CountSemaphore* pvalue);
/// suppress copying
const CountSemaphore& operator=(const CountSemaphore* pvalue);
/// suppress comparison
bool operator==(const CountSemaphore* pvalue);
Mutex mutex;
volatile int count; // why is this volatile ?
};
CountSemaphore::CountSemaphore(const CountSemaphore* pvalue)
:mutex(),count(0)
{
count = pvalue->getCount();
}
const CountSemaphore& CountSemaphore::operator=(const CountSemaphore* pvalue)
{
int icount = pvalue->getCount();
VLOCK();
count = icount;
VUNLOCK();
return *this;
}
bool CountSemaphore::operator==(const CountSemaphore* pvalue)
{
int icount = pvalue->getCount();
return count == icount;
}
/////////////////////////////////////////////////////////
template < class T >
class Sptr
{
// we need to work around Visual C++'s limitations. this
// is needed so that we can grab these bits directly
private:
mutable T* ptr;
mutable CountSemaphore* count;
public:
/// increment the reference count.
void increment()
{
if (ptr)
{
if (!count)
{
count = new CountSemaphore();
}
count->increment();
}
}
/// decrement the reference count
void decrement()
{
if (ptr && count)
{
if(count->decrement())
{
delete ptr;
delete count;
}
}
ptr = 0;
count = 0;
}
/** conversion operator converts pointers of this const class
* to class const Sptr< T2 >., where T2 is a different base
* class. This is most often used when attempting to call a
* const method of the base class through a derived class
* pointer. This is a workaround for SUNPRO .
*/
template < class T2 >
operator const Sptr<T2 > () const
{
return Sptr < T2 > (ptr, count);
}
/// default constructor. points to NULL.
Sptr() : ptr(0), count(0)
{}
;
/** constructor used most often as the constructor from a
* plain pointer. Do not use this to convert a single pointer
* to a smart pointer multiple times -- this will result in an
* error (see class introduction for details).
*/
Sptr(T* original, CountSemaphore* myCount = 0)
: ptr(original), count(myCount)
{
if (ptr)
{
increment();
}
};
/** copy constructor
*/
Sptr(const Sptr& x)
: ptr(x.ptr), count(x.count)
{
increment();
};
/// destructor
~Sptr()
{
{
decrement();
}
}
/// dereference operator
T& operator*() const
{
return *ptr;
}
/// ! operator . Returns true if ptr == 0, false otherwise.
int operator!() const
{
if (ptr)
{
return (ptr == 0);
}
else
return true;
}
/// pointer operator.
T* operator->() const
{
return ptr;
}
template < class T2 > Sptr& dynamicCast(const Sptr < T2 > & x)
{
if (ptr == x.getPtr()) return *this;
decrement();
if(T* p = dynamic_cast < T* > (x.getPtr()))
{
count = x.getCount();
ptr = p;
increment();
}
return *this;
}
/** assignment operator -- this is most often used to assign
* from a smart pointer to a derived type to a smart pointer
* of the base type.
*/
template < class T2 >
Sptr& operator=(const Sptr < T2 > & x)
{
if (ptr == x.getPtr()) return * this;
decrement();
ptr = x.getPtr();
count = x.getCount();
increment();
return *this;
}
/** assignment operator from plain pointer. Do not use this
* to convert a single pointer to a smart pointer multiple
* times -- this will result in an error (see class
* introduction for details).
*/
Sptr& operator=(T* original)
{
if (ptr == original) return * this;
decrement();
ptr = original;
increment();
return *this;
};
/// assignment operator
Sptr& operator=(const Sptr& x)
{
if (ptr == x.ptr) return * this;
decrement();
ptr = x.ptr;
count = x.count;
increment();
return *this;
}
/// compare whether a pointer and a smart pointer point to different things
friend bool operator!=(const void* y, const Sptr& x)
{
if (x.ptr != y)
return true;
else
return false;
}
/// compare whether a smart pointer and a pointer point to different things
friend bool operator!=(const Sptr& x, const void* y)
{
return (y != x);
}
/// compare whether a pointer and a smart pointer point to the same thing
friend bool operator==(const void* y, const Sptr& x)
{
if (x.ptr == y)
return true;
else
return false;
}
/// compare whether a smart pointer and a pointer point to the same thing
friend bool operator==(const Sptr& x, const void* y)
{
return (y == x);
}
/// compare whether two smart pointers point to the same thing
bool operator==(const Sptr& x) const
{
if (x.ptr == ptr)
return true;
else
return false;
}
/// compare whether two smart pointers point to the same thing
bool operator!=(const Sptr& x) const
{
return !(operator==(x));
}
/**
this interface is here because it may sometimes be
necessary. DO NOT USE unless you must use it.
get the value of the reference count of the smart pointer.
*/
CountSemaphore* getCount() const
{
return count;
}
/**
this interface is here because it may sometimes be
necessary. DO NOT USE unless you must use it.
get the pointer to which the smart pointer points.
*/
T* getPtr() const
{
return ptr;
}
};
/////////////////////////////////////////////////////////////
struct stu
{
int a;
int b;
};
struct stuc
{
int a;
int b;
};
int _tmain(int argc, _TCHAR* argv[])
{
Sptr<stu> pStu = new stu;
Sptr<stu> pStuc = pStu;
pStu->a = 10;
pStu->b = 5;
return 0;
}