diff --git a/inc/hgl/platform/os/MSWindows.h b/inc/hgl/platform/os/MSWindows.h index d41d663..50a21d0 100644 --- a/inc/hgl/platform/os/MSWindows.h +++ b/inc/hgl/platform/os/MSWindows.h @@ -59,6 +59,13 @@ using os_char =wchar_t; #define hgl_realloc(ptr,size) _aligned_realloc(ptr,size,HGL_MEM_ALIGN) #define hgl_free _aligned_free +void *hgl_align_malloc(size_t n,size_t align_size) +{ + if(n<=0)return(nullptr); + + return _aligned_malloc(n,align_size); +} + template inline T *hgl_align_malloc(size_t n) { @@ -67,19 +74,37 @@ inline T *hgl_align_malloc(size_t n) return (T *)_aligned_malloc(n*sizeof(T),alignof(T)); } +void *hgl_align_realloc(void *ptr,size_t n,size_t align_size) +{ + if(n<=0) + { + if(ptr) + _aligned_free(ptr); + + return(nullptr); + } + + if(ptr) + return _aligned_realloc(ptr,n,align_size); + else + return _aligned_malloc(n,align_size); +} + template inline T *hgl_align_realloc(T *ptr,size_t n) { if(n<=0) { - _aligned_free(ptr); + if(ptr) + _aligned_free(ptr); + return(nullptr); } if(ptr) return (T *)_aligned_realloc(ptr,n*sizeof(T),alignof(T)); else - return (T *)_aligned_malloc(n*sizeof(T),alignof(T)); + return (T *)_aligned_malloc(n*sizeof(T),alignof(T)); } #define OS_EXTERNAL_H diff --git a/inc/hgl/type/Collection.h b/inc/hgl/type/Collection.h new file mode 100644 index 0000000..83d0362 --- /dev/null +++ b/inc/hgl/type/Collection.h @@ -0,0 +1,257 @@ +#ifndef HGL_COLLECTION_INCLUDE +#define HGL_COLLECTION_INCLUDE + +#include +namespace hgl +{ + /** + * 抽像数据块 + */ + class AbstractDataBlock + { + protected: + + uint64 data_size; ///<数据长度 + + uint64 alloc_unit_size; ///<分配单位长度(分配长度必须为此值的整倍数) + uint64 alloc_size; ///<实际分配数据长度 + + public: + + virtual void SetAllocUnitSize(const uint64 size) + { + alloc_unit_size=size; + } + + /** + * 计算需要分配的内存容量 + */ + virtual uint64 ComputeAllocSize(const uint64 size) + { + if(alloc_unit_size==0) + { + alloc_size=power_to_2(size); + } + else + if(alloc_unit_size==1) + { + alloc_size=size; + } + else + { + alloc_size=(size+alloc_unit_size-1)/alloc_unit_size; + alloc_size*=alloc_unit_size; + } + + return alloc_size; + } + + public: + + AbstractDataBlock() + { + data_size=0; + alloc_unit_size=0; + alloc_size=0; + } + + virtual bool Alloc (const uint64 size)=0; ///<分配指定空间的数据 + virtual void Free ()=0; ///<释放数据空间 + virtual void Clear ()=0; ///<清空数据(但不释放空间) + + virtual const uint64 GetSize()const {return data_size;} + + virtual bool Exchange (const uint64 target,const uint64 source,const uint64 size)=0; ///<交换两个数据空间 + virtual void Move (const uint64 target,const uint64 source,const uint64 size)=0; ///<移动一块数据 + + virtual bool Write (const uint64 target,const void *source,const uint64 size)=0; ///<写入一块数据 + + virtual bool CopyFrom (const uint64 target,AbstractDataBlock *source,const uint64 offset,const uint64 size)=0; + virtual bool CopyFrom (const uint64 target,AbstractDataBlock *source) + { + if(!source)return(false); + + return CopyFrom(target,source,0,source->GetSize()); + } + };//class AbstractDataBlock + + class MemoryBlock:public AbstractDataBlock + { + protected: + + void *memory_block; + + void *temp_block; + uint64 temp_size; + + public: + + MemoryBlock() + { + memory_block=nullptr; + temp_block=nullptr; + temp_size=0; + } + + virtual ~MemoryBlock() + { + Free(); + hgl_free(temp_block); + } + + bool Alloc(const uint64 size) override + { + if(size<=0)return(false); + if(size<=data_size)return(true); + + if(sizedata_size)return(false); + if(!source||!size)return(false); + + memcpy((uint8 *)memory_block+target,source,size); + return(true); + } + + bool Exchange (const uint64 target,const uint64 source,const uint64 size) override + { + if(size<=0)return(false); + if(target==source)return(true); + + if(size>temp_size) + { + temp_size=ComputeAllocSize(size); + temp_block=hgl_align_realloc(temp_block,temp_size,alloc_unit_size); + } + + memcpy( temp_block, + (uint8 *)memory_block+target, + size); + + memcpy( (uint8 *)memory_block+target, + (uint8 *)memory_block+source, + size); + + memcpy( (uint8 *)memory_block+source, + temp_block, + size); + + return(true); + } + + void Move (const uint64 target,const uint64 source,const uint64 size) override + { + memmove((uint8 *)memory_block+target, + (uint8 *)memory_block+source, + size); + } + + bool CopyFrom (const uint64 target,AbstractDataBlock *source,const uint64 offset,const uint64 size) override + { + } + + bool CopyFrom (const uint64 target,AbstractDataBlock *source) override + { + } + };//class MemoryBlock:public AbstractDataBlock + + /** + * 抽像合集 + */ + template class AbstractCollection + { + protected: + + AbstractDataBlock *data_block; + + uint64 data_count; + + public: + + AbstractCollection(AbstractDataBlock *adb) + { + data_block=adb; + data_count=0; + } + + virtual ~AbstractCollection() + { + SAFE_CLEAR(data_block); + } + + virtual AbstractDataBlock *getDataBlock()const{return data_block;} + + virtual const uint64 GetCount()const{return data_count;} + virtual const bool isEmpty()const{return !data_count;} + + virtual bool add(const T &obj) + { + if(!data_block->Alloc((data_count+1)*sizeof(T))) + return(false); + + if(!data_block->Write(data_count*sizeof(T),&obj,sizeof(T))) + return(false); + + ++data_count; + return(true); + } + + virtual bool addAll(const AbstractCollection &c) + { + const uint64 source_size=c.GetCount(); + + if(!source_size)return(true); + + if(!data_block->Alloc((data_count+source_size)*sizeof(T))) + return(false); + + return data_block->CopyFrom(data_count*sizeof(T),getDataBlock()); + } + + virtual void clear() + { + data_count=0; + if(data_block)data_block->Clear(); + } + };// + + /** + * 数据合集模板 + */ + template class Collection:public AbstractCollection + { + public: + + Collection():AbstractCollection(new MemoryBlock){} + + virtual bool add(const T &obj); + virtual bool addAll(const Collection &c); + + virtual void clear(); + };// +}//namespace hgl +#endif//HGL_COLLECTION_INCLUDE \ No newline at end of file