Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
priority_queue.h
00001 ///\file 00002 00003 /****************************************************************************** 00004 The MIT License(MIT) 00005 00006 Embedded Template Library. 00007 https://github.com/ETLCPP/etl 00008 http://www.etlcpp.com 00009 00010 Copyright(c) 2015 jwellbelove, rlindeman 00011 00012 Permission is hereby granted, free of charge, to any person obtaining a copy 00013 of this software and associated documentation files(the "Software"), to deal 00014 in the Software without restriction, including without limitation the rights 00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00016 copies of the Software, and to permit persons to whom the Software is 00017 furnished to do so, subject to the following conditions : 00018 00019 The above copyright notice and this permission notice shall be included in all 00020 copies or substantial portions of the Software. 00021 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00028 SOFTWARE. 00029 ******************************************************************************/ 00030 00031 #ifndef __ETL_PRIORITY_QUEUE__ 00032 #define __ETL_PRIORITY_QUEUE__ 00033 00034 #include <stddef.h> 00035 #include <functional> 00036 #include <algorithm> 00037 00038 #include "platform.h " 00039 #include "container.h " 00040 #include "vector.h " 00041 #include "type_traits.h " 00042 #include "parameter_type.h " 00043 #include "error_handler.h " 00044 #include "exception.h " 00045 00046 #undef ETL_FILE 00047 #define ETL_FILE "12" 00048 00049 //***************************************************************************** 00050 ///\defgroup queue queue 00051 /// A priority queue with the capacity defined at compile time, 00052 /// written in the STL style. 00053 ///\ingroup containers 00054 //***************************************************************************** 00055 00056 namespace etl 00057 { 00058 //*************************************************************************** 00059 /// The base class for priority_queue exceptions. 00060 ///\ingroup queue 00061 //*************************************************************************** 00062 class priority_queue_exception : public exception 00063 { 00064 public: 00065 00066 priority_queue_exception(string_type reason_, string_type file_name_, numeric_type line_number_) 00067 : exception(reason_, file_name_, line_number_) 00068 { 00069 } 00070 }; 00071 00072 //*************************************************************************** 00073 /// The exception thrown when the queue is full. 00074 ///\ingroup queue 00075 //*************************************************************************** 00076 class priority_queue_full : public etl::priority_queue_exception 00077 { 00078 public: 00079 00080 priority_queue_full(string_type file_name_, numeric_type line_number_) 00081 : priority_queue_exception(ETL_ERROR_TEXT("priority_queue:full", ETL_FILE"A"), file_name_, line_number_) 00082 { 00083 } 00084 }; 00085 00086 //*************************************************************************** 00087 /// The priority queue iterator exception on reversed iterators 00088 ///\ingroup queue 00089 //*************************************************************************** 00090 class priority_queue_iterator : public etl::priority_queue_exception 00091 { 00092 public: 00093 00094 priority_queue_iterator(string_type file_name_, numeric_type line_number_) 00095 : priority_queue_exception(ETL_ERROR_TEXT("priority_queue:iterator", ETL_FILE"B"), file_name_, line_number_) 00096 { 00097 } 00098 }; 00099 00100 //*************************************************************************** 00101 ///\ingroup queue 00102 ///\brief This is the base for all priority queues that contain a particular type. 00103 ///\details Normally a reference to this type will be taken from a derived queue. 00104 /// The TContainer specified must provide the front, push_back, pop_back, and 00105 /// assign methods to work correctly with priority_queue. 00106 ///\code 00107 /// etl::priority_queue<int, 10> myPriorityQueue; 00108 /// etl::ipriority_queue<int>& iQueue = myPriorityQueue; 00109 ///\endcode 00110 /// \warning This priority queue cannot be used for concurrent access from 00111 /// multiple threads. 00112 /// \tparam T The type of value that the queue holds. 00113 /// \tparam TContainer to hold the T queue values 00114 /// \tparam TCompare to use in comparing T values 00115 //*************************************************************************** 00116 template <typename T, typename TContainer, typename TCompare> 00117 class ipriority_queue 00118 { 00119 public: 00120 00121 typedef T value_type; ///< The type stored in the queue. 00122 typedef TContainer container_type; ///< The container type used for priority queue. 00123 typedef TCompare compare_type; ///< The comparison type. 00124 typedef T& reference; ///< A reference to the type used in the queue. 00125 typedef const T& const_reference; ///< A const reference to the type used in the queue. 00126 typedef typename TContainer::size_type size_type; ///< The type used for determining the size of the queue. 00127 typedef typename std::iterator_traits<typename TContainer::iterator>::difference_type difference_type; 00128 00129 private: 00130 00131 typedef typename etl::parameter_type<T>::type parameter_t; 00132 00133 public: 00134 00135 //************************************************************************* 00136 /// Gets a reference to the highest priority value in the priority queue.<br> 00137 /// \return A reference to the highest priority value in the priority queue. 00138 //************************************************************************* 00139 reference top() 00140 { 00141 return container.front(); 00142 } 00143 00144 //************************************************************************* 00145 /// Gets a const reference to the highest priority value in the priority queue.<br> 00146 /// \return A const reference to the highest priority value in the priority queue. 00147 //************************************************************************* 00148 const_reference top() const 00149 { 00150 return container.front(); 00151 } 00152 00153 //************************************************************************* 00154 /// Adds a value to the queue. 00155 /// If asserts or exceptions are enabled, throws an etl::priority_queue_full 00156 /// is the priority queue is already full. 00157 ///\param value The value to push to the queue. 00158 //************************************************************************* 00159 void push(parameter_t value) 00160 { 00161 ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); 00162 00163 // Put element at end 00164 container.push_back(value); 00165 // Make elements in container into heap 00166 std::push_heap(container.begin(), container.end(), TCompare()); 00167 } 00168 00169 //************************************************************************* 00170 /// Emplaces a value to the queue. 00171 /// If asserts or exceptions are enabled, throws an etl::priority_queue_full 00172 /// is the priority queue is already full. 00173 ///\param value The value to push to the queue. 00174 //************************************************************************* 00175 template <typename T1> 00176 void emplace(const T1& value1) 00177 { 00178 ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); 00179 00180 // Put element at end 00181 container.emplace_back(value1); 00182 // Make elements in container into heap 00183 std::push_heap(container.begin(), container.end(), TCompare()); 00184 } 00185 00186 //************************************************************************* 00187 /// Emplaces a value to the queue. 00188 /// If asserts or exceptions are enabled, throws an etl::priority_queue_full 00189 /// is the priority queue is already full. 00190 ///\param value The value to push to the queue. 00191 //************************************************************************* 00192 template <typename T1, typename T2> 00193 void emplace(const T1& value1, const T2& value2) 00194 { 00195 ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); 00196 00197 // Put element at end 00198 container.emplace_back(value1, value2); 00199 // Make elements in container into heap 00200 std::push_heap(container.begin(), container.end(), TCompare()); 00201 } 00202 00203 //************************************************************************* 00204 /// Emplaces a value to the queue. 00205 /// If asserts or exceptions are enabled, throws an etl::priority_queue_full 00206 /// is the priority queue is already full. 00207 ///\param value The value to push to the queue. 00208 //************************************************************************* 00209 template <typename T1, typename T2, typename T3> 00210 void emplace(const T1& value1, const T2& value2, const T3& value3) 00211 { 00212 ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); 00213 00214 // Put element at end 00215 container.emplace_back(value1, value2, value3); 00216 // Make elements in container into heap 00217 std::push_heap(container.begin(), container.end(), TCompare()); 00218 } 00219 00220 //************************************************************************* 00221 /// Emplaces a value to the queue. 00222 /// If asserts or exceptions are enabled, throws an etl::priority_queue_full 00223 /// is the priority queue is already full. 00224 ///\param value The value to push to the queue. 00225 //************************************************************************* 00226 template <typename T1, typename T2, typename T3, typename T4> 00227 void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) 00228 { 00229 ETL_ASSERT(!full(), ETL_ERROR(etl::priority_queue_full)); 00230 00231 // Put element at end 00232 container.emplace_back(value1, value2, value3, value4); 00233 // Make elements in container into heap 00234 std::push_heap(container.begin(), container.end(), TCompare()); 00235 } 00236 00237 //************************************************************************* 00238 /// Assigns values to the priority queue. 00239 /// If asserts or exceptions are enabled, emits priority_queue_full if 00240 /// priority queue does not have enough free space. 00241 /// If asserts or exceptions are enabled, emits priority_iterator if the 00242 /// iterators are reversed. 00243 ///\param first The iterator to the first element. 00244 ///\param last The iterator to the last element + 1. 00245 //************************************************************************* 00246 template <typename TIterator> 00247 void assign(TIterator first, TIterator last) 00248 { 00249 #if defined(ETL_DEBUG) 00250 difference_type d = std::distance(first, last); 00251 ETL_ASSERT(d >= 0, ETL_ERROR(etl::priority_queue_iterator)); 00252 ETL_ASSERT(static_cast<size_t>(d) <= max_size(), ETL_ERROR(etl::priority_queue_full)); 00253 #endif 00254 00255 clear(); 00256 container.assign(first, last); 00257 std::make_heap(container.begin(), container.end(), TCompare()); 00258 } 00259 00260 //************************************************************************* 00261 /// Removes the oldest value from the back of the priority queue. 00262 /// Does nothing if the priority queue is already empty. 00263 //************************************************************************* 00264 void pop() 00265 { 00266 // Move largest element to end 00267 std::pop_heap(container.begin(), container.end(), TCompare()); 00268 // Actually remove largest element at end 00269 container.pop_back(); 00270 } 00271 00272 //************************************************************************* 00273 /// Gets the highest priority value in the priority queue 00274 /// and assigns it to destination and removes it from the queue. 00275 //************************************************************************* 00276 void pop_into(reference destination) 00277 { 00278 destination = top(); 00279 pop(); 00280 } 00281 00282 //************************************************************************* 00283 /// Returns the current number of items in the priority queue. 00284 //************************************************************************* 00285 size_type size() const 00286 { 00287 return container.size(); 00288 } 00289 00290 //************************************************************************* 00291 /// Returns the maximum number of items that can be queued. 00292 //************************************************************************* 00293 size_type max_size() const 00294 { 00295 return container.max_size(); 00296 } 00297 00298 //************************************************************************* 00299 /// Checks to see if the priority queue is empty. 00300 /// \return <b>true</b> if the queue is empty, otherwise <b>false</b> 00301 //************************************************************************* 00302 bool empty() const 00303 { 00304 return container.empty(); 00305 } 00306 00307 //************************************************************************* 00308 /// Checks to see if the priority queue is full. 00309 /// \return <b>true</b> if the priority queue is full, otherwise <b>false</b> 00310 //************************************************************************* 00311 bool full() const 00312 { 00313 return container.size() == container.max_size(); 00314 } 00315 00316 //************************************************************************* 00317 /// Returns the remaining capacity. 00318 ///\return The remaining capacity. 00319 //************************************************************************* 00320 size_t available() const 00321 { 00322 return container.max_size() - container.size(); 00323 } 00324 00325 //************************************************************************* 00326 /// Clears the queue to the empty state. 00327 //************************************************************************* 00328 void clear() 00329 { 00330 container.clear(); 00331 } 00332 00333 protected: 00334 00335 //************************************************************************* 00336 /// Make this a clone of the supplied priority queue 00337 //************************************************************************* 00338 void clone(const ipriority_queue& other) 00339 { 00340 assign(other.container.cbegin(), other.container.cend()); 00341 } 00342 00343 //************************************************************************* 00344 /// The constructor that is called from derived classes. 00345 //************************************************************************* 00346 ipriority_queue() 00347 { 00348 } 00349 00350 private: 00351 00352 // Disable copy construction. 00353 ipriority_queue(const ipriority_queue&); 00354 00355 /// The container specified at instantiation of the priority_queue 00356 TContainer container; 00357 }; 00358 00359 //*************************************************************************** 00360 ///\ingroup priority_queue 00361 /// A fixed capacity priority queue. 00362 /// This queue does not support concurrent access by different threads. 00363 /// \tparam T The type this queue should support. 00364 /// \tparam SIZE The maximum capacity of the queue. 00365 //*************************************************************************** 00366 template <typename T, const size_t SIZE, typename TContainer = etl::vector<T, SIZE>, typename TCompare = std::less<typename TContainer::value_type> > 00367 class priority_queue : public etl::ipriority_queue<T, TContainer, TCompare> 00368 { 00369 public: 00370 00371 static const size_t MAX_SIZE = SIZE; 00372 00373 //************************************************************************* 00374 /// Default constructor. 00375 //************************************************************************* 00376 priority_queue() 00377 : etl::ipriority_queue<T, TContainer, TCompare>() 00378 { 00379 } 00380 00381 //************************************************************************* 00382 /// Copy constructor 00383 //************************************************************************* 00384 priority_queue(const priority_queue& rhs) 00385 : etl::ipriority_queue<T, TContainer, TCompare>() 00386 { 00387 etl::ipriority_queue<T, TContainer, TCompare>::clone(rhs); 00388 } 00389 00390 //************************************************************************* 00391 /// Constructor, from an iterator range. 00392 ///\tparam TIterator The iterator type. 00393 ///\param first The iterator to the first element. 00394 ///\param last The iterator to the last element + 1. 00395 //************************************************************************* 00396 template <typename TIterator> 00397 priority_queue(TIterator first, TIterator last) 00398 : etl::ipriority_queue<T, TContainer, TCompare>() 00399 { 00400 etl::ipriority_queue<T, TContainer, TCompare>::assign(first, last); 00401 } 00402 00403 //************************************************************************* 00404 /// Destructor. 00405 //************************************************************************* 00406 ~priority_queue() 00407 { 00408 etl::ipriority_queue<T, TContainer, TCompare>::clear(); 00409 } 00410 00411 //************************************************************************* 00412 /// Assignment operator. 00413 //************************************************************************* 00414 priority_queue& operator = (const priority_queue& rhs) 00415 { 00416 if (&rhs != this) 00417 { 00418 etl::ipriority_queue<T, TContainer, TCompare>::clone(rhs); 00419 } 00420 00421 return *this; 00422 } 00423 }; 00424 } 00425 00426 #undef ETL_FILE 00427 00428 #endif 00429
Generated on Tue Jul 12 2022 14:05:43 by
