STLVisual C++ 7.1Visual Studio 6Visual C++ 7.0Windows 2003Windows 2000Visual C++ 6.0Windows XPIntermediateDevVisual StudioWindowsC++
safedeque - easy to use stl::deque






2.17/5 (12 votes)
Jan 20, 2004

48706

444
safedeque shows the way to use deque with cslock and smart pointer.
Introduction
I think deque is better than vector or list. Because, deque can be used to iterate elements like vector []
operator. And it can push/pop at start/end.
The advantages of safedeque are:
- it works with smart pointer basically.
- easy sample function
add
/del
, andfind
with critical section lock. - it shows the common ways to search for class member.
Using safedeque
// sample data class class a { public: a( int a,LPCTSTR b) { x = a; s = b; } int x; CString s; // member find sample member functions static bool by_x( a* x, int s ) { return x->x == s; } static bool by_s( a* x, char* p ) { return x->s == p; } }; safe_deque< a > sd; // no need to delete ( smartpointer is internally working ) sd.add( new a(1,"hello") ); sd.add( new a(2,"world") ); //_sp<a>* spa = new a; // it's ok // sd.add( spa ); // it's ok // find in member a* p2 = sd.find( a::by_x, 1 ); TRACE(_T("%d\r\n"), p2->x ); a* p3 = sd.find( a::by_s, "hello" ); // it's ok //a* p3 = sd.find( a::by_s, "Hello" ).get(); // also, it's ok TRACE(_T("%s\r\n"), p3->s ); // it's deque spec ( iterating, surely you can use iterator ) for( int i = 0 ; i < sd.size(); i ++ ) { int x = sd[i]->x; a* pa = sd[i]; int x2 = pa->x; } sd.del( p2 ); // delete element.. automatically object destruct
Source
Source code is short, so you can use it by copy-n-paste.
safedeque.h
#include "sp.h" #include <deque> #include <algorithm> class cslock { public: CRITICAL_SECTION cs; cslock(){ InitializeCriticalSection( &cs ); } ~cslock(){ DeleteCriticalSection( &cs ); } void lock(){ EnterCriticalSection( &cs ); } void unlock(){ LeaveCriticalSection( &cs ); } }; // 2003-12-12 : first code. // by Cho, Kyung Min - nick: bro (bro@shinbiro.com) // // - easy to use // - lock/unlock with criticalsection // - safe termination with sp ( smart pointer ) // - support search function with member variables template<class T > class safe_deque : public std::deque< _sp<T> >, public cslock { public: void add( const _sp<T>& x ) { lock(); __try { push_back(x); }__finally { unlock(); } } void del( const _sp<T>& x ) { lock(); __try { iterator it = std::find(begin(), end(), x); if( it != end() ) erase( it ); }__finally { unlock(); } } void del( const T* x ) { lock(); _try { for( iterator it = begin(); it != end(); ++(it) ) if( (*it).get() == x ){ erase( it ); break; } }__finally { unlock(); } } template <class M> _sp<T>& find( bool (*compare)( T* x, M m), M _m ) { lock(); __try { for( iterator it = begin(); it != end(); ++(it) ) if( compare( (*it).get(), _m ) ) return (*it); }__finally { unlock(); } static _sp<T> spNull; return spNull; } };
and, sp.h
////////////////////////////////////////////////////////////////// // smart pointer version: 1.0 // by bro ( bro@shinbiro.com ) 2003-07-07 // std::auto_ptr is not safe for return value of function. template <class _T> class _sp { private: class obj { public: obj(_T* _p){ ref = 0; p = _p; addref(); } ~obj(){ release(); } void addref(){ ref++; } _T* get(){ return p; } void release() { if( --ref == 0 ) { if( p ) { delete p; p=0; } delete this; } } _T* p; int ref; }; obj* _o; public: _sp() { _o = 0; } _sp( bool bNew ) { bNew ? _o = new obj(new _T) : _o = 0; } _sp( int bNew ) { bNew ? _o = new obj(new _T) : _o = 0; } _sp(_T* p) { _o = new obj(p); } ~_sp() { if( _o ) _o->release(); } _sp(const _T*& p) { _o = new obj(p); } _sp( const _sp<_T>& sp2 ) { _o = sp2._o; if(_o)_o->addref(); } _sp& operator = ( const _sp& sp2 ) { if( this == &sp2 ) return *this; if( _o ) _o->release(); _o = sp2._o; if(_o)_o->addref(); return *this; } _sp& operator = ( _T* p ) { if( _o ) if( _o->p == p ) return *this; if( _o ) _o->release(); if( !p ){ _o = 0; return *this; } _o = new obj(p); return *this; } _T& operator*() const { return *get(); } _T *operator->() const {return get(); } _T *get() const { if(!_o) return NULL; return _o->p; } operator _T*() { return get(); } operator bool() { if( _o && _o->p ) return true; return false; } friend bool operator==(const _sp<_T>& sp1, const _sp<_T>& sp2); friend bool operator==(const _sp<_T>& sp, const _T* p); friend bool operator==(const _sp<_T>& sp, int n); bool operator !() { return !operator bool(); } }; template<class _T> inline bool operator==(const _sp<_T>& sp1, const _sp<_T>& sp2) { if( sp1._o && sp2._o ) return (sp1._o->p == sp2._o->p); return false; } template<class _T> inline bool operator==(const _sp<_T>& sp, const _T* p) { if( sp->_o ) return ( sp->_o->p == p ); return false;} template<class _T> inline bool operator==(const _sp<_T>& sp, int n) { int tmp = 0; if( !sp._o ) tmp = 0; else { if( !sp._o->p ) tmp = 0; else tmp = (int)(sp._o->p); } return (tmp == n ); }