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;
181 if (rhs >= this->size)
184 result.pData = BufferBase::Allocate(this->SizeAsByte());
185 result.size = this->size;
189 const size_t thisSize_byte = this->SizeAsByte();
190 const size_t rhsSize_byte = BufferBase::SizeAsByte(rhs);
193 result.pData = BufferBase::AllocateUninitialized(thisSize_byte);
194 result.size = this->size;
196 (void)std::memcpy(result.pData, this->pData + rhs, thisSize_byte - rhsSize_byte);
199 BufferBase::Initialize(result.pData + this->size - rhs, result.pData + this->size);
212 if (rhs >= this->size)
218 (void)std::memcpy(this->pData, this->pData + rhs, this->SizeAsByte() - BufferBase::SizeAsByte(rhs));
219 BufferBase::Initialize(this->pData + this->size - rhs, this->pData + this->size);
222 return *(Tself*)
this;
234 if (rhs >= this->size)
237 result.pData = BufferBase::Allocate(this->SizeAsByte());
238 result.size = this->size;
242 const size_t thisSize_byte = this->SizeAsByte();
245 result.pData = BufferBase::AllocateUninitialized(thisSize_byte);
246 result.size = this->size;
248 (void)std::memcpy(result.pData + rhs, this->pData, thisSize_byte - BufferBase::SizeAsByte(rhs));
251 BufferBase::Initialize(result.pData, result.pData + rhs);
264 if (rhs >= this->size)
270 (void)std::memcpy(this->pData + rhs, this->pData, this->SizeAsByte() - BufferBase::SizeAsByte(rhs));
271 BufferBase::Initialize(this->pData, this->pData + rhs);
273 return *(Tself*)
this;
276 virtual bool operator==(
const Tself& rhs)
const
278 return (this->IsEmpty() && rhs.IsEmpty()) ||
279 (this->size == rhs.size &&
280 std::memcmp(this->pData, rhs.pData, this->SizeAsByte()) == 0);
283 virtual bool operator!=(
const Tself& rhs)
const
285 return !((*this) == rhs);
295 return this->pData[index];
313 return this->size *
sizeof(Tdata);
321 Tdata&
At(
size_t index)
const
323 if (index >= this->size)
327 return this->pData[index];
337 return this->pData ==
nullptr || this->size == 0;
346 if (!this->IsEmpty())
348 BufferBase::Initialize(this->pData, this->pData + this->size);
358 if (this->pData !=
nullptr)
360 std::free(this->pData);
361 this->pData =
nullptr;
375 virtual Tself
SubBuffer(
size_t index,
size_t size)
const
379 result.pData = BufferBase::SubBuffer(this->pData, this->SizeAsByte(), BufferBase::SizeAsByte(index), BufferBase::SizeAsByte(size));
395 this->pData = BufferBase::Prepend(this->pData, this->SizeAsByte(), rhs.pData,
397 this->size += rhs.size;
410 this->pData = BufferBase::Append(this->pData, this->SizeAsByte(), rhs.pData,
412 this->size += rhs.size;
423 virtual void Insert(
const Tself& rhs,
size_t index)
425 this->pData = BufferBase::Insert(this->pData, this->SizeAsByte(), rhs.pData,
426 rhs.SizeAsByte(), BufferBase::SizeAsByte(index));
427 this->size += rhs.size;
438 virtual void Cut(
size_t index,
size_t size)
440 size_t cutSize_byte = BufferBase::SizeAsByte(size);
441 this->pData = BufferBase::Cut(this->pData, this->SizeAsByte(), BufferBase::SizeAsByte(index), cutSize_byte);
442 this->size -= cutSize_byte /
sizeof(Tdata);
453 virtual void Replace(
const Tself& rhs,
size_t index)
455 this->Replace(rhs, index, rhs.size);
467 virtual void Replace(
const Tself& rhs,
size_t index,
size_t size)
474 BufferBase::Replace(this->pData, this->SizeAsByte(), rhs.pData,
475 BufferBase::SizeAsByte(size), BufferBase::SizeAsByte(index));
486 if (this->size != newSize)
494 Tdata* pTemp = (Tdata*)std::realloc(this->pData, BufferBase::SizeAsByte(newSize));
495 if (pTemp ==
nullptr)
499 if (newSize > this->size)
501 BufferBase::Initialize(pTemp + this->size, pTemp + newSize);
505 this->size = newSize;
516 const size_t halfSize = this->size / 2;
517 for (
size_t i = 0; i < halfSize; ++i)
519 std::swap(this->pData[i], this->pData[this->size - i - 1]);
538 return this->pData !=
nullptr
539 ? (this->pData + this->size)
551 return size *
sizeof(Tdata);
561 template<
typename U = Tdata>
562 static typename std::enable_if<std::is_class<U>::value>::type
Initialize(U* pData, U* pDataEnd)
564 for (; pData < pDataEnd; ++pData)
577 template<
typename U = Tdata>
578 static typename std::enable_if<!std::is_class<U>::value>::type
Initialize(U* pData, U* pDataEnd)
580 (void)std::memset(pData, 0, ((uint8_t*)pDataEnd) - ((uint8_t*)pData));
593 Tdata* pData = BufferBase::AllocateUninitialized(size_byte);
594 BufferBase::Initialize(pData, (Tdata*)(((uint8_t*)pData) + size_byte));
608 Tdata* pData = (Tdata*)std::malloc(size_byte);
609 if (pData ==
nullptr)
616 static Tdata* SubBuffer(Tdata* pThisData,
size_t thisSize_byte,
size_t index_byte,
size_t subBufferSize_byte)
618 if (subBufferSize_byte > 0)
620 if (pThisData ==
nullptr)
624 else if (index_byte >= thisSize_byte)
629 size_t copySize_byte = subBufferSize_byte;
630 if ((index_byte + copySize_byte) > thisSize_byte)
632 copySize_byte = thisSize_byte - index_byte;
635 Tdata* pSubBufferData = BufferBase::AllocateUninitialized(subBufferSize_byte);
636 (void)std::memcpy(pSubBufferData, ((uint8_t*)pThisData) + index_byte, copySize_byte);
638 if (subBufferSize_byte > copySize_byte)
640 BufferBase::Initialize((Tdata*)(((uint8_t*)pSubBufferData) + copySize_byte), (Tdata*)(((uint8_t*)pSubBufferData) + subBufferSize_byte));
643 return pSubBufferData;
648 static Tdata* Prepend(Tdata* pThisData,
size_t thisSize_byte, Tdata* pRhsData,
size_t rhsSize_byte)
650 if (rhsSize_byte > 0)
652 if (pRhsData ==
nullptr)
657 Tdata* pResultData = (Tdata*)std::realloc(pThisData, thisSize_byte + rhsSize_byte);
658 if (pResultData ==
nullptr)
663 if (pThisData == pRhsData)
665 (void)std::memcpy(((uint8_t*)pResultData) + rhsSize_byte, pResultData, thisSize_byte);
666 (void)std::memcpy(pResultData, ((uint8_t*)pResultData) + rhsSize_byte, rhsSize_byte);
670 (void)std::memcpy(((uint8_t*)pResultData) + rhsSize_byte, pThisData, thisSize_byte);
671 (void)std::memcpy(pResultData, pRhsData, rhsSize_byte);
679 static Tdata* Append(Tdata* pThisData,
size_t thisSize_byte, Tdata* pRhsData,
size_t rhsSize_byte)
681 if (rhsSize_byte > 0)
683 if (pRhsData ==
nullptr)
688 Tdata* pResultData = (Tdata*)std::realloc(pThisData, thisSize_byte + rhsSize_byte);
689 if (pResultData ==
nullptr)
694 if (pThisData == pRhsData)
696 (void)std::memcpy(((uint8_t*)pResultData) + thisSize_byte, pResultData, rhsSize_byte);
700 (void)std::memcpy(((uint8_t*)pResultData) + thisSize_byte, pRhsData, rhsSize_byte);
708 static Tdata* Insert(Tdata* pThisData,
size_t thisSize_byte, Tdata* pRhsData,
size_t rhsSize_byte,
size_t index_byte)
710 if (rhsSize_byte > 0)
712 if (pRhsData ==
nullptr)
716 else if (index_byte > thisSize_byte)
720 else if (index_byte == thisSize_byte)
722 return BufferBase::Append(pThisData, thisSize_byte, pRhsData, rhsSize_byte);
724 else if (index_byte == 0)
726 return BufferBase::Prepend(pThisData, thisSize_byte, pRhsData, rhsSize_byte);
729 Tdata* pResultData = (Tdata*)std::realloc(pThisData, thisSize_byte + rhsSize_byte);
730 if (pResultData ==
nullptr)
735 if (pThisData == pRhsData)
737 (void)std::memcpy(((uint8_t*)pResultData) + index_byte + rhsSize_byte, ((uint8_t*)pResultData) + index_byte, thisSize_byte - index_byte);
738 if (rhsSize_byte > index_byte)
740 (void)std::memcpy(((uint8_t*)pResultData) + index_byte, pResultData, index_byte);
741 (void)std::memcpy(((uint8_t*)pResultData) + 2 * index_byte, ((uint8_t*)pResultData) + index_byte + rhsSize_byte, rhsSize_byte - index_byte);
745 (void)std::memcpy(((uint8_t*)pResultData) + index_byte, pResultData, rhsSize_byte);
750 (void)std::memcpy(((uint8_t*)pResultData) + index_byte + rhsSize_byte, ((uint8_t*)pResultData) + index_byte, thisSize_byte - index_byte);
751 (void)std::memcpy(((uint8_t*)pResultData) + index_byte, pRhsData, rhsSize_byte);
759 static Tdata* Cut(Tdata* pThisData,
size_t thisSize_byte,
size_t index_byte,
size_t& cutSize_byte)
761 if (thisSize_byte > 0 && cutSize_byte > 0)
763 if (pThisData ==
nullptr)
767 else if (index_byte >= thisSize_byte)
771 else if (index_byte == 0 && cutSize_byte >= thisSize_byte)
773 std::free(pThisData);
774 cutSize_byte = thisSize_byte;
778 if ((index_byte + cutSize_byte) > thisSize_byte)
780 cutSize_byte = thisSize_byte - index_byte;
783 Tdata* pResultData = BufferBase::AllocateUninitialized(thisSize_byte - cutSize_byte);
786 (void)std::memcpy(pResultData, pThisData, index_byte);
788 if ((index_byte + cutSize_byte) < thisSize_byte)
790 (void)std::memcpy(((uint8_t*)pResultData) + index_byte, ((uint8_t*)pThisData) + index_byte + cutSize_byte, thisSize_byte - index_byte - cutSize_byte);
793 std::free(pThisData);
801 static void Replace(Tdata* pThisData,
size_t thisSize_byte, Tdata* pRhsData,
size_t rhsSize_byte,
size_t index_byte)
803 if (thisSize_byte > 0 && rhsSize_byte > 0)
805 if (pThisData ==
nullptr)
809 else if (pRhsData ==
nullptr)
813 else if (index_byte >= thisSize_byte)
818 if ((index_byte + rhsSize_byte) > thisSize_byte)
820 rhsSize_byte = thisSize_byte - index_byte;
822 (void)std::memcpy(((uint8_t*)pThisData) + index_byte, pRhsData, rhsSize_byte);