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

📄 memblock.h

📁 A C++ class library for scientific computing
💻 H
字号:
// -*- C++ -*-/*************************************************************************** * blitz/memblock.h      MemoryBlock<T> and MemoryBlockReference<T> * * $Id: memblock.h,v 1.18 2005/10/11 21:54:57 julianc Exp $ * * Copyright (C) 1997-1999 Todd Veldhuizen <tveldhui@oonumerics.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * Suggestions:          blitz-dev@oonumerics.org * Bugs:                 blitz-bugs@oonumerics.org * * For more information, please see the Blitz++ Home Page: *    http://oonumerics.org/blitz/ * ***************************************************************************/#ifndef BZ_MEMBLOCK_H#define BZ_MEMBLOCK_H#include <blitz/blitz.h>#include <stddef.h>     // ptrdiff_t#ifdef BZ_THREADSAFE #include <pthread.h>#endifBZ_NAMESPACE(blitz)enum preexistingMemoryPolicy {   duplicateData,   deleteDataWhenDone,   neverDeleteData };// Forward declaration of MemoryBlockReferencetemplate<typename T_type> class MemoryBlockReference;// Class MemoryBlock provides a reference-counted block of memory.  This block// may be referred to by multiple vector, matrix and array objects.  The memory// is automatically deallocated when the last referring object is destructed.// MemoryBlock may be subclassed to provide special allocators.template<typename P_type>class MemoryBlock {    friend class MemoryBlockReference<P_type>;public:    typedef P_type T_type;protected:    MemoryBlock()    {        length_ = 0;        data_ = 0;        dataBlockAddress_ = 0;        references_ = 0;        BZ_MUTEX_INIT(mutex)    }    explicit MemoryBlock(size_t items)    {        length_ = items;        allocate(length_);#ifdef BZ_DEBUG_LOG_ALLOCATIONS    cout << "MemoryBlock: allocated " << setw(8) << length_          << " at " << ((void *)dataBlockAddress_) << endl;#endif        BZASSERT(dataBlockAddress_ != 0);        references_ = 0;        BZ_MUTEX_INIT(mutex)    }    MemoryBlock(size_t length, T_type* data)    {        length_ = length;        data_ = data;        dataBlockAddress_ = data;        references_ = 0;        BZ_MUTEX_INIT(mutex)    }    virtual ~MemoryBlock()    {        if (dataBlockAddress_)         {#ifdef BZ_DEBUG_LOG_ALLOCATIONS    cout << "MemoryBlock:     freed " << setw(8) << length_         << " at " << ((void *)dataBlockAddress_) << endl;#endif            deallocate();        }        BZ_MUTEX_DESTROY(mutex)    }    void          addReference()    {         BZ_MUTEX_LOCK(mutex)        ++references_; #ifdef BZ_DEBUG_LOG_REFERENCES    cout << "MemoryBlock:    reffed " << setw(8) << length_          << " at " << ((void *)dataBlockAddress_) << " (r="          << (int)references_ << ")" << endl;#endif        BZ_MUTEX_UNLOCK(mutex)    }    T_type* restrict      data()     {         return data_;     }    const T_type* restrict data()      const    {         return data_;     }    T_type*&      dataBlockAddress()     {         return dataBlockAddress_;     }    size_t        length()    const    {         return length_;     }    int           removeReference()    {        BZ_MUTEX_LOCK(mutex)        int refcount = --references_;#ifdef BZ_DEBUG_LOG_REFERENCES    cout << "MemoryBlock: dereffed  " << setw(8) << length_         << " at " << ((void *)dataBlockAddress_) << " (r=" << (int)references_          << ")" << endl;#endif        BZ_MUTEX_UNLOCK(mutex)        return refcount;    }    int references() const    {        BZ_MUTEX_LOCK(mutex)        int refcount = references_;        BZ_MUTEX_UNLOCK(mutex)        return refcount;    }protected:    inline void allocate(size_t length);    void deallocate();private:   // Disabled member functions    MemoryBlock(const MemoryBlock<T_type>&)    { }    void operator=(const MemoryBlock<T_type>&)    { }private:   // Data members    T_type * restrict     data_;    T_type *              dataBlockAddress_;#ifdef BZ_DEBUG_REFERENCE_ROLLOVER    volatile unsigned char references_;#else    volatile int references_;#endif    BZ_MUTEX_DECLARE(mutex)    size_t  length_;};template<typename P_type>class UnownedMemoryBlock : public MemoryBlock<P_type> {public:    UnownedMemoryBlock(size_t length, P_type* data)        : MemoryBlock<P_type>(length,data)    {        // This ensures that MemoryBlock destructor will not         // attempt to delete data        MemoryBlock<P_type>::dataBlockAddress() = 0;    }    virtual ~UnownedMemoryBlock()    {    }};template<typename P_type>class NullMemoryBlock : public MemoryBlock<P_type> {public:    NullMemoryBlock()    {         // This ensures that the delete operator will not be invoked        // on an instance of NullMemoryBlock in removeReference().        MemoryBlock<P_type>::addReference();            }    virtual ~NullMemoryBlock()      { }};template<typename P_type>class MemoryBlockReference {public:    typedef P_type T_type;protected:    T_type * restrict data_;private:    MemoryBlock<T_type>* block_;    static NullMemoryBlock<T_type> nullBlock_;public:    MemoryBlockReference()    {        block_ = &nullBlock_;        block_->addReference();        data_ = 0;    }    MemoryBlockReference(MemoryBlockReference<T_type>& ref, size_t offset=0)    {        block_ = ref.block_;        block_->addReference();        data_ = ref.data_ + offset;    }    MemoryBlockReference(size_t length, T_type* data,         preexistingMemoryPolicy deletionPolicy)    {        // Create a memory block using already allocated memory.         // Note: if the deletionPolicy is duplicateData, this must        // be handled by the leaf class.  In MemoryBlockReference,        // this is treated as neverDeleteData; the leaf class (e.g. Array)        // must duplicate the data.        if ((deletionPolicy == neverDeleteData)           || (deletionPolicy == duplicateData))            block_ = new UnownedMemoryBlock<T_type>(length, data);        else if (deletionPolicy == deleteDataWhenDone)            block_ = new MemoryBlock<T_type>(length, data);        block_->addReference();#ifdef BZ_DEBUG_LOG_ALLOCATIONS    cout << "MemoryBlockReference: created MemoryBlock at "         << ((void*)block_) << endl;#endif        data_ = data;    }    explicit MemoryBlockReference(size_t items)    {        block_ = new MemoryBlock<T_type>(items);        block_->addReference();        data_ = block_->data();#ifdef BZ_DEBUG_LOG_ALLOCATIONS    cout << "MemoryBlockReference: created MemoryBlock at "         << ((void*)block_) << endl;#endif    }    void blockRemoveReference()    {        int refcount = block_->removeReference();        if ((refcount == 0) && (block_ != &nullBlock_))        {#ifdef BZ_DEBUG_LOG_ALLOCATIONS    cout << "MemoryBlock: no more refs, delete MemoryBlock object at "         << ((void*)block_) << endl;#endif            delete block_;        }    }   ~MemoryBlockReference()    {        blockRemoveReference();    }    int numReferences() const    {        return block_->references();    }protected:    void changeToNullBlock()    {        blockRemoveReference();        block_ = &nullBlock_;        block_->addReference();        data_ = 0;    }    void changeBlock(MemoryBlockReference<T_type>& ref, size_t offset=0)    {        blockRemoveReference();        block_ = ref.block_;        block_->addReference();        data_ = ref.data_ + offset;    }    void newBlock(size_t items)    {        blockRemoveReference();        block_ = new MemoryBlock<T_type>(items);        block_->addReference();        data_ = block_->data();#ifdef BZ_DEBUG_LOG_ALLOCATIONS    cout << "MemoryBlockReference: created MemoryBlock at "         << ((void*)block_) << endl;#endif    }private:    void operator=(const MemoryBlockReference<T_type>&)    { }};BZ_NAMESPACE_END#include <blitz/memblock.cc>#endif // BZ_MEMBLOCK_H

⌨️ 快捷键说明

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