1 #ifndef DALI_CIRCULAR_QUEUE_H
2 #define DALI_CIRCULAR_QUEUE_H
5 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 #include <dali/public-api/common/dali-vector.h>
25 * Class to provide a circular growable queue on top of Dali::Vector
26 * It is designed to occupy a fixed block of memory. It does not allow
27 * addition of elements past the start; i.e. it doesn't overwrite.
29 template <typename ElementType>
33 typedef Dali::Vector<ElementType> Queue;
37 * @param[in] maximumSize The maximum number of elements that the queue can contain
39 CircularQueue( int maximumSize )
40 : mMaximumSize(maximumSize),
45 mQueue.Reserve(maximumSize);
49 * @brief Index operator.
51 * @param[in] index The index to lookup.
53 * @warning This method asserts if the user attempts to read outside the
56 ElementType& operator[](unsigned int index)
58 unsigned int actualIndex = (mStartMarker + index) % mMaximumSize;
59 DALI_ASSERT_ALWAYS( actualIndex<mQueue.Count() && "Reading outside queue boundary");
60 return mQueue[actualIndex];
63 const ElementType& operator[](unsigned int index) const
65 unsigned int actualIndex = (mStartMarker + index) % mMaximumSize;
66 DALI_ASSERT_ALWAYS( actualIndex<mQueue.Count() && "Reading outside queue boundary");
67 return mQueue[actualIndex];
71 * @brief Push back an element into the queue.
73 * @param[in] element The element to push to the back of the queue
74 * @warning This method asserts if the user attempts to push more elements
75 * than the maximum size specified in the constructor
77 void PushBack( const ElementType& element )
79 DALI_ASSERT_ALWAYS( !IsFull() && "Adding to full queue");
81 // Push back if we need to increase the vector count
82 if( mQueue.Count() == 0 || ( mQueue.Count() < mMaximumSize && ! IsEmpty() ) )
84 mQueue.PushBack(element);
93 // Don't advance the end marker or increase the vector count
94 mQueue[mEndMarker] = element;
99 // vector is at max and there is space: advance end marker
101 mEndMarker %= mMaximumSize;
102 mQueue[ mEndMarker ] = element;
108 * @brief Pops an element off the front of the queue
110 * @return A copy of the element at the front of the queue
111 * @warning This method asserts if the queue is empty
113 ElementType PopFront()
115 DALI_ASSERT_ALWAYS( !IsEmpty() && "Reading from empty queue" );
118 if( mNumberOfElements == 1 )
120 element = mQueue[mStartMarker];
121 mNumberOfElements = 0;
123 else if( mNumberOfElements > 1 )
125 element = mQueue[mStartMarker];
127 mStartMarker %= mMaximumSize;
136 DALI_ASSERT_ALWAYS( !IsEmpty() && "Reading from empty queue" );
137 return mQueue[mStartMarker];
140 const ElementType& Front() const
142 DALI_ASSERT_ALWAYS( !IsEmpty() && "Reading from empty queue" );
143 return mQueue[mStartMarker];
148 DALI_ASSERT_ALWAYS( !IsEmpty() && "Reading from empty queue" );
149 return mQueue[mEndMarker];
152 const ElementType& Back() const
154 DALI_ASSERT_ALWAYS( !IsEmpty() && "Reading from empty queue" );
155 return mQueue[mEndMarker];
159 * @brief Predicate to determine if the queue is empty
161 * @return true if the queue is empty
165 return mNumberOfElements == 0;
169 * @brief Predicate to determine if the queue is full
171 * @return true if the queue is full
175 return ( mQueue.Count() == mMaximumSize &&
176 mNumberOfElements > 0 &&
177 (mEndMarker + 1) % mMaximumSize == mStartMarker );
181 * @brief Get a count of the elements in the queue
183 * @return the number of elements in the queue.
185 std::size_t Count() const
187 return mNumberOfElements;
191 Queue mQueue; ///< The queue of elements
192 std::size_t mMaximumSize; ///< maximum size of queue
193 std::size_t mStartMarker; ///< Index of the first element in the queue
194 std::size_t mEndMarker; ///< Index of the last element in the queue
195 int mNumberOfElements; ///< Number of valid elements in the queue
200 #endif // DALI_CIRCULAR_QUEUE_H