Click here to Skip to main content
15,905,325 members
Articles / Programming Languages / C++
Article

safedeque - easy to use stl::deque

Rate me:
Please Sign up or sign in to vote.
2.17/5 (12 votes)
19 Jan 2004 48.3K   444   13   10
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, and find 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 );
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
Korea (Republic of) Korea (Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalrisk of skin cancer Pin
NGS 54967221-Jan-04 5:38
NGS 54967221-Jan-04 5:38 
QuestionWhy create yet another smart pointer class? Pin
Don Clugston20-Jan-04 13:45
Don Clugston20-Jan-04 13:45 
AnswerRe: Why create yet another smart pointer class? Pin
Cho, Kyung-min20-Jan-04 14:49
Cho, Kyung-min20-Jan-04 14:49 
GeneralRIIA Pin
Anonymous19-Jan-04 22:23
Anonymous19-Jan-04 22:23 
GeneralYou mean RAII? Pin
Ian Darling19-Jan-04 23:26
Ian Darling19-Jan-04 23:26 
GeneralRe: You mean RAII? Pin
Anonymous20-Jan-04 5:12
Anonymous20-Jan-04 5:12 
GeneralRe: RIIA Pin
Cho, Kyung-min20-Jan-04 15:02
Cho, Kyung-min20-Jan-04 15:02 
GeneralRAII Pin
Anonymous20-Jan-04 21:53
Anonymous20-Jan-04 21:53 
GeneralNot getting it Pin
GarethLewin19-Jan-04 21:52
GarethLewin19-Jan-04 21:52 
GeneralRe: Not getting it Pin
Cho, Kyung-min20-Jan-04 14:20
Cho, Kyung-min20-Jan-04 14:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.