/* Copyright 2015, 2016, Michele Santullo * This file is part of "dindexer". * * "dindexer" 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 3 of the License, or * (at your option) any later version. * * "dindexer" 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. * * You should have received a copy of the GNU General Public License * along with "dindexer". If not, see . */ namespace dinhelp { ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template MaxSizedArray::MaxSizedArray() { m_localMem = this->AllocMemory(); m_used = 0; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template MaxSizedArray::MaxSizedArray (const MaxSizedArray& parOther) : parent_type(), m_used(0) { m_localMem = this->AllocMemory(); const size_type count = parOther.size(); for (size_type z = 0; z < count; ++z) { this->push_back(parOther[z]); } } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template MaxSizedArray::MaxSizedArray (MaxSizedArray&& parOther) : parent_type(), m_used(0) { m_localMem = this->AllocMemory(); const size_type count = parOther.size(); for (size_type z = 0; z < count; ++z) { this->push_back(std::move(parOther[z])); } } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template MaxSizedArray::~MaxSizedArray() { this->clear(); this->FreeMemory(); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template bool MaxSizedArray::empty() const { return 0 == m_used; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::size_type MaxSizedArray::size() const { return m_used; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template void MaxSizedArray::push_back (value_type&& parNewItem) { assert(size() < capacity()); this->GetNewT(m_used, std::move(parNewItem)); ++m_used; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template void MaxSizedArray::push_back (const value_type& parNewItem) { assert(size() < capacity()); this->GetNewT(m_used, parNewItem); ++m_used; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template void MaxSizedArray::pop_back() { assert(not empty()); m_localMem[m_used - 1].~T(); --m_used; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::mov_reference MaxSizedArray::operator[] (size_type parIndex) { assert(parIndex < size()); return std::move(m_localMem[parIndex]); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::const_reference MaxSizedArray::operator[] (size_type parIndex) const { assert(parIndex < size()); return m_localMem[parIndex]; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template MaxSizedArray& MaxSizedArray::operator= (const MaxSizedArray& parOther) { m_used = parOther.m_used; std::copy(parOther.GetMemPtr(), parOther.GetMemPtr() + parOther.size(), this->GetMemPtr()); return *this; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template bool MaxSizedArray::operator== (const MaxSizedArray& parOther) const { if (size() != parOther.size()) return false; for (size_type z = 0; z < size(); ++z) { if ((*this)[z] != parOther[z]) return false; } return true; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template bool MaxSizedArray::operator!= (const MaxSizedArray& parOther) const { return not (*this == parOther); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::pointer MaxSizedArray::GetPointer() { assert(size() > 0); return GetPointer_NoAssert(); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::const_pointer MaxSizedArray::GetPointer() const { assert(size() > 0); return GetPointer_NoAssert(); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template void MaxSizedArray::clear() { const size_type count = this->size(); for (size_type z = 0; z < count; ++z) { (*this)[z].~T(); } m_used = 0; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::iterator MaxSizedArray::begin() { return iterator(GetPointer_NoAssert(), size()); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::const_iterator MaxSizedArray::begin() const { return const_iterator(GetPointer_NoAssert(), size()); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::iterator MaxSizedArray::end() { return iterator(GetPointer_NoAssert() + size(), 0); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::const_iterator MaxSizedArray::end() const { return const_iterator(GetPointer_NoAssert() + size(), 0); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::reverse_iterator MaxSizedArray::rbegin() { return reverse_iterator(GetPointer_NoAssert() + size() - 1, size()); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::const_reverse_iterator MaxSizedArray::rbegin() const { return const_reverse_iterator(GetPointer_NoAssert() + size() - 1, size()); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::reverse_iterator MaxSizedArray::rend() { return reverse_iterator(GetPointer_NoAssert() - 1, 0); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::const_reverse_iterator MaxSizedArray::rend() const { return const_reverse_iterator(GetPointer_NoAssert() - 1, 0); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::iterator MaxSizedArray::erase (const iterator& parDele) { assert(end() != parDele); return erase(parDele, parDele + 1); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename MaxSizedArray::iterator MaxSizedArray::erase (const iterator& parFrom, const iterator& parToExcl) { assert(parFrom >= begin()); assert(parToExcl <= end()); assert(parToExcl >= parFrom); //I'm doing this in two passes: first, I'm deleting as many elements as //the ones that would be left at the end (that is, delete and move), //then delete everything to the end of the buffer, if necessary. const size_type deleCount = static_cast(parToExcl - parFrom); const size_type firstIndexToDele = static_cast(parFrom - begin()); const size_type& sz = m_used; assert(firstIndexToDele + deleCount <= sz); const size_type deleAndCopyCount = sz - (firstIndexToDele + deleCount); //As said, make room and copy from the cut tail for (size_type z = firstIndexToDele; z < firstIndexToDele + deleAndCopyCount; z++) { (*this)[z].~T(); new(&(*this)[z]) T((*this)[z + deleCount]); } //Any leftover is rubbish for (size_type z = firstIndexToDele + deleAndCopyCount; z < sz; z++) { (*this)[z].~T(); } m_used -= deleCount; return begin() + firstIndexToDele; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template void MaxSizedArray::reserve (size_type parReserve) { assert(parReserve <= S); if (parReserve > S) { throw std::length_error("Unable to reserve more memory than the build-time size for MaxSizedArray"); } } } //namespace dinhelp