32 static_assert(std::is_default_constructible<Tdata>::value,
"Tdata must have a default constructor");
33 static_assert(std::is_trivially_destructible<Tdata>::value,
"Tdata must be trivially destructible");
57 explicit BufferBase(
size_t size) : pData(nullptr), size(size)
61 this->pData = BufferBase::Allocate(this->SizeAsByte());
75 if (flags & BufferFlags::AllocUninitialized)
76 this->pData = BufferBase::AllocateUninitialized(this->SizeAsByte());
78 this->pData = BufferBase::Allocate(this->SizeAsByte());
87 BufferBase(
const std::initializer_list<Tdata>& rhs) : pData(nullptr), size(rhs.size())
91 const size_t size_byte = this->SizeAsByte();
92 this->pData = BufferBase::AllocateUninitialized(size_byte);
93 (void)std::memcpy(this->pData, rhs.begin(), size_byte);
103 this->pData = BufferBase::AllocateUninitialized(size_byte);
104 (void)std::memcpy(this->pData, rhs.
pData, size_byte);
115 Tself& operator=(
const std::initializer_list<Tdata>& rhs)
119 this->size = rhs.size();
122 const size_t size_byte = this->SizeAsByte();
123 this->pData = BufferBase::AllocateUninitialized(size_byte);
124 (void)std::memcpy(this->pData, rhs.begin(), size_byte);
127 return *(Tself*)
this;
130 Tself& operator=(
const Tself& rhs)
138 const size_t size_byte = rhs.SizeAsByte();
139 this->pData = BufferBase::AllocateUninitialized(size_byte);
140 (void)std::memcpy(this->pData, rhs.pData, size_byte);
142 this->size = rhs.size;
146 return *(Tself*)
this;
149 Tself& operator=(Tself&& rhs)
noexcept
155 this->pData = rhs.pData;
156 this->size = rhs.size;
162 return *(Tself*)
this;
180 if (rhs >= this->size)
183 result.pData = BufferBase::Allocate(this->SizeAsByte());
184 result.size = this->size;
188 const size_t thisSize_byte = this->SizeAsByte();
189 const size_t rhsSize_byte = BufferBase::SizeAsByte(rhs);
192 result.pData = BufferBase::AllocateUninitialized(thisSize_byte);
193 result.size = this->size;
195 (void)std::memcpy(result.pData, this->pData + rhs, thisSize_byte - rhsSize_byte);
198 BufferBase::Initialize(result.pData + this->size - rhs, result.pData + this->size);
211 if (rhs >= this->size)
217 (void)std::memmove(this->pData, this->pData + rhs, this->SizeAsByte() - BufferBase::SizeAsByte(rhs));
218 BufferBase::Initialize(this->pData + this->size - rhs, this->pData + this->size);
221 return *(Tself*)
this;
232 if (rhs >= this->size)
235 result.pData = BufferBase::Allocate(this->SizeAsByte());
236 result.size = this->size;
240 const size_t thisSize_byte = this->SizeAsByte();
243 result.pData = BufferBase::AllocateUninitialized(thisSize_byte);
244 result.size = this->size;
246 (void)std::memcpy(result.pData + rhs, this->pData, thisSize_byte - BufferBase::SizeAsByte(rhs));
249 BufferBase::Initialize(result.pData, result.pData + rhs);
262 if (rhs >= this->size)
268 (void)std::memmove(this->pData + rhs, this->pData, this->SizeAsByte() - BufferBase::SizeAsByte(rhs));
269 BufferBase::Initialize(this->pData, this->pData + rhs);
271 return *(Tself*)
this;
274 virtual bool operator==(
const Tself& rhs)
const
276 return (this->IsEmpty() && rhs.IsEmpty()) ||
277 (this->size == rhs.size &&
278 std::memcmp(this->pData, rhs.pData, this->SizeAsByte()) == 0);
281 virtual bool operator!=(
const Tself& rhs)
const
283 return !((*this) == rhs);
293 return this->pData[index];
311 return this->size *
sizeof(Tdata);
318 Tdata&
At(
size_t index)
const
320 if (index >= this->size)
324 return this->pData[index];
334 return this->pData ==
nullptr || this->size == 0;
343 if (!this->IsEmpty())
345 BufferBase::Initialize(this->pData, this->pData + this->size);
355 if (this->pData !=
nullptr)
357 std::free(this->pData);
358 this->pData =
nullptr;
370 virtual Tself
SubBuffer(
size_t index,
size_t size)
const
374 result.pData = BufferBase::SubBuffer(this->pData, this->SizeAsByte(), BufferBase::SizeAsByte(index), BufferBase::SizeAsByte(size));
388 this->pData = BufferBase::Prepend(this->pData, this->SizeAsByte(), rhs.pData,
390 this->size += rhs.size;
401 this->pData = BufferBase::Append(this->pData, this->SizeAsByte(), rhs.pData,
403 this->size += rhs.size;
412 virtual void Insert(
const Tself& rhs,
size_t index)
414 this->pData = BufferBase::Insert(this->pData, this->SizeAsByte(), rhs.pData,
415 rhs.SizeAsByte(), BufferBase::SizeAsByte(index));
416 this->size += rhs.size;
426 virtual void Cut(
size_t index,
size_t size)
428 size_t cutSize_byte = BufferBase::SizeAsByte(size);
429 this->pData = BufferBase::Cut(this->pData, this->SizeAsByte(), BufferBase::SizeAsByte(index), cutSize_byte);
430 this->size -= cutSize_byte /
sizeof(Tdata);
440 virtual void Replace(
const Tself& rhs,
size_t index)
442 this->Replace(rhs, index, rhs.size);
453 virtual void Replace(
const Tself& rhs,
size_t index,
size_t size)
460 BufferBase::Replace(this->pData, this->SizeAsByte(), rhs.pData,
461 BufferBase::SizeAsByte(size), BufferBase::SizeAsByte(index));
471 if (this->size != newSize)
479 Tdata* pTemp = (Tdata*)std::realloc(this->pData, BufferBase::SizeAsByte(newSize));
480 if (pTemp ==
nullptr)
484 if (newSize > this->size)
486 BufferBase::Initialize(pTemp + this->size, pTemp + newSize);
490 this->size = newSize;
501 const size_t halfSize = this->size / 2;
502 for (
size_t i = 0; i < halfSize; ++i)
504 std::swap(this->pData[i], this->pData[this->size - i - 1]);
523 return this->pData !=
nullptr
524 ? (this->pData + this->size)
536 return size *
sizeof(Tdata);
546 template<
typename U = Tdata>
547 static typename std::enable_if<std::is_class<U>::value>::type
Initialize(U* pData, U* pDataEnd)
549 for (; pData < pDataEnd; ++pData)
562 template<
typename U = Tdata>
563 static typename std::enable_if<!std::is_class<U>::value>::type
Initialize(U* pData, U* pDataEnd)
565 (void)std::memset(pData, 0, ((uint8_t*)pDataEnd) - ((uint8_t*)pData));
577 Tdata* pData = BufferBase::AllocateUninitialized(size_byte);
578 BufferBase::Initialize(pData, (Tdata*)(((uint8_t*)pData) + size_byte));
591 Tdata* pData = (Tdata*)std::malloc(size_byte);
592 if (pData ==
nullptr)
599 static Tdata* SubBuffer(Tdata* pThisData,
size_t thisSize_byte,
size_t index_byte,
size_t subBufferSize_byte)
601 if (subBufferSize_byte > 0)
603 if (pThisData ==
nullptr)
607 else if (index_byte >= thisSize_byte)
612 size_t copySize_byte = subBufferSize_byte;
613 if ((index_byte + copySize_byte) > thisSize_byte)
615 copySize_byte = thisSize_byte - index_byte;
618 Tdata* pSubBufferData = BufferBase::AllocateUninitialized(subBufferSize_byte);
619 (void)std::memcpy(pSubBufferData, ((uint8_t*)pThisData) + index_byte, copySize_byte);
621 if (subBufferSize_byte > copySize_byte)
623 BufferBase::Initialize((Tdata*)(((uint8_t*)pSubBufferData) + copySize_byte), (Tdata*)(((uint8_t*)pSubBufferData) + subBufferSize_byte));
626 return pSubBufferData;
631 static Tdata* Prepend(Tdata* pThisData,
size_t thisSize_byte, Tdata* pRhsData,
size_t rhsSize_byte)
633 if (rhsSize_byte > 0)
635 if (pRhsData ==
nullptr)
640 Tdata* pResultData = (Tdata*)std::realloc(pThisData, thisSize_byte + rhsSize_byte);
641 if (pResultData ==
nullptr)
646 if (pThisData == pRhsData)
648 (void)std::memmove(((uint8_t*)pResultData) + rhsSize_byte, pResultData, thisSize_byte);
649 (void)std::memmove(pResultData, ((uint8_t*)pResultData) + rhsSize_byte, rhsSize_byte);
653 (void)std::memmove(((uint8_t*)pResultData) + rhsSize_byte, pResultData, thisSize_byte);
654 (void)std::memcpy(pResultData, pRhsData, rhsSize_byte);
662 static Tdata* Append(Tdata* pThisData,
size_t thisSize_byte, Tdata* pRhsData,
size_t rhsSize_byte)
664 if (rhsSize_byte > 0)
666 if (pRhsData ==
nullptr)
671 Tdata* pResultData = (Tdata*)std::realloc(pThisData, thisSize_byte + rhsSize_byte);
672 if (pResultData ==
nullptr)
677 if (pThisData == pRhsData)
679 (void)std::memmove(((uint8_t*)pResultData) + thisSize_byte, pResultData, rhsSize_byte);
683 (void)std::memcpy(((uint8_t*)pResultData) + thisSize_byte, pRhsData, rhsSize_byte);
691 static Tdata* Insert(Tdata* pThisData,
size_t thisSize_byte, Tdata* pRhsData,
size_t rhsSize_byte,
size_t index_byte)
693 if (rhsSize_byte > 0)
695 if (pRhsData ==
nullptr)
699 else if (index_byte > thisSize_byte)
703 else if (index_byte == thisSize_byte)
705 return BufferBase::Append(pThisData, thisSize_byte, pRhsData, rhsSize_byte);
707 else if (index_byte == 0)
709 return BufferBase::Prepend(pThisData, thisSize_byte, pRhsData, rhsSize_byte);
712 Tdata* pResultData = (Tdata*)std::realloc(pThisData, thisSize_byte + rhsSize_byte);
713 if (pResultData ==
nullptr)
718 if (pThisData == pRhsData)
720 (void)std::memmove(((uint8_t*)pResultData) + index_byte + rhsSize_byte, ((uint8_t*)pResultData) + index_byte, thisSize_byte - index_byte);
721 if (rhsSize_byte > index_byte)
723 (void)std::memmove(((uint8_t*)pResultData) + index_byte, pResultData, index_byte);
724 (void)std::memmove(((uint8_t*)pResultData) + 2 * index_byte, ((uint8_t*)pResultData) + index_byte + rhsSize_byte, rhsSize_byte - index_byte);
728 (void)std::memmove(((uint8_t*)pResultData) + index_byte, pResultData, rhsSize_byte);
733 (void)std::memmove(((uint8_t*)pResultData) + index_byte + rhsSize_byte, ((uint8_t*)pResultData) + index_byte, thisSize_byte - index_byte);
734 (void)std::memcpy(((uint8_t*)pResultData) + index_byte, pRhsData, rhsSize_byte);
742 static Tdata* Cut(Tdata* pThisData,
size_t thisSize_byte,
size_t index_byte,
size_t& cutSize_byte)
744 if (thisSize_byte > 0 && cutSize_byte > 0)
746 if (pThisData ==
nullptr)
750 else if (index_byte >= thisSize_byte)
754 else if (index_byte == 0 && cutSize_byte >= thisSize_byte)
756 std::free(pThisData);
757 cutSize_byte = thisSize_byte;
761 if ((index_byte + cutSize_byte) > thisSize_byte)
763 cutSize_byte = thisSize_byte - index_byte;
766 Tdata* pResultData = BufferBase::AllocateUninitialized(thisSize_byte - cutSize_byte);
769 (void)std::memcpy(pResultData, pThisData, index_byte);
771 if ((index_byte + cutSize_byte) < thisSize_byte)
773 (void)std::memcpy(((uint8_t*)pResultData) + index_byte, ((uint8_t*)pThisData) + index_byte + cutSize_byte, thisSize_byte - index_byte - cutSize_byte);
776 std::free(pThisData);
784 static void Replace(Tdata* pThisData,
size_t thisSize_byte, Tdata* pRhsData,
size_t rhsSize_byte,
size_t index_byte)
786 if (thisSize_byte > 0 && rhsSize_byte > 0)
788 if (pThisData ==
nullptr)
792 else if (pRhsData ==
nullptr)
796 else if (index_byte >= thisSize_byte)
801 if ((index_byte + rhsSize_byte) > thisSize_byte)
803 rhsSize_byte = thisSize_byte - index_byte;
805 (void)std::memcpy(((uint8_t*)pThisData) + index_byte, pRhsData, rhsSize_byte);