123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- //
- #pragma once
- #include <memory>
- #define __TmplBlockBuffer__
- ////////////////////////////////////////////////////////////////////////////////
- // TmplBuffer - 定义一个连续的内存块
- //
- // Copyright (c) 1997-2013 E-COM Technology Ltd.
- //
- // V1.0 ?? - Initial Version
- // V2.0 2019-10-31 - Use std::shared_ptr & std::unique_ptr
- // V2.1 2019-11-08 - Define TmplBuffer_Base as the base class
- // V2.2 2020-06-17 - add TmplSharedBuffer (TmplUniqueBuffer <T> && from)
- // V2.3 2022-06-02 - add TmplUniqueBuffer::Resize (int count)
- // V2.4 2022-08-01 - pass the compiler option /permissive
- // V2.3 2023-04-23 - add TmplBuffer_view
- namespace ECOM
- {
- namespace Utility
- {
- //-----------------------------------------------------------------------------
- // TmplBuffer_Base
- // 基本类
- //-----------------------------------------------------------------------------
- template <typename T, typename PTR>
- class TmplBuffer_Base
- {
- protected:
- int m_nCount; // count of data, 注意是 数量 而不是 字节 长度 !!!
- PTR m_Data;
- public:
- TmplBuffer_Base ()
- {
- m_nCount = 0;
- }
- TmplBuffer_Base (TmplBuffer_Base && from)
- {
- m_Data = std::move (from.m_Data);
- m_nCount = from.m_nCount;
- from.m_nCount = 0;
- }
- void Attach (T * object, int count)
- {
- if (! object)
- {
- m_Data.reset ();
- m_nCount = 0;
- return;
- }
- m_Data.reset (object);
- m_nCount = count;
- }
- public:
- // operator bool () const { return ! IsEmpty (); }
- operator T * () { return m_Data.get (); }
- operator const T * () const { return m_Data.get (); }
- public:
- // Allow usage as a pointer
- T * operator -> ()
- {
- return m_Data.get ();
- }
- const T * operator -> () const
- {
- return m_Data.get ();
- }
- T * As ()
- {
- return m_Data.get ();
- }
- const T * As () const
- {
- return m_Data.get ();
- }
- public:
- int GetCount () const
- {
- return m_nCount;
- }
- int GetNbOfBytes () const
- {
- return m_nCount * sizeof (T);
- }
- bool IsEmpty () const { return (m_Data.get () == nullptr); }
- public:
- void Release () { m_Data.reset (); m_nCount = 0; }
- public:
- TmplBuffer_Base & operator = (const TmplBuffer_Base & from) = delete;
- TmplBuffer_Base & operator = (TmplBuffer_Base && from) = delete;
- public:
- // MemCpy
- void MemCopyFrom (const T * from, int count);
- void MemCopyTo (T * to, int count) const;
- protected:
- T * _GetBufferSetCount (int count);
- void MoveAssign (TmplBuffer_Base & from)
- {
- m_Data = std::move (from.m_Data);
- m_nCount = from.m_nCount;
- from.m_nCount = 0;
- }
- // make a real copy
- void MemCopyTo (TmplBuffer_Base & To) const;
- void ResizeTo (int count, TmplBuffer_Base & To) const;
- };
- template <typename T>
- class TmplUniqueBuffer;
- template <typename T>
- class TmplSharedBuffer;
- //-----------------------------------------------------------------------------
- // TmplSharedBuffer
- //
- // 定义一个连续的内存块, 用 shared_ptr 定义, 因此可以在多个模块之间共享
- //-----------------------------------------------------------------------------
- template <typename T>
- class TmplSharedBuffer : public TmplBuffer_Base <T, std::shared_ptr <T>>
- {
- typedef TmplBuffer_Base <T, std::shared_ptr <T>> inherited;
- public:
- TmplSharedBuffer ()
- {
- }
- #if 1
- explicit TmplSharedBuffer (T * from, int count)
- {
- this->m_Data.reset (from);
- this->m_nCount = count;
- }
- #endif
- TmplSharedBuffer (const TmplSharedBuffer & from)
- {
- this->m_Data = from.m_Data;
- this->m_nCount = from.m_nCount;
- }
- TmplSharedBuffer (TmplSharedBuffer && from) : inherited (std::move (from))
- {
- }
- TmplSharedBuffer (TmplUniqueBuffer <T> && from);
- TmplSharedBuffer & operator = (const TmplSharedBuffer & from)
- {
- this->m_Data = from.m_Data;
- this->m_nCount = from.m_nCount;
- return *this;
- }
- TmplSharedBuffer & operator = (TmplSharedBuffer && from)
- {
- inherited::MoveAssign (from);
- return (*this);
- }
- TmplSharedBuffer & operator = (TmplUniqueBuffer <T> && from);
- public:
- T * GetBufferSetCount (int count)
- {
- return inherited::_GetBufferSetCount (count);
- }
- // return real copy
- TmplSharedBuffer Clone () const
- {
- TmplSharedBuffer <T> To;
- inherited::MemCopyTo (To);
- return std::move (To);
- }
- // 调整大小, 只要前面的 count 个对象
- // 如果要的数量比我现有的数量 (m_nCount) 多,就重新分配,然后memcpy,但填充值由上层自行决定
- TmplSharedBuffer Resize (int count) const
- {
- TmplSharedBuffer <T> To;
- inherited::ResizeTo (count, To);
- return std::move (To);
- }
- };
- //-----------------------------------------------------------------------------
- // TmplUniqueBuffer
- // 用 unique_ptr 定义, 不能共享, 但是可以转移
- //-----------------------------------------------------------------------------
- template <typename T>
- class TmplUniqueBuffer : public TmplBuffer_Base <T, std::unique_ptr <T>>
- {
- typedef TmplBuffer_Base <T, std::unique_ptr <T>> inherited;
- public:
- TmplUniqueBuffer ()
- {
- this->m_nCount = 0;
- }
- explicit TmplUniqueBuffer (T * from, int count)
- {
- this->m_Data.reset (from);
- this->m_nCount = count;
- }
- TmplUniqueBuffer (TmplUniqueBuffer && from) : inherited (std::move (from))
- {
- }
- TmplUniqueBuffer (const TmplUniqueBuffer & from) = delete;
- TmplUniqueBuffer & operator = (const TmplUniqueBuffer & from) = delete;
- TmplUniqueBuffer & operator = (TmplUniqueBuffer && from)
- {
- inherited::MoveAssign (from);
- return (*this);
- }
- public:
- T * GetBufferSetCount (int count)
- {
- return this->_GetBufferSetCount (count);
- }
- // return real copy
- TmplUniqueBuffer Clone () const
- {
- TmplUniqueBuffer <T> To;
- inherited::MemCopyTo (To);
- return std::move (To);
- }
- // 调整大小, 只要前面的 count 个对象
- // 如果要的数量比我现有的数量 (m_nCount) 多,就重新分配,然后memcpy,但填充值由上层自行决定
- void Resize (int count)
- {
- // 如果要的很少, 只需要修改 m_nCount
- if (count <= this->m_nCount)
- {
- this->m_nCount = count;
- }
- else
- // 如果要的太多了, 重新分配, 然后 memcpy
- {
- auto tmp = std::move (*this);
- auto pDst = this->_GetBufferSetCount (count);
- auto pSrc = tmp.As ();
- memcpy (pDst, pSrc, sizeof (T) * tmp.m_nCount);
- }
- }
- public:
- T * Detach ()
- {
- this->m_nCount = 0;
- auto pc = this->m_Data.release ();
- ASSERT (pc);
- return pc;
- }
- };
- //-----------------------------------------------------------------------------
- // TmplBuffer_View
- // 是 TmplUniqueBuffer 或 TmplSharedBuffer 的只读视图
- // 某些类或 API 的参数, 既可以用 TmplUniqueBuffer 也可以用 TmplSharedBuffer,
- // 但是如果想让这些函数适用于两种情况, 就必须写成 template.
- // 为避免 template, 参数类型可改用 TmplBuffer_View.
- // 典型的场景是 Compress/Decompress
- //-----------------------------------------------------------------------------
- template <typename T>
- class TmplBuffer_View
- {
- protected:
- int m_nCount; // count of data, 注意是 数量 而不是 字节 长度 !!!
- const T * m_Data;
- public:
- TmplBuffer_View () : m_nCount{ 0 } {}
- TmplBuffer_View (const TmplUniqueBuffer <T> & from) :
- m_Data { from.As () },
- m_nCount { from.GetCount () }
- {
- }
- TmplBuffer_View (const TmplSharedBuffer <T> & from) :
- m_Data{ from.As () },
- m_nCount{ from.GetCount () }
- {
- }
- TmplBuffer_View (const TmplBuffer_View & from) :
- m_Data { from.m_Data },
- m_nCount { from.m_nCount }
- {
- }
- TmplBuffer_View (TmplBuffer_View && from):
- m_Data { from.m_Data },
- m_nCount { from.m_nCount }
- {
- }
- public:
- TmplBuffer_View & operator = (const TmplBuffer_View & from)
- {
- m_Data = from.m_Data;
- m_nCount = from.m_nCount;
- }
- TmplBuffer_View & operator = (TmplBuffer_View && from)
- {
- m_Data = from.m_Data;
- m_nCount = from.m_nCount;
- return (*this);
- }
- public:
- const T * As () const
- {
- return m_Data;
- }
- public:
- int GetCount () const
- {
- return m_nCount;
- }
- int GetNbOfBytes () const
- {
- return m_nCount * sizeof (T);
- }
- };
- }
- }
- // 共享版本
- // 为像素数据定义一个专用的类型
- using BlockBuffer = ECOM::Utility::TmplSharedBuffer <unsigned char>;
- // 非共享版本
- using UniqueBuffer = ECOM::Utility::TmplUniqueBuffer <unsigned char> ;
- using IBlockBuffer = UniqueBuffer;
- using OBlockBuffer = UniqueBuffer;
- using Buffer_View = ECOM::Utility::TmplBuffer_View <unsigned char>;
|