Click here to Skip to main content
Licence 
First Posted 19 Jan 2004
Views 36,612
Bookmarked 13 times

safedeque - easy to use stl::deque

By | 19 Jan 2004 | Article
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

About the Author

Cho, Kyung-min

Software Developer

Korea (Republic Of) Korea (Republic Of)

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalrisk of skin cancer PinmemberNGS 5496725:38 21 Jan '04  
QuestionWhy create yet another smart pointer class? PinmemberDon Clugston13:45 20 Jan '04  
AnswerRe: Why create yet another smart pointer class? PinmemberCho, Kyung-min14:49 20 Jan '04  
GeneralRIIA PinsussAnonymous22:23 19 Jan '04  
GeneralYou mean RAII? PinmemberIan Darling23:26 19 Jan '04  
GeneralRe: You mean RAII? PinsussAnonymous5:12 20 Jan '04  
GeneralRe: RIIA PinmemberCho, Kyung-min15:02 20 Jan '04  
GeneralRAII PinsussAnonymous21:53 20 Jan '04  
GeneralNot getting it PinmemberGarethLewin21:52 19 Jan '04  
GeneralRe: Not getting it PinmemberCho, Kyung-min14:20 20 Jan '04  

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

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 20 Jan 2004
Article Copyright 2004 by Cho, Kyung-min
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid