X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Fpublic-api%2Fcommon%2Fdali-vector.h;h=6b5dc8f9fac86bb43de1e6043bf001ca876257d2;hb=c035b65926609db54d979cffaadaae22eec5864f;hp=313c7eee4d6c7c2af679b064792af4888ed4f6c9;hpb=5c66381841dd4dfd82c5a118d34104a00a2e0e1c;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/public-api/common/dali-vector.h b/dali/public-api/common/dali-vector.h index 313c7ee..6b5dc8f 100644 --- a/dali/public-api/common/dali-vector.h +++ b/dali/public-api/common/dali-vector.h @@ -1,28 +1,29 @@ #ifndef __DALI_VECTOR_H__ #define __DALI_VECTOR_H__ -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ // EXTERNAL INCLUDES #include // INTERNAL INCLUDES #include +#include /** * @brief For DALi internal use asserts are enabled in debug builds. @@ -80,16 +81,15 @@ public: // API */ SizeType Count() const { - SizeType items = 0; + SizeType items = 0u; if( mData ) { SizeType* metadata = reinterpret_cast< SizeType* >( mData ); - items = *(metadata - 1); + items = *(metadata - 1u); } return items; } - /** * @return The count of elements in this vector. */ @@ -152,6 +152,28 @@ protected: // for Derived classes */ void Erase( char* address, SizeType elementSize ); + /** + * @brief Erase a range of elements. + * + * Does not change capacity. + * @param[in] first Address to the first element to be erased. + * @param[in] last Address to the last element to be erased. + * @param[in] elementSize Size of one of the elements to be erased. + * @return address pointing to the next element of the last one. + */ + char* Erase( char* first, char* last, SizeType elementSize ); + + /** + * Copies a number of bytes from \e source to \e destination. + * + * \e source and \e destination must not overlap. + * + * @param[in] destination Pointer to the destination address. + * @param[in] source Pointer to the source address. + * @param[in] numberOfBytes The number of bytes to be copied. + */ + void CopyMemory( char* destination, const char* source, size_t numberOfBytes ); + private: // not copiable as it does not know the size of elements @@ -261,6 +283,55 @@ protected: // API for deriving classes VectorBase::Erase( address, elementSize ); } + /** + * @brief Erase a range of elements. Does not change capacity. + * + * @param[in] first Address to the first element to be erased. + * @param[in] last Address to the last element to be erased. + * @param[in] elementSize Size of one of the elements to be erased. + * @return address pointing to the next element of the last one. + */ + char* Erase( char* first, char* last, SizeType elementSize ) + { + return VectorBase::Erase( first, last, elementSize ); + } + + /** + * @brief Inserts the given elements into the vector. + * + * @param[in] at Address where to insert the elements into the vector. + * @param[in] from Address to the first element to be inserted. + * @param[in] to Address to the last element to be inserted. + * @param[in] elementSize Size of one of the elements to be inserted. + */ + void Insert( char* at, char* from, char* to, SizeType elementSize ) + { + const SizeType size = to - from; + const SizeType count = Count(); + const SizeType newCount = count + size / elementSize; + + if( newCount > Capacity() ) + { + // Calculate the at offset as the pointer is invalid after the Reserve() call. + std::size_t offset = at - reinterpret_cast( mData ); + + // need more space + Reserve( NextPowerOfTwo( newCount ), elementSize ); // reserve enough space to store at least the next power of two elements of the new required size. + + // Set the new at pointer. + at = reinterpret_cast( mData ) + offset; + } + // set new count first as otherwise the debug assert will hit us + SetCount( newCount ); + + // Move current items to a new position inside the vector. + CopyMemory( at + size, + at, + ( reinterpret_cast( mData ) + count * elementSize ) - at ); + + // Copy the given items. + CopyMemory( at, from, size ); + } }; /** @@ -363,6 +434,7 @@ public: // API } /** + * @pre index must be in the vector's range. * @param index of the element. * @return reference to the element for given index. */ @@ -373,6 +445,7 @@ public: // API } /** + * @pre index must be in the vector's range. * @param index of the element. * @return reference to the element for given index. */ @@ -388,7 +461,11 @@ public: // API /** * @brief Push back an element to the vector. * - * @param element to be added. + * The underlying storage may be reallocated to provide space. + * If this occurs, all pre-existing pointers into the vector will + * become invalid. + * + * @param[in] element to be added. */ void PushBack( const ItemType& element ) { @@ -398,7 +475,7 @@ public: // API if( newCount > capacity ) { // need more space - Reserve( newCount << 1 ); // reserve double the current count + Reserve( newCount << 1u ); // reserve double the current count } // set new count first as otherwise the debug assert will hit us VectorBase::SetCount( newCount ); @@ -406,6 +483,65 @@ public: // API } /** + *@brief Insert an element to the vector. + * + * Elements after \e at are moved one position to the right. + * + * The underlying storage may be reallocated to provide space. + * If this occurs, all pre-existing pointers into the vector will + * become invalid. + * + * @pre Iterator at must be in the vector's range ( Vector::Begin(), Vector::End() ). + * + * @param[in] at Iterator where to insert the elements into the vector. + * @param[in] element to be added. + */ + void Insert( Iterator at, const ItemType& element ) + { + DALI_ASSERT_VECTOR( ( at <= End() ) && ( at >= Begin() ) && "Iterator not inside vector" ); + const SizeType size = sizeof( ItemType ); + char* address = const_cast( reinterpret_cast( &element ) ); + VectorAlgorithms::Insert( reinterpret_cast< char* >( at ), + address, + address + size, + size ); + } + + /** + * @brief Inserts the given elements into the vector. + * + * Elements after \e at are moved the number of given elements positions to the right. + * + * The underlying storage may be reallocated to provide space. + * If this occurs, all pre-existing pointers into the vector will + * become invalid. + * + * @pre Iterator \e at must be in the vector's range ( Vector::Begin(), Vector::End() ). + * @pre Iterators \e from and \e to must be valid iterators. + * @pre Iterator \e from must not be grater than Iterator \e to. + * + * @param[in] at Iterator where to insert the elements into the vector. + * @param[in] from Iterator to the first element to be inserted. + * @param[in] to Iterator to the last element to be inserted. + */ + void Insert( Iterator at, Iterator from, Iterator to ) + { + DALI_ASSERT_VECTOR( ( at <= End() ) && ( at >= Begin() ) && "Iterator not inside vector" ); + DALI_ASSERT_VECTOR( ( from <= to ) && "from address can't be greater than to" ); + + if( from == to ) + { + // nothing to copy. + return; + } + + VectorAlgorithms::Insert( reinterpret_cast< char* >( at ), + reinterpret_cast< char* >( from ), + reinterpret_cast< char* >( to ), + sizeof( ItemType ) ); + } + + /** * @brief Reserve space in the vector. * * Reserving less than current Capacity is a no-op. @@ -420,7 +556,7 @@ public: // API * @brief Resize the vector. Does not change capacity. * * @param count to resize to. - * @param item to insert to the new indeces. + * @param item to insert to the new indices. */ void Resize( SizeType count, ItemType item = ItemType() ) { @@ -435,7 +571,7 @@ public: // API // remember how many new items get added SizeType newItems = count - oldCount; Reserve( count ); - for( ; newItems > 0; --newItems ) + for( ; newItems > 0u; --newItems ) { PushBack( item ); } @@ -446,14 +582,16 @@ public: // API * @brief Erase an element. * * Does not change capacity. Other elements get moved. + * + * @pre Iterator \e iterator must be within the vector's range ( Vector::Begin(), Vector::End() - 1 ). + * * @param iterator Iterator pointing to item to remove. * @return Iterator pointing to next element. */ Iterator Erase( Iterator iterator ) { - DALI_ASSERT_VECTOR( VectorBase::mData && "Vector is empty" ); - DALI_ASSERT_VECTOR( (iterator < End()) && (iterator >= Begin() ) && "Iterator not inside vector" ); - if( iterator < ( End() - 1 ) ) + DALI_ASSERT_VECTOR( (iterator < End()) && (iterator >= Begin()) && "Iterator not inside vector" ); + if( iterator < ( End() - 1u ) ) { VectorAlgorithms::Erase( reinterpret_cast< char* >( iterator ), sizeof( ItemType ) ); } @@ -466,25 +604,64 @@ public: // API } /** + * @brief Erase a range of elements. + * + * Does not change capacity. Other elements get moved. + * + * @pre Iterator \e first must be in the vector's range ( Vector::Begin(), Vector::End() ). + * @pre Iterator \e last must be in the vector's range ( Vector::Begin(), Vector::End() ). + * @pre Iterator \e first must not be grater than Iterator \e last. + * + * @param[in] first Iterator to the first element to be erased. + * @param[in] last Iterator to the last element to be erased. + * + * @return Iterator pointing to the next element of the last one. + */ + Iterator Erase( Iterator first, Iterator last ) + { + DALI_ASSERT_VECTOR( ( first <= End() ) && ( first >= Begin() ) && "Iterator not inside vector" ); + DALI_ASSERT_VECTOR( ( last <= End() ) && ( last >= Begin() ) && "Iterator not inside vector" ); + DALI_ASSERT_VECTOR( ( first <= last ) && "first iterator greater than last" ); + + Iterator nextElement; + + if( last == End() ) + { + // Erase up to the end. + VectorBase::SetCount( VectorBase::Count() - ( last - first ) ); + nextElement = End(); + } + else + { + nextElement = reinterpret_cast( VectorAlgorithms::Erase( reinterpret_cast< char* >( first ), + reinterpret_cast< char* >( last ), + sizeof( ItemType ) ) ); + } + + return nextElement; + } + + /** * @brief Removes an element. * * Does not maintain order. Swaps the element with end and * decreases size by one. This is much faster than Erase so use * this in case order does not matter. Does not change capacity. * + * @pre Iterator \e iterator must be in the vector's range ( Vector::Begin(), Vector::End() - 1 ). + * * @param iterator Iterator pointing to item to remove. */ void Remove( Iterator iterator ) { - DALI_ASSERT_VECTOR( VectorBase::mData && "Vector is empty" ); - Iterator end = End(); - DALI_ASSERT_VECTOR( (iterator < end) && (iterator >= Begin() ) && "Iterator not inside vector" ); - Iterator last = end - 1; - if( last != iterator ) + DALI_ASSERT_VECTOR( (iterator < End()) && (iterator >= Begin()) && "Iterator not inside vector" ); + + Iterator last = End() - 1u; + if( last > iterator ) { std::swap( *iterator, *last ); } - VectorBase::SetCount( VectorBase::Count() - 1 ); + VectorBase::SetCount( VectorBase::Count() - 1u ); } /** @@ -512,7 +689,6 @@ public: // API { VectorAlgorithms::Release(); } - }; } // namespace Dali