⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smartptr.cpp

📁 Windows Mobile平台上使用GDI+。GDI+功能很强大
💻 CPP
字号:
////////////////////////////////////////////////////////////////////////////////// The Loki Library// Copyright (c) 2001 by Andrei Alexandrescu// Copyright (c) 2006 Richard Sposato// This code accompanies the book:// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.// Permission to use, copy, modify, distribute and sell this software for any //     purpose is hereby granted without fee, provided that the above  copyright //     notice appear in all copies and that both that copyright notice and this //     permission notice appear in supporting documentation.// The author or Addison-Wesley Longman make no representations about the //     suitability of this software for any purpose. It is provided "as is" //     without express or implied warranty.////////////////////////////////////////////////////////////////////////////////// $Id: SmartPtr.cpp 756 2006-10-17 20:05:42Z syntheticpp $#include "SmartPtr.h"#include <cassert>//#define DO_EXTRA_LOKI_TESTS#ifdef DO_EXTRA_LOKI_TESTS    #include <iostream>#endif// ----------------------------------------------------------------------------namespace Loki{namespace Private{// ----------------------------------------------------------------------------RefLinkedBase::RefLinkedBase(const RefLinkedBase& rhs) {    prev_ = &rhs;    next_ = rhs.next_;    prev_->next_ = this;    next_->prev_ = this;#ifdef DO_EXTRA_LOKI_TESTS    assert( prev_->HasPrevNode( this ) );    assert( next_->HasNextNode( this ) );    assert( CountPrevCycle( this ) == CountNextCycle( this ) );#endif}// ----------------------------------------------------------------------------bool RefLinkedBase::Release(){#ifdef DO_EXTRA_LOKI_TESTS    assert( prev_->HasPrevNode( this ) );    assert( next_->HasNextNode( this ) );    assert( CountPrevCycle( this ) == CountNextCycle( this ) );#endif    if ( NULL == next_ )    {        assert( NULL == prev_ );        // Return false so it does not try to destroy shared object        // more than once.        return false;    }    else if (next_ == this)    {           assert(prev_ == this);        // Set these to NULL to prevent re-entrancy.        prev_ = NULL;        next_ = NULL;        return true;    }#ifdef DO_EXTRA_LOKI_TESTS    assert( this != prev_ );    assert( NULL != prev_ );    assert( prev_->HasPrevNode( this ) );    assert( next_->HasNextNode( this ) );#endif    prev_->next_ = next_;    next_->prev_ = prev_;#ifdef DO_EXTRA_LOKI_TESTS    next_ = this;    prev_ = this;    assert( 1 == CountNextCycle( this ) );    assert( 1 == CountPrevCycle( this ) );#endif    return false;}// ----------------------------------------------------------------------------void RefLinkedBase::Swap(RefLinkedBase& rhs){#ifdef DO_EXTRA_LOKI_TESTS    assert( prev_->HasPrevNode( this ) );    assert( next_->HasNextNode( this ) );    assert( CountPrevCycle( this ) == CountNextCycle( this ) );#endif    if (next_ == this)    {        assert(prev_ == this);        if (rhs.next_ == &rhs)        {            assert(rhs.prev_ == &rhs);            // both lists are empty, nothing 2 do            return;        }        prev_ = rhs.prev_;        next_ = rhs.next_;        prev_->next_ = next_->prev_ = this;        rhs.next_ = rhs.prev_ = &rhs;        return;    }    if (rhs.next_ == &rhs)    {        rhs.Swap(*this);        return;    }    if (next_ == &rhs ) // rhs is next neighbour    {        if ( prev_ == &rhs )            return;  // cycle of 2 pointers - no need to swap.        std::swap(prev_, next_);        std::swap(rhs.prev_, rhs.next_);        std::swap(rhs.prev_, next_);        std::swap(rhs.prev_->next_,next_->prev_);    }    else if ( prev_ == &rhs ) // rhs is prev neighbor    {        if ( next_ == &rhs )            return;  // cycle of 2 pointers - no need to swap.        std::swap( prev_, next_ );        std::swap( rhs.next_, rhs.prev_ );        std::swap( rhs.next_, prev_ );        std::swap( rhs.next_->prev_, prev_->next_ );    }    else // not neighhbors    {        std::swap(prev_, rhs.prev_);        std::swap(next_, rhs.next_);        std::swap(prev_->next_, rhs.prev_->next_);        std::swap(next_->prev_, rhs.next_->prev_);    }#ifdef DO_EXTRA_LOKI_TESTS    assert( next_ == this ? prev_ == this : prev_ != this);    assert( prev_ == this ? next_ == this : next_ != this);    assert( prev_->HasPrevNode( this ) );    assert( next_->HasNextNode( this ) );    assert( CountPrevCycle( this ) == CountNextCycle( this ) );    assert( rhs.prev_->HasPrevNode( &rhs ) );    assert( rhs.next_->HasNextNode( &rhs ) );    assert( CountPrevCycle( &rhs ) == CountNextCycle( &rhs ) );#endif}// ----------------------------------------------------------------------------unsigned int RefLinkedBase::CountPrevCycle( const RefLinkedBase * pThis ){    if ( NULL == pThis )        return 0;    const RefLinkedBase * p = pThis->prev_;    if ( NULL == p )        return 0;    if ( pThis == p )        return 1;    unsigned int count = 1;    do    {        p = p->prev_;        ++count;    } while ( p != pThis );    return count;}// ----------------------------------------------------------------------------unsigned int RefLinkedBase::CountNextCycle( const RefLinkedBase * pThis ){    if ( NULL == pThis )        return 0;    const RefLinkedBase * p = pThis->next_;    if ( NULL == p )        return 0;    if ( pThis == p )        return 1;    unsigned int count = 1;    while ( p != pThis )    {        p = p->next_;        ++count;    }    return count;}// ----------------------------------------------------------------------------bool RefLinkedBase::HasPrevNode( const RefLinkedBase * p ) const{    if ( this == p )        return true;    const RefLinkedBase * prev = prev_;    if ( NULL == prev )        return false;    while ( prev != this )    {        if ( p == prev )            return true;        prev = prev->prev_;    }    return false;}// ----------------------------------------------------------------------------bool RefLinkedBase::HasNextNode( const RefLinkedBase * p ) const{    if ( this == p )        return true;    const RefLinkedBase * next = next_;    if ( NULL == next )        return false;    while ( next != this )    {        if ( p == next )            return true;        next = next->next_;    }    return false;}// ----------------------------------------------------------------------------bool RefLinkedBase::Merge( RefLinkedBase & rhs ){    if ( NULL == next_ )    {        assert( NULL == prev_ );        return false;    }    RefLinkedBase * prhs = &rhs;    if ( prhs == this )        return true;    if ( NULL == prhs->next_ )    {        assert( NULL == prhs->prev_ );        return true;    }    assert( CountPrevCycle( this ) == CountNextCycle( this ) );    assert( CountPrevCycle( prhs ) == CountNextCycle( prhs ) );    // If rhs node is already in this cycle, then no need to merge.    if ( HasPrevNode( &rhs ) )    {        assert( HasNextNode( &rhs ) );        return true;    }    if ( prhs == prhs->next_ )    {        /// rhs is in a cycle with 1 node.        assert( prhs->prev_ == prhs );        prhs->prev_ = prev_;        prhs->next_ = this;        prev_->next_ = prhs;        prev_ = prhs;    }    else if ( this == next_ )    {        /// this is in a cycle with 1 node.        assert( prev_ == this );        prev_ = prhs->prev_;        next_ = prhs;        prhs->prev_->next_ = this;        prhs->prev_ = this;    }    else    {        next_->prev_ = prhs->prev_;        prhs->prev_->next_ = prev_;        next_ = prhs;        prhs->prev_ = this;    }    assert( CountPrevCycle( this ) == CountNextCycle( this ) );    return true;}// ----------------------------------------------------------------------------} // end namespace Private} // end namespace Loki

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -