#ifndef CT_CloudIndexStdVectorTMethodImpl_HPP #define CT_CloudIndexStdVectorTMethodImpl_HPP #include "ct_cloudindex/tools/ct_cloudindexstdvectortmethodimpl.h" template CT_CloudIndexStdVectorTMethodImpl::CT_CloudIndexStdVectorTMethodImpl(const CT_AbstractCloudIndex &ci, std::vector &vector) : _vector(vector), m_ci(ci) { } template void CT_CloudIndexStdVectorTMethodImpl::setSortType(CT_AbstractCloudIndex::SortType type) { if(m_ci.sortType() != type) { if(m_ci.sortType() == CT_AbstractCloudIndex::SortedInAscendingOrder) std::sort(_vector.begin(), _vector.end()); } } template size_t CT_CloudIndexStdVectorTMethodImpl::size() const { return _vector.size(); } template size_t CT_CloudIndexStdVectorTMethodImpl::indexAt(const size_t &i) const { return _vector[i]; } template size_t CT_CloudIndexStdVectorTMethodImpl::operator[](const size_t &i) const { return _vector[i]; } template void CT_CloudIndexStdVectorTMethodImpl::indexAt(const size_t &i, size_t &index) const { index = _vector[i]; } template const T& CT_CloudIndexStdVectorTMethodImpl::constIndexAt(const size_t &i) const { return _vector[i]; } template size_t CT_CloudIndexStdVectorTMethodImpl::first() const { return _vector.front(); } template size_t CT_CloudIndexStdVectorTMethodImpl::last() const { return _vector.back(); } template bool CT_CloudIndexStdVectorTMethodImpl::contains(const size_t &index) const { if(m_ci.sortType() == CT_AbstractCloudIndex::SortedInAscendingOrder) return std::binary_search(_vector.begin(), _vector.end(), index); return (std::find(_vector.begin(), _vector.end(), index) != _vector.end()); } template size_t CT_CloudIndexStdVectorTMethodImpl::indexOf(const size_t &index) const { if(m_ci.sortType() == CT_AbstractCloudIndex::SortedInAscendingOrder) { typename std::vector::iterator first = _vector.begin(); typename std::vector::iterator last = _vector.end(); first = std::lower_bound(first, last, index); if(first!=last && !(index<(*first))) return std::distance(_vector.begin(), first); } else { typename std::vector::const_iterator it = std::find(_vector.begin(), _vector.end(), index); if(it != _vector.end()) return std::distance(_vector.cbegin(), it); } return size(); } template size_t CT_CloudIndexStdVectorTMethodImpl::lowerBound(const size_t &value) const { typename std::vector::iterator it; typename std::vector::iterator itEnd = _vector.end(); if(m_ci.sortType() == CT_AbstractCloudIndex::SortedInAscendingOrder) it = std::lower_bound(_vector.begin(), _vector.end(), value); else it = std::find_if(_vector.begin(), _vector.end(), std::bind2nd(std::greater_equal(), value)); return size() - (itEnd-it); } template size_t CT_CloudIndexStdVectorTMethodImpl::upperBound(const size_t &value) const { typename std::vector::iterator it; typename std::vector::iterator itEnd = _vector.end(); if(m_ci.sortType() == CT_AbstractCloudIndex::SortedInAscendingOrder) it = std::upper_bound(_vector.begin(), _vector.end(), value); else std::find_if(_vector.begin(), _vector.end(), std::bind2nd(std::greater(), value)); return size() - (itEnd-it); } template void CT_CloudIndexStdVectorTMethodImpl::addIndex(const size_t &newIndex) { if(m_ci.sortType() == CT_AbstractCloudIndex::SortedInAscendingOrder) _vector.insert(std::lower_bound(_vector.begin(), _vector.end(), newIndex), newIndex); else _vector.push_back(newIndex); } template void CT_CloudIndexStdVectorTMethodImpl::removeIndex(const size_t &index) { if(m_ci.sortType() == CT_AbstractCloudIndex::SortedInAscendingOrder) { typename std::vector::iterator first = _vector.begin(); typename std::vector::iterator last = _vector.end(); first = std::lower_bound(first, last, index); if(first!=last && !(index<(*first))) _vector.erase(first); } else { _vector.erase(std::find(_vector.begin(), _vector.end(), index)); } } template void CT_CloudIndexStdVectorTMethodImpl::replaceIndex(const size_t &i, const T &newIndex, const bool &verifyRespectSort) { _vector[i] = newIndex; if(verifyRespectSort && (m_ci.sortType() == CT_AbstractCloudIndex::SortedInAscendingOrder)) { bool ok = false; if(i>0) { if(_vector.at(i-1) <= newIndex) ok = true; } if(ok && i<(size()-1)) { if(_vector.at(i+1) >= newIndex) ok = true; else ok = false; } if(!ok) this->setSortType(CT_AbstractCloudIndex::NotSorted); } } template void CT_CloudIndexStdVectorTMethodImpl::push_front(const size_t &newIndex) { CT_AbstractCloudIndex::SortType t = m_ci.sortType(); if(t != CT_AbstractCloudIndex::NotSorted) { if(size() > 0) { if(newIndex > first()) t = CT_AbstractCloudIndex::NotSorted; } } _vector.insert(_vector.begin(), newIndex); } template void CT_CloudIndexStdVectorTMethodImpl::fill() { size_t s = size(); for(size_t i=0; i void CT_CloudIndexStdVectorTMethodImpl::clear() { internalClear(); } template void CT_CloudIndexStdVectorTMethodImpl::erase(const size_t &beginIndex, const size_t &sizes) { size_t endIndex = (beginIndex+sizes)-1; size_t cpySize = size()-(beginIndex+sizes); if(cpySize > 0) { T *data = _vector.data(); T *dst = data+beginIndex; T *src = data+endIndex; memcpy(dst, src, sizeof(T)*cpySize); } resize(size()-sizes); } template void CT_CloudIndexStdVectorTMethodImpl::resize(const size_t &newSize) { _vector.resize(newSize, 0); _vector.shrink_to_fit(); } template void CT_CloudIndexStdVectorTMethodImpl::reserve(const size_t &newSize) { _vector.reserve(newSize); } template void CT_CloudIndexStdVectorTMethodImpl::removeIfOrShiftIf(typename CT_CloudIndexStdVectorTMethodImpl::FindIfFunction findIf, typename CT_CloudIndexStdVectorTMethodImpl::RemoveIfFunction removeIf, typename CT_CloudIndexStdVectorTMethodImpl::ShiftIfFunction shiftIf, const size_t &shiftValue, const bool &negativeShift, void *context) { typename std::vector::iterator first = vectorFindIf(findIf, context); typename std::vector::iterator last = _vector.end(); if(first != last) { typename std::vector::iterator i = first; size_t nI; while(i != last) { nI = *i; if(!(*removeIf)(context, nI)) { if((*shiftIf)(context, nI)) { if(negativeShift) *i -= shiftValue; else *i += shiftValue; } *first = *i; ++first; } ++i; } } if(first != last) _vector.erase(first); } template void CT_CloudIndexStdVectorTMethodImpl::shiftAll(const size_t &offset, const bool &negativeOffset) { this->internalShiftAll(offset, negativeOffset); } template void CT_CloudIndexStdVectorTMethodImpl::eraseBetweenAndShiftRest(const size_t &eraseBeginPos, const size_t &eraseSize, const size_t &offset, const bool &negativeOffset) { size_t isize = size(); size_t i = eraseBeginPos; size_t j = i+eraseSize; // we copy the shift part to the erase part and shift the index in the same time if(negativeOffset) { while(j < isize) { _vector.at(i) -= offset; ++j; ++i; } } else { while(j < isize) { _vector.at(i) += offset; ++j; ++i; } } // we erase the end of the cloud if(i < isize) erase(i, isize-i); } template typename std::vector::iterator CT_CloudIndexStdVectorTMethodImpl::vectorFindIf(typename CT_CloudIndexStdVectorTMethodImpl::FindIfFunction findIf, void *context) const { typename std::vector::iterator first = _vector.begin(); typename std::vector::iterator last = _vector.end(); size_t tmp; while (first!=last) { tmp = *first; if ((*findIf)(context, tmp)) return first; ++first; } return last; } template void CT_CloudIndexStdVectorTMethodImpl::internalShiftAll(const size_t &offset, const bool &negativeOffset) { typename std::vector::iterator first = _vector.begin(); typename std::vector::iterator last = _vector.end(); if(negativeOffset) { while(first != last) { *first -= offset; ++first; } } else { while(first != last) { *first += offset; ++first; } } } template void CT_CloudIndexStdVectorTMethodImpl::internalClear() { _vector.clear(); } template void CT_CloudIndexStdVectorTMethodImpl::copy(std::vector &destination) { typename std::vector::const_iterator it = _vector.begin(); typename std::vector::const_iterator end = _vector.begin(); typename std::vector::iterator itDest = destination.begin(); while(it != end) { (*itDest) = (*it); ++it; ++itDest; } } #endif // CT_CloudIndexStdVectorTMethodImpl_HPP